[Bug middle-end/55142] [4.8 Regression] internal compiler error: in plus_constant, at explow.c:88
hjl.tools at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Oct 31 12:20:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55142
--- Comment #8 from H.J. Lu <hjl.tools at gmail dot com> 2012-10-31 12:19:56 UTC ---
Does this make any senses?
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 5ea5110..50879d6 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -7038,6 +7038,24 @@ fold_to_nonsharp_ineq_using_bound (location_t loc, tree
ineq, tree bound)
return fold_build2_loc (loc, GE_EXPR, type, a, y);
}
+static unsigned int
+unsigned_expr_operands (tree op)
+{
+ switch (TREE_CODE (op))
+ {
+ case MULT_EXPR:
+ if (!unsigned_expr_operands (TREE_OPERAND (op, 0)))
+ return 0;
+ return unsigned_expr_operands (TREE_OPERAND (op, 1));
+
+ case NOP_EXPR:
+ return unsigned_expr_operands (TREE_OPERAND (op, 0));
+
+ default:
+ return TYPE_UNSIGNED (TREE_TYPE (op));
+ }
+}
+
/* Fold a sum or difference of at least one multiplication.
Returns the folded tree or NULL if no simplification could be made. */
@@ -7048,6 +7066,17 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code
code, tree type,
tree arg00, arg01, arg10, arg11;
tree alt0 = NULL_TREE, alt1 = NULL_TREE, same;
+ /* Make sure the type is not saturating and has the signedness of
+ the stripped operands, as fold_plusminus_mult_expr will re-associate.
+ ??? The latter condition should use TYPE_OVERFLOW_* flags instead. */
+ if (!((TREE_CODE (arg0) == MULT_EXPR
+ || TREE_CODE (arg1) == MULT_EXPR)
+ && !TYPE_SATURATING (type)
+ && TYPE_UNSIGNED (type) == unsigned_expr_operands (arg0)
+ && TYPE_UNSIGNED (type) == unsigned_expr_operands (arg1)
+ && (!FLOAT_TYPE_P (type) || flag_associative_math)))
+ return NULL_TREE;
+
/* (A * C) +- (B * C) -> (A+-B) * C.
(A * C) +- A -> A * (C+-1).
We are most concerned about the case where C is a constant,
@@ -10042,17 +10071,7 @@ fold_binary_loc (location_t loc,
}
}
- /* Handle (A1 * C1) + (A2 * C2) with A1, A2 or C1, C2 being the same or
- one. Make sure the type is not saturating and has the signedness of
- the stripped operands, as fold_plusminus_mult_expr will re-associate.
- ??? The latter condition should use TYPE_OVERFLOW_* flags instead. */
- if ((TREE_CODE (arg0) == MULT_EXPR
- || TREE_CODE (arg1) == MULT_EXPR)
- && !TYPE_SATURATING (type)
- && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg0))
- && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg1))
- && (!FLOAT_TYPE_P (type) || flag_associative_math))
- {
+ {
tree tem = fold_plusminus_mult_expr (loc, code, type, arg0, arg1);
if (tem)
return tem;
@@ -10668,17 +10687,7 @@ fold_binary_loc (location_t loc,
&& (tem = distribute_real_division (loc, code, type, arg0, arg1)))
return tem;
- /* Handle (A1 * C1) - (A2 * C2) with A1, A2 or C1, C2 being the same or
- one. Make sure the type is not saturating and has the signedness of
- the stripped operands, as fold_plusminus_mult_expr will re-associate.
- ??? The latter condition should use TYPE_OVERFLOW_* flags instead. */
- if ((TREE_CODE (arg0) == MULT_EXPR
- || TREE_CODE (arg1) == MULT_EXPR)
- && !TYPE_SATURATING (type)
- && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg0))
- && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg1))
- && (!FLOAT_TYPE_P (type) || flag_associative_math))
- {
+ {
tree tem = fold_plusminus_mult_expr (loc, code, type, arg0, arg1);
if (tem)
return tem;
More information about the Gcc-bugs
mailing list