&& expr_no_side_effects_p (@1))
@2)))
-/* x != CST1 ? x + CST2 : 0 -> x + CST2 when CST1 == -CST2. */
-(simplify
- (cond (ne @0 INTEGER_CST@2) (plus@1 @0 INTEGER_CST@3) integer_zerop)
- (if (wi::to_wide (@2) == -wi::to_wide (@3))
- @1))
+/* x != CST1 ? x + CST2 : CST3 -> x + CST2 when CST1 + CST2 == CST3.
+ This handles both scalars and uniform vectors. */
+(for cnd (cond vec_cond)
+ (simplify
+ (cnd (ne @0 uniform_integer_cst_p@1)
+ (plus@2 @0 uniform_integer_cst_p@3)
+ uniform_integer_cst_p@4)
+ (with {
+ tree cst1 = uniform_integer_cst_p (@1);
+ tree cst2 = uniform_integer_cst_p (@3);
+ tree cst3 = uniform_integer_cst_p (@4);
+ }
+ (if (wi::to_wide (cst1) + wi::to_wide (cst2) == wi::to_wide (cst3))
+ @2))))
/* Simplifications of shift and rotates. */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-psabi -fdump-tree-forwprop1" } */
+
+#define vector4 __attribute__((vector_size(4*sizeof(int))))
+#define vector4_u8 __attribute__((vector_size(4*sizeof(unsigned char))))
+#define vector4_u32 __attribute__((vector_size(4*sizeof(unsigned int))))
+#define vector2_u64 __attribute__((vector_size(2*sizeof(unsigned long))))
+
+void unopt(vector4 int *v) {
+ vector4 int t = *v;
+ vector4 int t1 = t + 8;
+ *v = (t != -8) ? (t1) : (vector4 int){0, 0, 0, 0};
+}
+
+vector2_u64 unsigned long f1 (vector2_u64 unsigned long x) {
+ return x != (vector2_u64 unsigned long){5, 5}
+ ? x + (vector2_u64 unsigned long){10, 10}
+ : (vector2_u64 unsigned long){15, 15};
+}
+
+vector4_u32 unsigned int f2 (vector4_u32 unsigned int x)
+{
+ return x != (vector4_u32 unsigned int){20, 20, 20, 20}
+ ? x - (vector4_u32 unsigned int){5, 5, 5, 5}
+ : (vector4_u32 unsigned int){15, 15, 15, 15};
+}
+
+vector4_u8 unsigned char
+f3 (vector4_u8 unsigned char x)
+{
+ return x != (vector4_u8 unsigned char){100, 100, 100, 100}
+ ? x + (vector4_u8 unsigned char){166, 166, 166, 166}
+ : (vector4_u8 unsigned char){10, 10, 10, 10};
+}
+
+/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "forwprop1" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-psabi -fdump-tree-forwprop1" } */
+
+#define vector4 __attribute__((vector_size(4*sizeof(int))))
+#define vector2_u64 __attribute__((vector_size(2*sizeof(unsigned long))))
+
+vector4 int g1 (vector4 int x) {
+ vector4 int cst1 = {5, 1};
+ vector4 int cst2 = {10, 2};
+ vector4 int cst3 = {15, 3};
+ return x != cst1 ? x + cst2 : cst3;
+}
+
+vector2_u64 unsigned long g2 (vector2_u64 unsigned long x) {
+ return x != (vector2_u64 unsigned long){10, 10}
+ ? x + (vector2_u64 unsigned long){20, 20}
+ : (vector2_u64 unsigned long){40, 40};
+}
+
+/* { dg-final { scan-tree-dump-times "VEC_COND_EXPR" 2 "forwprop1" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long u64;
+
+u64 f1 (u64 x) { return x != 5 ? x + 10 : 15; }
+
+u32 f2 (u32 x) { return x != 20 ? x - 5 : 15; }
+
+u16 f3 (u16 x) { return x == 100 ? 150 : x + 50; }
+
+u8 f4 (u8 x) { return x != 250 ? x + 2 : 252; }
+
+u8 f5 (u8 x) {
+ if (x == 100)
+ return 10;
+ else
+ return x + 166;
+}
+
+/* { dg-final { scan-tree-dump-not "if " "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef unsigned int u32;
+typedef unsigned long u64;
+
+u64 g1 (u64 x) { return x != 10 ? x + 20 : 40; }
+
+u32 g2 (u32 x) { return x == 100 ? 10 : x + 166; }
+
+/* { dg-final { scan-tree-dump-times "if " 2 "optimized" } } */