diff options
author | Jeffrey A Law <law@cygnus.com> | 1999-07-12 13:30:40 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1999-07-12 07:30:40 -0600 |
commit | cbbc503edd4ed154d86e4f7bd915e28ba616b610 (patch) | |
tree | c56c7eddc5e8a770ae6723b26cd5ba5ca503caf7 | |
parent | d4a8b6a2f37357e1ad9d7e998dc05738559b2ce5 (diff) | |
download | gcc-cbbc503edd4ed154d86e4f7bd915e28ba616b610.zip gcc-cbbc503edd4ed154d86e4f7bd915e28ba616b610.tar.gz gcc-cbbc503edd4ed154d86e4f7bd915e28ba616b610.tar.bz2 |
expr.c (expand_expr, [...]): Pass constants through immed_double_const to ensure they are properly truncated...
* expr.c (expand_expr, case PLUS_EXPR): Pass constants through
immed_double_const to ensure they are properly truncated then
sign extended.
From-SVN: r28066
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 26 |
2 files changed, 30 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 95e8005..fd5d177 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Mon Jul 12 14:29:15 1999 Jeffrey A Law (law@cygnus.com) + + * expr.c (expand_expr, case PLUS_EXPR): Pass constants through + immed_double_const to ensure they are properly truncated then + sign extended. + Mon Jul 12 10:40:01 1999 Vladimir Makarov <vmakarov@tofu.to.cygnus.com> * config/arm/thumb.c (thumb_reorg): Call replace_symbols_in_block @@ -6968,13 +6968,25 @@ expand_expr (exp, target, tmode, modifier) if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER || mode == ptr_mode) { + rtx constant_part; + if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT && TREE_CONSTANT (TREE_OPERAND (exp, 1))) { + rtx constant_part; + op1 = expand_expr (TREE_OPERAND (exp, 1), subtarget, VOIDmode, EXPAND_SUM); - op1 = plus_constant (op1, TREE_INT_CST_LOW (TREE_OPERAND (exp, 0))); + /* Use immed_double_const to ensure that the constant is + truncated according to the mode of OP1, then sign extended + to a HOST_WIDE_INT. Using the constant directly can result + in non-canonical RTL in a 64x32 cross compile. */ + constant_part + = immed_double_const (TREE_INT_CST_LOW (TREE_OPERAND (exp, 0)), + (HOST_WIDE_INT) 0, + GET_MODE (op1)); + op1 = plus_constant (op1, XINT (constant_part, 0)); if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) op1 = force_operand (op1, target); return op1; @@ -6984,6 +6996,8 @@ expand_expr (exp, target, tmode, modifier) && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_INT && TREE_CONSTANT (TREE_OPERAND (exp, 0))) { + rtx constant_part; + op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_SUM); if (! CONSTANT_P (op0)) @@ -6996,7 +7010,15 @@ expand_expr (exp, target, tmode, modifier) goto binop2; goto both_summands; } - op0 = plus_constant (op0, TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))); + /* Use immed_double_const to ensure that the constant is + truncated according to the mode of OP1, then sign extended + to a HOST_WIDE_INT. Using the constant directly can result + in non-canonical RTL in a 64x32 cross compile. */ + constant_part + = immed_double_const (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)), + (HOST_WIDE_INT) 0, + GET_MODE (op0)); + op0 = plus_constant (op0, XINT (constant_part, 0)); if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER) op0 = force_operand (op0, target); return op0; |