diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1994-12-13 07:50:58 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1994-12-13 07:50:58 -0500 |
commit | ae4311830e2a3915fe7c05227ac4a49d960420b7 (patch) | |
tree | dff17658f3eb622fa50779555d50fc90b54a0dba /gcc | |
parent | cd8ce14b50e90712ceaabbab45f6fa286675739b (diff) | |
download | gcc-ae4311830e2a3915fe7c05227ac4a49d960420b7.zip gcc-ae4311830e2a3915fe7c05227ac4a49d960420b7.tar.gz gcc-ae4311830e2a3915fe7c05227ac4a49d960420b7.tar.bz2 |
(expand_expr, case MINUS_EXPR): Properly handle case when the NEGATE
overflows.
From-SVN: r8648
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/expr.c | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -5239,10 +5239,29 @@ expand_expr (exp, target, tmode, modifier) /* Convert A - const to A + (-const). */ if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) { - exp = build (PLUS_EXPR, type, TREE_OPERAND (exp, 0), - fold (build1 (NEGATE_EXPR, type, - TREE_OPERAND (exp, 1)))); - goto plus_expr; + tree negated = fold (build1 (NEGATE_EXPR, type, + TREE_OPERAND (exp, 1))); + + /* Deal with the case where we can't negate the constant + in TYPE. */ + if (TREE_UNSIGNED (type) || TREE_OVERFLOW (negated)) + { + tree newtype = signed_type (type); + tree newop0 = convert (newtype, TREE_OPERAND (exp, 0)); + tree newop1 = convert (newtype, TREE_OPERAND (exp, 1)); + tree newneg = fold (build1 (NEGATE_EXPR, newtype, newop1)); + + if (! TREE_OVERFLOW (newneg)) + return expand_expr (convert (type, + build (PLUS_EXPR, newtype, + newop0, newneg)), + target, tmode, modifier); + } + else + { + exp = build (PLUS_EXPR, type, TREE_OPERAND (exp, 0), negated); + goto plus_expr; + } } this_optab = sub_optab; goto binop; |