&& (INTEGRAL_TYPE_P (TREE_TYPE (@0))))
(op (mult (convert:type @0) @2) @1))))
+/* ?: Value replacement. */
+/* a == 0 ? b : b + a -> b + a */
+(for op (plus bit_ior bit_xor)
+ (simplify
+ (cond (eq @0 integer_zerop) @1 (op:c@2 @1 @0))
+ @2))
+/* a == 0 ? b : b - a -> b - a */
+/* a == 0 ? b : b ptr+ a -> b ptr+ a */
+/* a == 0 ? b : b shift/rotate a -> b shift/rotate a */
+(for op (lrotate rrotate lshift rshift minus pointer_plus)
+ (simplify
+ (cond (eq @0 integer_zerop) @1 (op@2 @1 @0))
+ @2))
+
/* Simplifications of shift and rotates. */
(for rotate (lrotate rrotate)
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+int sub(int a, int b, int c, int d) {
+ int e = (a == 0);
+ int f = !e;
+ c = b;
+ d = b - a ;
+ return ((-e & c) | (-f & d));
+}
+
+/* In the end we end up with `(a == 0) ? (b - a) : b`
+ which then can be optimized to just `(b - a)`. */
+
+/* { dg-final { scan-tree-dump-not "cond_expr," "optimized" } } */
+/* { dg-final { scan-tree-dump-not "eq_expr," "optimized" } } */
+/* { dg-final { scan-tree-dump-times "minus_expr," 1 "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* Phi-OPT should be able to optimize this without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
+
+char *f(char *a, __SIZE_TYPE__ b) {
+ char *d = a + b;
+ if (b == 0) return a;
+ return d;
+}
+int sub(int a, int b, int c) {
+ int d = a - b;
+ if (b == 0) return a;
+ return d;
+}
+
+/* { dg-final { scan-tree-dump-not "goto" "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+[[gnu::const]]
+int constcall(int);
+
+int f(int a, int b)
+{
+ int c = b+a;
+ int t = constcall(c);
+ int d;
+ if (a == 0) d= b; else d= c;
+ return constcall(d) + t;
+}
+
+/* There should be no if statement and 2 calls to call1. */
+/* { dg-final { scan-tree-dump-not "if " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "constcall " 1 "optimized" } } */
+
--- /dev/null
+/* { dg-do compile } */
+/* Phi-OPT should be able to optimize this without sinking being invoked. */
+/* { dg-options "-O -fdump-tree-phiopt2 -fdump-tree-optimized -fno-tree-sink" } */
+
+int f(int a, int b, int c) {
+ int d = a + b;
+ if (c > 5) return c;
+ if (a == 0) return b;
+ return d;
+}
+
+unsigned rot(unsigned x, int n) {
+ const int bits = __CHAR_BIT__ * __SIZEOF_INT__;
+ int t = ((x << n) | (x >> (bits - n)));
+ return (n == 0) ? x : t;
+}
+
+/* { dg-final { scan-tree-dump-times "goto" 2 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "goto" 2 "optimized" } } */