aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0781f4212b7..8e1b0623763 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -473,12 +473,15 @@ negate_expr_p (tree t)
case EXACT_DIV_EXPR:
if (TYPE_UNSIGNED (type))
break;
- if (negate_expr_p (TREE_OPERAND (t, 0)))
+ /* In general we can't negate A in A / B, because if A is INT_MIN and
+ B is not 1 we change the sign of the result. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
+ && negate_expr_p (TREE_OPERAND (t, 0)))
return true;
/* In general we can't negate B in A / B, because if A is INT_MIN and
B is 1, we may turn this into INT_MIN / -1 which is undefined
and actually traps on some architectures. */
- if (! INTEGRAL_TYPE_P (TREE_TYPE (t))
+ if (! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
&& ! integer_onep (TREE_OPERAND (t, 1))))
@@ -652,14 +655,17 @@ fold_negate_expr_1 (location_t loc, tree t)
case EXACT_DIV_EXPR:
if (TYPE_UNSIGNED (type))
break;
- if (negate_expr_p (TREE_OPERAND (t, 0)))
+ /* In general we can't negate A in A / B, because if A is INT_MIN and
+ B is not 1 we change the sign of the result. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
+ && negate_expr_p (TREE_OPERAND (t, 0)))
return fold_build2_loc (loc, TREE_CODE (t), type,
negate_expr (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1));
/* In general we can't negate B in A / B, because if A is INT_MIN and
B is 1, we may turn this into INT_MIN / -1 which is undefined
and actually traps on some architectures. */
- if ((! INTEGRAL_TYPE_P (TREE_TYPE (t))
+ if ((! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t))
|| TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
&& ! integer_onep (TREE_OPERAND (t, 1))))