On February 15, 2020 7:09:51 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >As the following testcases show (the first one reported, last two >found by code inspection), we need to disallow side-effects >in simplifications that turn some unconditional expression into >conditional >one. From my little understanding of genmatch.c, it is able to >automatically disallow side effects if the same operand is used >multiple >times in the match pattern, maybe if it is used multiple times in the >replacement pattern, and if it is used in conditional contexts in the >match >pattern, could it be taught to handle this case too? If yes, perhaps >just the first hunk could be usable for 8/9 backports (+ the >testcases).
It could possibly be done but then it's only three cases so far. OK. Richard. >Bootstrapped/regtested on x86_64-linux and i686-linux. > >2020-02-15 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/93744 > * match.pd (((m1 >/</>=/<= m2) * d -> (m1 >/</>=/<= m2) ? d : 0, > A - ((A - B) & -(C cmp D)) -> (C cmp D) ? B : A, > A + ((B - A) & -(C cmp D)) -> (C cmp D) ? B : A): For GENERIC, make > sure @2 in the first and @1 in the other patterns has no side-effects. > > * gcc.c-torture/execute/pr93744-1.c: New test. > * gcc.c-torture/execute/pr93744-2.c: New test. > * gcc.c-torture/execute/pr93744-3.c: New test. > >--- gcc/match.pd.jj 2020-02-05 11:12:33.679383217 +0100 >+++ gcc/match.pd 2020-02-14 22:49:22.858771394 +0100 >@@ -1472,7 +1472,8 @@ (define_operator_list COND_TERNARY > (for cmp (gt lt ge le) > (simplify > (mult (convert (cmp @0 @1)) @2) >- (cond (cmp @0 @1) @2 { build_zero_cst (type); }))) >+ (if (GIMPLE || !TREE_SIDE_EFFECTS (@2)) >+ (cond (cmp @0 @1) @2 { build_zero_cst (type); })))) > > /* For integral types with undefined overflow and C != 0 fold > x * C EQ/NE y * C into x EQ/NE y. */ >@@ -2709,7 +2710,8 @@ (define_operator_list COND_TERNARY > && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE > && INTEGRAL_TYPE_P (TREE_TYPE (@5)) > && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type) >- || !TYPE_UNSIGNED (TREE_TYPE (@4)))) >+ || !TYPE_UNSIGNED (TREE_TYPE (@4))) >+ && (GIMPLE || !TREE_SIDE_EFFECTS (@1))) > (cond (cmp @2 @3) @1 @0))) > (simplify > (plus:c @0 (bit_and:c (minus @1 @0) >@@ -2719,7 +2721,8 @@ (define_operator_list COND_TERNARY > && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE > && INTEGRAL_TYPE_P (TREE_TYPE (@5)) > && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type) >- || !TYPE_UNSIGNED (TREE_TYPE (@4)))) >+ || !TYPE_UNSIGNED (TREE_TYPE (@4))) >+ && (GIMPLE || !TREE_SIDE_EFFECTS (@1))) > (cond (cmp @2 @3) @1 @0)))) > > /* Simplifications of shift and rotates. */ >--- gcc/testsuite/gcc.c-torture/execute/pr93744-1.c.jj 2020-02-14 >22:50:58.993346192 +0100 >+++ gcc/testsuite/gcc.c-torture/execute/pr93744-1.c 2020-02-14 >22:49:57.934251395 +0100 >@@ -0,0 +1,14 @@ >+/* PR tree-optimization/93744 */ >+ >+typedef int I; >+ >+int >+main () >+{ >+ int a = 0; >+ I b = 0; >+ (a > 0) * (b |= 2); >+ if (b != 2) >+ __builtin_abort (); >+ return 0; >+} >--- gcc/testsuite/gcc.c-torture/execute/pr93744-2.c.jj 2020-02-14 >22:51:01.100314955 +0100 >+++ gcc/testsuite/gcc.c-torture/execute/pr93744-2.c 2020-02-14 >22:50:18.299949478 +0100 >@@ -0,0 +1,21 @@ >+/* PR tree-optimization/93744 */ >+ >+int w; >+ >+int >+foo (int x, int y, int z) >+{ >+ int r = z - ((z - w++) & -(x < y)); >+ return r; >+} >+ >+int >+main () >+{ >+ w = 4; >+ if (foo (5, 7, 12) != 4 || w != 5) >+ __builtin_abort (); >+ if (foo (7, 5, 12) != 12 || w != 6) >+ __builtin_abort (); >+ return 0; >+} >--- gcc/testsuite/gcc.c-torture/execute/pr93744-3.c.jj 2020-02-14 >22:51:03.415280636 +0100 >+++ gcc/testsuite/gcc.c-torture/execute/pr93744-3.c 2020-02-14 >22:50:25.820837971 +0100 >@@ -0,0 +1,21 @@ >+/* PR tree-optimization/93744 */ >+ >+int w; >+ >+int >+foo (int x, int y, int z) >+{ >+ int r = z + ((w++ - z) & -(x < y)); >+ return r; >+} >+ >+int >+main () >+{ >+ w = 4; >+ if (foo (5, 7, 12) != 4 || w != 5) >+ __builtin_abort (); >+ if (foo (7, 5, 12) != 12 || w != 6) >+ __builtin_abort (); >+ return 0; >+} > > Jakub