The following fixes fold_binary_op_with_conditional_arg to not move
a possibly trapping operation into the conditional arms because
this breaks later re-gimplification and also because we lose
information this way (like dividend is nonzero on the unconditional path).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

>From d705c926cd25d7794df6d5759a3f94c307c30c8c Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguent...@suse.de>
Date: Wed, 11 Jul 2018 12:37:58 +0200
Subject: [PATCH] fix-pr86479

2018-07-11  Richard Biener  <rguent...@suse.de>

        PR middle-end/86479
        * fold-const.c (fold_binary_op_with_conditional_arg): Do not
        move possibly trapping operations into the conditional.

        * gcc.dg/graphite/pr86479.c: New testcase.

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 97c435fa5e0..ac65dcfaf1d 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6587,6 +6587,13 @@ fold_binary_op_with_conditional_arg (location_t loc,
   tree rhs = NULL_TREE;
   enum tree_code cond_code = COND_EXPR;
 
+  /* Do not move possibly trapping operations into the conditional as this
+     pessimizes code and causes gimplification issues when applied late.  */
+  if (operation_could_trap_p (code, FLOAT_TYPE_P (type),
+                             ANY_INTEGRAL_TYPE_P (type)
+                             && TYPE_OVERFLOW_TRAPS (type), op1))
+    return NULL_TREE;
+
   if (TREE_CODE (cond) == COND_EXPR
       || TREE_CODE (cond) == VEC_COND_EXPR)
     {
diff --git a/gcc/testsuite/gcc.dg/graphite/pr86479.c 
b/gcc/testsuite/gcc.dg/graphite/pr86479.c
new file mode 100644
index 00000000000..7df63546c05
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr86479.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -floop-nest-optimize -fnon-call-exceptions 
-fno-guess-branch-probability -fno-tree-loop-im" } */
+
+__INTPTR_TYPE__ uf;
+
+void
+m7 (__INTPTR_TYPE__ *aw, __INTPTR_TYPE__ ws)
+{
+  __INTPTR_TYPE__ *e5 = &ws;
+
+  if (ws < 1)
+    {
+      int cq = 0;
+
+      while (cq < 1)
+        {
+          int *ng;
+          int *ud;
+
+          *e5 *= uf < 0;
+
+          for (*ng = 0; *ng < 2; ++*ng)
+            {
+            }
+
+          ws /= cq;
+          *aw *= ws;
+
+          for (*ud = 0; *ud < 2; ++*ud)
+            {
+            }
+        }
+    }
+
+  if (ws < 2)
+    e5 = &uf;
+
+  *e5 = 0;
+}

Reply via email to