]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization: Fold constant conditional selects [PR124663]
authorTorbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Sat, 18 Jul 2026 09:00:32 +0000 (11:00 +0200)
committerTorbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Tue, 21 Jul 2026 20:10:49 +0000 (22:10 +0200)
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 <torbjorn.svensson@foss.st.com>
gcc/match.pd
gcc/testsuite/g++.dg/tree-ssa/pr124663.C [new file with mode: 0644]

index 017b1362b7e4a6bd85af7c810e3ed7a4b1127c87..723780b8c38148d24093e7edc003fdb96aa49463 100644 (file)
@@ -7112,7 +7112,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 (file)
index 0000000..dfd12de
--- /dev/null
@@ -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" } }