aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-10-21 02:43:58 +0000
committerRichard Stallman <rms@gnu.org>1993-10-21 02:43:58 +0000
commit76fb0b6041539676f5abb95700db22f0c21376ed (patch)
treebb48288a4b6fdbe77ceb8d312da5b847b9711692 /gcc
parentcc8187fc1da50b99899be52de1ce2aa83483d238 (diff)
downloadgcc-76fb0b6041539676f5abb95700db22f0c21376ed.zip
gcc-76fb0b6041539676f5abb95700db22f0c21376ed.tar.gz
gcc-76fb0b6041539676f5abb95700db22f0c21376ed.tar.bz2
(fold_rtx): Alter previous change: don't fold the shift
if the count exceeds the width of the value inside the subreg. (note_mem_written): (mem (scratch)) means clobber everything. (fold_rtx): Special case handling for folding a subreg of the result of a left shift. From-SVN: r5854
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cse.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 2f37876..ade0532 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4729,7 +4729,29 @@ fold_rtx (x, insn)
if (op1)
op1 = equiv_constant (op1);
- if (op0 && op1)
+ /* If we are looking for the low SImode part of
+ (ashift:DI c (const_int 32)), it doesn't work
+ to compute that in SImode, because a 32-bit shift
+ in SImode is unpredictable. We know the value is 0. */
+ if (op0 && op1
+ && (GET_CODE (elt->exp) == ASHIFT
+ || GET_CODE (elt->exp) == LSHIFT)
+ && GET_CODE (op1) == CONST_INT
+ && INTVAL (op1) >= GET_MODE_BITSIZE (mode))
+ {
+ if (INTVAL (op1) < GET_MODE_BITSIZE (GET_MODE (elt->exp)))
+
+ /* If the count fits in the inner mode's width,
+ but exceeds the outer mode's width,
+ the value will get truncated to 0
+ by the subreg. */
+ new = const0_rtx;
+ else
+ /* If the count exceeds even the inner mode's width,
+ don't fold this expression. */
+ new = 0;
+ }
+ else if (op0 && op1)
new = simplify_binary_operation (GET_CODE (elt->exp), mode,
op0, op1);
}
@@ -7101,6 +7123,9 @@ note_mem_written (written, writes_ptr)
}
else if (GET_MODE (written) == BLKmode)
*writes_ptr = everything;
+ /* (mem (scratch)) means clobber everything. */
+ else if (GET_CODE (addr) == SCRATCH)
+ *writes_ptr = everything;
else if (cse_rtx_addr_varies_p (written))
{
/* A varying address that is a sum indicates an array element,