Hi, PR 127967 revealed that there are two places in ipa-prop where it is asked if a load will result in a known constant after IPA-CP but it did not check that the requested offset is at a byte boundary and so could return a constant that sits at a different place within an aggregate (at the byte boundary). This patch simply adds the two checks.
Bootstrapped and tested on x86_64-linux. I plan to push this as obvious on Monday to master and a bit later to all active release branches. Thanks, Martin gcc/ChangeLog: 2026-10-23 Martin Jambor <[email protected]> PR ipa/127967 * ipa-prop.cc (ipcp_modif_dom_walker::before_dom_children): Add a check that bit_offset aligns to byte boundary. (ipcp_get_aggregate_const): Likewise. gcc/testsuite/ChangeLog: 2026-10-23 Martin Jambor <[email protected]> PR ipa/127967 * gcc.dg/ipa/pr127967.c: New test. --- gcc/ipa-prop.cc | 7 +++++-- gcc/testsuite/gcc.dg/ipa/pr127967.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr127967.c diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index fb374fb53c9..f35f8fa36f4 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -6423,7 +6423,8 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb) continue; if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index, - &bit_offset, &size, &by_ref)) + &bit_offset, &size, &by_ref) + || (bit_offset % BITS_PER_UNIT) != 0) continue; unsigned unit_offset = bit_offset / BITS_PER_UNIT; ipa_argagg_value_list avl (m_ts); @@ -6492,7 +6493,9 @@ ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref, cgraph_node *node = cgraph_node::get (func->decl); ipcp_transformation *ts = ipcp_get_transformation_summary (node); - if (!ts || !ts->m_agg_values) + if (!ts + || !ts->m_agg_values + || (bit_offset % BITS_PER_UNIT) != 0) return NULL_TREE; int index = ts->get_param_index (func->decl, parm); diff --git a/gcc/testsuite/gcc.dg/ipa/pr127967.c b/gcc/testsuite/gcc.dg/ipa/pr127967.c new file mode 100644 index 00000000000..f1cd02b5199 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr127967.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-require-effective-target le } */ +/* { dg-require-effective-target int32plus } */ +/* { dg-options "-O3" } */ + +struct S { unsigned p : 4, q : 8; }; + +__attribute__((noinline)) static int f(struct S s) { return s.q; } + +int main() { + union { unsigned char b[4]; struct S s; } u = {{16}}; + int r = f(u.s); + if (r != 1) + __builtin_abort (); + return 0; +} -- 2.55.0
