aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1999-07-12 13:30:40 +0000
committerJeff Law <law@gcc.gnu.org>1999-07-12 07:30:40 -0600
commitcbbc503edd4ed154d86e4f7bd915e28ba616b610 (patch)
treec56c7eddc5e8a770ae6723b26cd5ba5ca503caf7
parentd4a8b6a2f37357e1ad9d7e998dc05738559b2ce5 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/expr.c26
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
diff --git a/gcc/expr.c b/gcc/expr.c
index a5c6f88..111e6eb 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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;