diff mbox series

tree-optimization/113796 - if-conversion and ranges

Message ID 20240207144938.085873858001@sourceware.org
State New
Headers show
Series tree-optimization/113796 - if-conversion and ranges | expand

Commit Message

Richard Biener Feb. 7, 2024, 2:49 p.m. UTC
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.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	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 | 16 ++++++++++
 gcc/tree-if-conv.cc                     | 41 +++++++++++++++----------
 2 files changed, 41 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr113796.c
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr113796.c b/gcc/testsuite/gcc.dg/torture/pr113796.c
new file mode 100644
index 00000000000..bdf96d0b687
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr113796.c
@@ -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;
+}
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 8e79362f96a..db0d0f4a497 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -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.  */