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; +}