&& operand_equal_p (@1, @2)))
(with
{
+ bool one_before = false;
+ bool one_after = false;
int cmp = 0;
if (TREE_CODE (@1) == INTEGER_CST
&& TREE_CODE (@2) == INTEGER_CST)
- cmp = tree_int_cst_compare (@1, @2);
+ {
+ cmp = tree_int_cst_compare (@1, @2);
+ if (cmp < 0
+ && wi::to_wide (@1) == wi::to_wide (@2) - 1)
+ one_before = true;
+ if (cmp > 0
+ && wi::to_wide (@1) == wi::to_wide (@2) + 1)
+ one_after = true;
+ }
bool val;
switch (code2)
{
&& code2 == LE_EXPR
&& cmp == 0)
(lt @0 @1))
+ /* (a != (b+1)) & (a > b) -> a > (b+1) */
+ (if (code1 == NE_EXPR
+ && code2 == GT_EXPR
+ && one_after)
+ (gt @0 @1))
+ /* (a != (b-1)) & (a < b) -> a < (b-1) */
+ (if (code1 == NE_EXPR
+ && code2 == LT_EXPR
+ && one_before)
+ (lt @0 @1))
)
)
)
&& operand_equal_p (@1, @2)))
(with
{
+ bool one_before = false;
+ bool one_after = false;
int cmp = 0;
if (TREE_CODE (@1) == INTEGER_CST
&& TREE_CODE (@2) == INTEGER_CST)
- cmp = tree_int_cst_compare (@1, @2);
+ {
+ cmp = tree_int_cst_compare (@1, @2);
+ if (cmp < 0
+ && wi::to_wide (@1) == wi::to_wide (@2) - 1)
+ one_before = true;
+ if (cmp > 0
+ && wi::to_wide (@1) == wi::to_wide (@2) + 1)
+ one_after = true;
+ }
bool val;
switch (code2)
{
&& code2 == LT_EXPR
&& cmp == 0)
(le @0 @1))
+ /* (a == (b-1)) | (a >= b) -> a >= (b-1) */
+ (if (code1 == EQ_EXPR
+ && code2 == GE_EXPR
+ && one_before)
+ (ge @0 @1))
+ /* (a == (b+1)) | (a <= b) -> a <= (b-1) */
+ (if (code1 == EQ_EXPR
+ && code2 == LE_EXPR
+ && one_after)
+ (le @0 @1))
)
)
)
return 1;
}
-/* { dg-final { scan-tree-dump-times "Optimizing range tests c_\[0-9\]*.D. -.0, 31. and -.32, 32.\[\n\r\]* into" 6 "reassoc1" } } */
+/* Note with match being able to simplify this, optimizing range tests is no longer needed here. */
+/* Equivalence: _7 | _2 -> c_5(D) <= 32 */
+/* old test: dg-final scan-tree-dump-times "Optimizing range tests c_\[0-9\]*.D. -.0, 31. and -.32, 32.\[\n\r\]* into" 6 "reassoc1" */
+/* { dg-final { scan-tree-dump-times "Equivalence: _\[0-9\]+ \\\| _\[0-9\]+ -> c_\[0-9\]+.D. <= 32" 5 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "Equivalence: _\[0-9\]+ \& _\[0-9\]+ -> c_\[0-9\]+.D. > 32" 1 "reassoc1" } } */
--- /dev/null
+/* PR tree-optimization/106164 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1-details" } */
+
+
+int f(int a)
+{
+ int c = a != 2;
+ int d = a >= 2;
+ return c & d;
+}
+int g(int b)
+{
+ int c = b != -1;
+ int d = b <= -1;
+ return c & d;
+}
+
+
+int g_(int e)
+{
+ int c = e != -2;
+ int d = e <= -2;
+ return c & d;
+}
+
+int f1(int x)
+{
+ int c = x == 2;
+ int d = x <= 1;
+ return c | d;
+}
+int g1(int y)
+{
+ int c = y == -1;
+ int d = y > -1;
+ return c | d;
+}
+int g1_(int z)
+{
+ int c = z == -2;
+ int d = z >= -1;
+ return c | d;
+}
+
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]+ = a_\[0-9\]+.D. > 2" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]+ = b_\[0-9\]+.D. < -1" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]+ = e_\[0-9\]+.D. < -2" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]+ = x_\[0-9\]+.D. <= 2" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]+ = y_\[0-9\]+.D. >= -1" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]+ = z_\[0-9\]+.D. >= -2" "forwprop1" } } */
--- /dev/null
+/* PR tree-optimization/106164 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-phiopt2" } */
+
+_Bool f2(int a)
+{
+ if (a != 2)
+ return a > 1;
+ return 0;
+}
+/* phiopt2 should be able to optimize this to `a > 2` via match and simplify */
+/* { dg-final { scan-tree-dump "_\[0-9\]+ = a_\[0-9\]+.D. > 2" "phiopt2" } } */
+/* { dg-final { scan-tree-dump-not "a_\[0-9\]+.D. != 2" "phiopt2" } } */