]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/125250 - LIM speculating not noop load/store
authorRichard Biener <rguenther@suse.de>
Mon, 11 May 2026 08:25:57 +0000 (10:25 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 11 May 2026 12:38:47 +0000 (14:38 +0200)
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).

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 [new file with mode: 0644]
gcc/tree-ssa-loop-im.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr125250.c b/gcc/testsuite/gcc.dg/torture/pr125250.c
new file mode 100644 (file)
index 0000000..25d69c0
--- /dev/null
@@ -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 ();
+}
index 72e19981698480058a0a6bd445145c48755488d0..4f7401e2d5d3e932f5befc2326b615867d4de828 100644 (file)
@@ -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;
 
   if (multi_threaded_model_p && !use_other_flag_var)