aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-02-07 13:08:43 +0100
committerRichard Biener <rguenther@suse.de>2024-02-07 15:49:51 +0100
commit8636c538b68068cd2a4115fece531dc3e3e3a84a (patch)
tree69093ae104c97e68786caf29371c01e5003a6366
parent99200573096c03120c8d4514383951acecdd5ab1 (diff)
downloadgcc-8636c538b68068cd2a4115fece531dc3e3e3a84a.zip
gcc-8636c538b68068cd2a4115fece531dc3e3e3a84a.tar.gz
gcc-8636c538b68068cd2a4115fece531dc3e3e3a84a.tar.bz2
tree-optimization/113796 - if-conversion and ranges
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.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr113796.c16
-rw-r--r--gcc/tree-if-conv.cc41
2 files changed, 41 insertions, 16 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr113796.c b/gcc/testsuite/gcc.dg/torture/pr113796.c
new file mode 100644
index 0000000..bdf96d0
--- /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 8e79362..db0d0f4 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. */