aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-02-23 11:03:03 +0100
committerRichard Biener <rguenther@suse.de>2023-02-23 11:16:39 +0100
commit31cc5821223a096ef61743bff520f4a0dbba5872 (patch)
tree93347d8a41ea5a6e37f2f0ceb46e3eb5571bb2ee
parent4f609c6f762832e43524352527a7ecbea2698ff9 (diff)
downloadgcc-31cc5821223a096ef61743bff520f4a0dbba5872.zip
gcc-31cc5821223a096ef61743bff520f4a0dbba5872.tar.gz
gcc-31cc5821223a096ef61743bff520f4a0dbba5872.tar.bz2
tree-optimization/108888 - call if-conversion
The following makes sure to only predicate calls necessary. PR tree-optimization/108888 * tree-if-conv.cc (if_convertible_stmt_p): Set PLF_2 on calls to predicate. (predicate_statements): Only predicate calls with PLF_2. * g++.dg/torture/pr108888.C: New testcase.
-rw-r--r--gcc/testsuite/g++.dg/torture/pr108888.C18
-rw-r--r--gcc/tree-if-conv.cc17
2 files changed, 28 insertions, 7 deletions
diff --git a/gcc/testsuite/g++.dg/torture/pr108888.C b/gcc/testsuite/g++.dg/torture/pr108888.C
new file mode 100644
index 0000000..29a22e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr108888.C
@@ -0,0 +1,18 @@
+// { dg-do compile }
+
+int scaleValueSaturate_scalefactor, scaleValueSaturate___trans_tmp_2,
+ scaleValuesSaturate_i;
+int scaleValueSaturate(int value) {
+ int result = __builtin_clz(value);
+ if (value)
+ if (-result <= scaleValueSaturate_scalefactor)
+ return 0;
+ return scaleValueSaturate___trans_tmp_2;
+}
+short scaleValuesSaturate_dst;
+short *scaleValuesSaturate_src;
+void scaleValuesSaturate() {
+ for (; scaleValuesSaturate_i; scaleValuesSaturate_i++)
+ scaleValuesSaturate_dst =
+ scaleValueSaturate(scaleValuesSaturate_src[scaleValuesSaturate_i]);
+}
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index a7a8406..0e384e3 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -1099,6 +1099,7 @@ if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
n = n->simdclone->next_clone)
if (n->simdclone->inbranch)
{
+ gimple_set_plf (stmt, GF_PLF_2, true);
need_to_predicate = true;
return true;
}
@@ -2541,7 +2542,8 @@ predicate_statements (loop_p loop)
release_defs (stmt);
continue;
}
- else if (gimple_plf (stmt, GF_PLF_2))
+ else if (gimple_plf (stmt, GF_PLF_2)
+ && is_gimple_assign (stmt))
{
tree lhs = gimple_assign_lhs (stmt);
tree mask;
@@ -2625,13 +2627,14 @@ predicate_statements (loop_p loop)
gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
update_stmt (stmt);
}
-
- /* Convert functions that have a SIMD clone to IFN_MASK_CALL. This
- will cause the vectorizer to match the "in branch" clone variants,
- and serves to build the mask vector in a natural way. */
- gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
- if (call && !gimple_call_internal_p (call))
+ else if (gimple_plf (stmt, GF_PLF_2)
+ && is_gimple_call (stmt))
{
+ /* Convert functions that have a SIMD clone to IFN_MASK_CALL.
+ This will cause the vectorizer to match the "in branch"
+ clone variants, and serves to build the mask vector
+ in a natural way. */
+ gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
tree orig_fn = gimple_call_fn (call);
int orig_nargs = gimple_call_num_args (call);
auto_vec<tree> args;