(fold_rtx): Alter previous change: don't fold the shift
authorRichard Stallman <rms@gnu.org>
Thu, 21 Oct 1993 02:43:58 +0000 (02:43 +0000)
committerRichard Stallman <rms@gnu.org>
Thu, 21 Oct 1993 02:43:58 +0000 (02:43 +0000)
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

gcc/cse.c

index 2f378763500ec26fbb6e07c7aa35a3f9e2f52c81..ade0532ce4521fb05dedb79be00053f3048062ac 100644 (file)
--- 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,