https://gcc.gnu.org/g:d45381550ec25de9c5eb7168bad85586109b4991
commit r17-4774-gd45381550ec25de9c5eb7168bad85586109b4991 Author: Richard Biener <[email protected]> Date: Tue Sep 29 13:15:07 2026 +0200 tree-optimization/60075 - fix address-space handling in PRE The following fixes a thinko in COMPONENT_REF handling in VN/PRE where we falsely assumed the type of the FIELD_DECL specifies the type of the COMPONENT_REF in full, disregarding address-space qualification. PR tree-optimization/60075 * tree-ssa-sccvn.cc (copy_reference_ops_from_ref): Do not use the type of the FIELD_DECL for COMPONENT_REF ops. * tree-ssa-pre.cc (create_component_ref_by_pieces_1): Likewise. * gcc.target/avr/pr60075.c: New testcase. Diff: --- gcc/testsuite/gcc.target/avr/pr60075.c | 49 ++++++++++++++++++++++++++++++++++ gcc/tree-ssa-pre.cc | 2 +- gcc/tree-ssa-sccvn.cc | 3 --- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.target/avr/pr60075.c b/gcc/testsuite/gcc.target/avr/pr60075.c new file mode 100644 index 000000000000..f4f857ce1185 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/pr60075.c @@ -0,0 +1,49 @@ +/* { dg-do run { target { ! avr_tiny } } } */ +/* { dg-options "-O2" } */ + +#define NI __attribute((noipa)) +typedef __UINT8_TYPE__ uint8_t; + +struct pair { uint8_t data; uint8_t cmd; }; +const __flash struct pair table[] = +{ + { 0x11, 1 }, { 0x33, 0 }, { 0x55, 1 } +}; + +uint8_t cnt; + +NI void write_data (uint8_t d) +{ + ++cnt; + if (cnt == 1 && d == 0x11) + { /*ok*/ } + else if (cnt == 3 && d == 0x55) + { /*ok*/ } + else + __builtin_abort (); +} + +NI void write_cmd (uint8_t c) +{ + ++cnt; + if (cnt != 2 || c != 0x33) + __builtin_abort (); +} + +NI void test (uint8_t loops) +{ + for (uint8_t i = 0; i < loops; i++) + { + // Bug is reading table[i].cmd from wrong AS. + if (table[i].cmd) + write_data (table[i].data); + else + write_cmd (table[i].data); + } +} + +int main (void) +{ + test (3); + return 0; +} diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index 9353f19d4053..478422518810 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2950,7 +2950,7 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, if (!genop2) return NULL_TREE; } - return build3 (COMPONENT_REF, TREE_TYPE (op1), op0, op1, genop2); + return build3 (COMPONENT_REF, currop->type, op0, op1, genop2); } case SSA_NAME: diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index c496ff93d11c..03bf9a0ec4d9 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -1003,9 +1003,6 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) temp.reverse = REF_REVERSE_STORAGE_ORDER (ref); break; case COMPONENT_REF: - /* The field decl is enough to unambiguously specify the field, - so use its type here. */ - temp.type = TREE_TYPE (TREE_OPERAND (ref, 1)); temp.op0 = TREE_OPERAND (ref, 1); temp.op1 = TREE_OPERAND (ref, 2); temp.reverse = (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
