]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/113796 - if-conversion and ranges
authorRichard Biener <rguenther@suse.de>
Wed, 7 Feb 2024 12:08:43 +0000 (13:08 +0100)
committerRichard Biener <rguenther@suse.de>
Wed, 7 Feb 2024 14:49:51 +0000 (15:49 +0100)
The following makes sure to wipe range info before folding the
COND_EXPRs we insert as part of replacing PHI nodes when combining
blocks in the if-conversion pass.

PR tree-optimization/113796
* tree-if-conv.cc (combine_blocks): Wipe range-info before
replacing PHIs and inserting predicates.

* gcc.dg/torture/pr113796.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr113796.c [new file with mode: 0644]
gcc/tree-if-conv.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr113796.c b/gcc/testsuite/gcc.dg/torture/pr113796.c
new file mode 100644 (file)
index 0000000..bdf96d0
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-loop-if-convert -fno-vect-cost-model" } */
+
+signed char a[] = {0x80, 0x80,0x80,0x80};
+int b;
+signed char c;
+
+int main()
+{
+  for (; b < sizeof(a); b += 1)
+    c = a[b] < 0 ?: a[b] >> 6;
+
+  if (c != 1)
+    __builtin_abort ();
+  return 0;
+}
index 8e79362f96abed09495cdc1d16fcb18a3dc0ff51..db0d0f4a49720e6b362de8acb9891cd5e6766125 100644 (file)
@@ -2909,6 +2909,29 @@ combine_blocks (class loop *loop, bool loop_versioned)
   edge e;
   edge_iterator ei;
 
+  /* Reset flow-sensitive info before predicating stmts or PHIs we
+     might fold.  */
+  bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
+  for (i = 0; i < orig_loop_num_nodes; i++)
+    {
+      bb = ifc_bbs[i];
+      predicated[i] = is_predicated (bb);
+      if (predicated[i])
+       {
+         for (auto gsi = gsi_start_phis (bb);
+              !gsi_end_p (gsi); gsi_next (&gsi))
+           reset_flow_sensitive_info (gimple_phi_result (*gsi));
+         for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             gimple *stmt = gsi_stmt (gsi);
+             ssa_op_iter i;
+             tree op;
+             FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
+               reset_flow_sensitive_info (op);
+           }
+       }
+    }
+
   remove_conditions_and_labels (loop);
   insert_gimplified_predicates (loop);
   predicate_all_scalar_phis (loop, loop_versioned);
@@ -2917,20 +2940,13 @@ combine_blocks (class loop *loop, bool loop_versioned)
     predicate_statements (loop);
 
   /* Merge basic blocks.  */
-  exit_bb = NULL;
-  bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
+  exit_bb = single_exit (loop)->src;
+  gcc_assert (exit_bb != loop->latch);
   for (i = 0; i < orig_loop_num_nodes; i++)
     {
       bb = ifc_bbs[i];
-      predicated[i] = !is_true_predicate (bb_predicate (bb));
       free_bb_predicate (bb);
-      if (bb_with_exit_edge_p (loop, bb))
-       {
-         gcc_assert (exit_bb == NULL);
-         exit_bb = bb;
-       }
     }
-  gcc_assert (exit_bb != loop->latch);
 
   merge_target_bb = loop->header;
 
@@ -3003,13 +3019,6 @@ combine_blocks (class loop *loop, bool loop_versioned)
            /* If this is the first load we arrive at update last_vdef
               so we handle stray PHIs correctly.  */
            last_vdef = gimple_vuse (stmt);
-         if (predicated[i])
-           {
-             ssa_op_iter i;
-             tree op;
-             FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
-               reset_flow_sensitive_info (op);
-           }
        }
 
       /* Update stmt list.  */