From: Torbjörn SVENSSON <[email protected]>

Fold `(x == CST) ? x : CST` and `(x != CST) ? CST : x` to `CST` for
integral scalar and vector types. This catches cases where earlier
folding has converted bitwise mask expressions into conditional selects,
including ARM MVE predicate-to-vector mask forms.

        PR tree-optimization/124663

gcc/ChangeLog:

        * match.pd: Fold constant conditional selects.

gcc/testsuite/ChangeLog:

        * g++.dg/tree-ssa/pr124663.C: New test.

Signed-off-by: Torbjörn SVENSSON <[email protected]>
---
 gcc/match.pd                             | 16 +++++++++++++++-
 gcc/testsuite/g++.dg/tree-ssa/pr124663.C | 13 +++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr124663.C

diff --git a/gcc/match.pd b/gcc/match.pd
index b3738fdde1da..df9689131b65 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7119,7 +7119,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   /* For CONDs, don't handle signed values here. */
   (if (cnd == VEC_COND_EXPR
        || TYPE_UNSIGNED (TREE_TYPE (@0)))
-   (cnd @0 @2 @1))))
+   (cnd @0 @2 @1)))
+
+ /* A == CST ? A : CST -> CST.  */
+ (simplify
+  (cnd (eq @0 CONSTANT_CLASS_P@1) (nop_convert? @0) CONSTANT_CLASS_P@2)
+  (if (ANY_INTEGRAL_TYPE_P (type)
+       && operand_equal_p (@1, @2))
+   (convert @1)))
+
+ /* A != CST ? CST : A -> CST.  */
+ (simplify
+  (cnd (ne @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2 (nop_convert? @0))
+  (if (ANY_INTEGRAL_TYPE_P (type)
+       && operand_equal_p (@1, @2))
+   (convert @1))))
 
 /* abs/negative simplifications moved from fold_cond_expr_with_comparison.
 
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr124663.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr124663.C
new file mode 100644
index 000000000000..dfd12debff95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr124663.C
@@ -0,0 +1,13 @@
+// PR c++/124663
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-forwprop3-raw" }
+
+#define vector __attribute__((vector_size(4*sizeof(int))))
+void f(vector int *a)
+{
+  vector int cst = {1,2,3,4};
+  vector int t = (*a == cst);
+  *a = (t ? *a : cst);
+}
+
+// { dg-final { scan-tree-dump-not "_expr" "forwprop3" } }
-- 
2.54.0

Reply via email to