On Mon, May 11, 2026 at 2:45 AM Richard Biener <[email protected]> wrote: > > The following avoids speculating a load/store pair for modes > that cannot transfer bits or, as for the testcase, bitfield > loads that are either value changing or invoke UB when out-of-bound > (and that we'd rewrite to be defined with explicit truncation). > > Bootstrapped and tested on x86_64-unknown-linux-gnu, will push later > today. > > Richard. > > PR tree-optimization/125250 > * tree-ssa-loop-im.cc (execute_sm): For modes that cannot > transfer bits, _Bool and bitfield accesses force the > multi-threaded model. > > * gcc.dg/torture/pr125250.c: New testcase. > --- > gcc/testsuite/gcc.dg/torture/pr125250.c | 32 +++++++++++++++++++++++++ > gcc/tree-ssa-loop-im.cc | 9 ++++++- > 2 files changed, 40 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr125250.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr125250.c > b/gcc/testsuite/gcc.dg/torture/pr125250.c > new file mode 100644 > index 00000000000..25d69c0e305 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr125250.c > @@ -0,0 +1,32 @@ > +/* { dg-do run } */ > + > +short g0, __chk, g9, g6; > +_Bool g1; > +void *g4; > + > +void __attribute__((noipa)) f5(_Bool a2, int a5) > +{ > + void *a1 = &a2; > +lbl_br11: > + *(_Bool *)a1 = 0; > + a1 = &a5; > + if (!a2) > + { > + g1 = *(_Bool *)g4; > + if (g1) > + { > + g9 = -g9; > + goto lbl_br11; > + } > + } > + g6 = a5; > +} > + > +int main() > +{ > + g4 = &g0; > + f5(0, 8); > + __chk = g6; > + if (__chk != 8) > + __builtin_abort (); > +} > diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc > index 72e19981698..4f7401e2d5d 100644 > --- a/gcc/tree-ssa-loop-im.cc > +++ b/gcc/tree-ssa-loop-im.cc > @@ -2323,7 +2323,14 @@ execute_sm (class loop *loop, im_mem_ref *ref, > bool always_stored = ref_always_accessed_p (loop, ref, true); > if (maybe_mt > && (bb_in_transaction (loop_preheader_edge (loop)->src) > - || (ref_can_have_store_data_races (ref->mem.ref) && ! > always_stored))) > + || (ref_can_have_store_data_races (ref->mem.ref) && ! always_stored) > + /* Do not speculate a load/store when that's not a noop, either > + because the mode cannot be transferred or because there's > + UB involved for out-of-bound values. */ > + || !mode_can_transfer_bits (TYPE_MODE (TREE_TYPE (ref->mem.ref))) > + || TREE_CODE (TREE_TYPE (ref->mem.ref)) == BOOLEAN_TYPE > + || (TREE_CODE (ref->mem.ref) == COMPONENT_REF > + && DECL_BIT_FIELD (TREE_OPERAND (ref->mem.ref, 1))))) > multi_threaded_model_p = true;
I was looking into doing this exact change, well only for boolean types. So thanks for doing this and expanding it to the other problem cases. Thanks, Andrea > > if (multi_threaded_model_p && !use_other_flag_var) > -- > 2.51.0
