diff options
author | Richard Stallman <rms@gnu.org> | 1993-10-21 02:43:58 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-10-21 02:43:58 +0000 |
commit | 76fb0b6041539676f5abb95700db22f0c21376ed (patch) | |
tree | bb48288a4b6fdbe77ceb8d312da5b847b9711692 | |
parent | cc8187fc1da50b99899be52de1ce2aa83483d238 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cse.c | 27 |
1 files changed, 26 insertions, 1 deletions
@@ -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, |