On April 3, 2018 6:07:06 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >As the following testcases show, fold_builtin_expect replaces >__builtin_expect (x && y, z) with >__builtin_expect (x, z) && __builtin_expect (y, z) >and similarly for || instead of &&. It does so without any kind of >copying of the z argument, which means if it is e.g. statement >expression >without side-effects we try to destructively gimplify it multiple times >and ICE the second time we do so. Or, as the other testcase shows, >if there are any side-effects in that argument, we evaluate them >multiple >times. > >Fixed by doing save_expr on that argument first. arg2 doesn't need it, >as it is provided only internally from the compiler and is always >INTEGER_CST or NULL, nothing else. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. >2018-04-03 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/85156 > * builtins.c (fold_builtin_expect): Use save_expr on arg1 to avoid > evaluating the argument multiple times. > > * c-c++-common/pr85156.c: New test. > * gcc.c-torture/execute/pr85156.c: New test. > >--- gcc/builtins.c.jj 2018-04-01 08:03:09.786562444 +0200 >+++ gcc/builtins.c 2018-04-03 12:03:53.673566330 +0200 >@@ -7998,6 +7998,7 @@ fold_builtin_expect (location_t loc, tre > { > tree op0 = TREE_OPERAND (inner, 0); > tree op1 = TREE_OPERAND (inner, 1); >+ arg1 = save_expr (arg1); > > op0 = build_builtin_expect_predicate (loc, op0, arg1, arg2); > op1 = build_builtin_expect_predicate (loc, op1, arg1, arg2); >--- gcc/testsuite/c-c++-common/pr85156.c.jj 2018-04-03 >12:06:53.056572306 +0200 >+++ gcc/testsuite/c-c++-common/pr85156.c 2018-04-03 12:07:34.557573689 >+0200 >@@ -0,0 +1,11 @@ >+/* PR tree-optimization/85156 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -g" } */ >+ >+int a, b; >+ >+int >+foo (void) >+{ >+ return __builtin_expect (a ? b != 0 : 0, ({ 1; })); >+} >--- gcc/testsuite/gcc.c-torture/execute/pr85156.c.jj 2018-04-03 >12:09:34.095577676 +0200 >+++ gcc/testsuite/gcc.c-torture/execute/pr85156.c 2018-04-03 >12:09:20.886577235 +0200 >@@ -0,0 +1,21 @@ >+/* PR tree-optimization/85156 */ >+ >+int x, y; >+ >+__attribute__((noipa)) int >+foo (int z) >+{ >+ if (__builtin_expect (x ? y != 0 : 0, z++)) >+ return 7; >+ return z; >+} >+ >+int >+main () >+{ >+ x = 1; >+ asm volatile ("" : "+m" (x), "+m" (y)); >+ if (foo (10) != 11) >+ __builtin_abort (); >+ return 0; >+} > > Jakub