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

Reply via email to