]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Prevent creation of paradoxical FLOAT_MODE subregs
authorBernd Schmidt <bernds@redhat.com>
Fri, 28 Jun 2002 15:43:54 +0000 (15:43 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Fri, 28 Jun 2002 15:43:54 +0000 (15:43 +0000)
From-SVN: r55064

gcc/ChangeLog
gcc/emit-rtl.c
gcc/recog.c

index 42ac032fac0c6156b03d0b199594a769f258068e..0b8c5a7567328c93cadba4702f5cb869042a2d70 100644 (file)
@@ -1,3 +1,9 @@
+2001-06-08  Bernd Schmidt  <bernds@redhat.com>
+
+       * emit-rtl.c (gen_lowpart_common): Don't create paradoxical FLOAT_MODE
+       subregs.
+       * recog.c (general_operand, register_operand): Disallow them.
+
 2002-06-28  Neil Booth  <neil@daikokuya.co.uk>
 
        PR preprocessor/7138
index 77697aef7e4697fc3201b47a9922502da9f7db4d..956d38db7424317c232cc980b4146d9f3425991c 100644 (file)
@@ -964,6 +964,11 @@ gen_lowpart_common (mode, x)
          > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
     return 0;
 
+  /* Don't allow generating paradoxical FLOAT_MODE subregs.  */
+  if (GET_MODE_CLASS (mode) == MODE_FLOAT
+      && GET_MODE (x) != VOIDmode && msize > xsize)
+    return 0;
+
   offset = subreg_lowpart_offset (mode, GET_MODE (x));
 
   if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
index 005885bc12515f7e9a3503e940321eb175dde27b..5b5d3dc062a8b78be0cc18f0e2ecc300be17da6d 100644 (file)
@@ -958,11 +958,13 @@ general_operand (op, mode)
 
   if (code == SUBREG)
     {
+      rtx sub = SUBREG_REG (op);
+
 #ifdef INSN_SCHEDULING
       /* On machines that have insn scheduling, we want all memory
         reference to be explicit, so outlaw paradoxical SUBREGs.  */
-      if (GET_CODE (SUBREG_REG (op)) == MEM
-         && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))
+      if (GET_CODE (sub) == MEM
+         && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
        return 0;
 #endif
       /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
@@ -972,10 +974,16 @@ general_operand (op, mode)
 
         ??? This is a kludge.  */
       if (!reload_completed && SUBREG_BYTE (op) != 0
-         && GET_CODE (SUBREG_REG (op)) == MEM)
+         && GET_CODE (sub) == MEM)
        return 0;
 
-      op = SUBREG_REG (op);
+      /* FLOAT_MODE subregs can't be paradoxical.  Combine will occasionally
+        create such rtl, and we must reject it.  */
+      if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
+         && GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
+       return 0;
+
+      op = sub;
       code = GET_CODE (op);
     }
 
@@ -1048,28 +1056,36 @@ register_operand (op, mode)
 
   if (GET_CODE (op) == SUBREG)
     {
+      rtx sub = SUBREG_REG (op);
+
       /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
         because it is guaranteed to be reloaded into one.
         Just make sure the MEM is valid in itself.
         (Ideally, (SUBREG (MEM)...) should not exist after reload,
         but currently it does result from (SUBREG (REG)...) where the
         reg went on the stack.)  */
-      if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM)
+      if (! reload_completed && GET_CODE (sub) == MEM)
        return general_operand (op, mode);
 
 #ifdef CLASS_CANNOT_CHANGE_MODE
-      if (GET_CODE (SUBREG_REG (op)) == REG
-         && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER
+      if (GET_CODE (sub) == REG
+         && REGNO (sub) < FIRST_PSEUDO_REGISTER
          && (TEST_HARD_REG_BIT
              (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
-              REGNO (SUBREG_REG (op))))
-         && CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (SUBREG_REG (op)))
-         && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op))) != MODE_COMPLEX_INT
-         && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op))) != MODE_COMPLEX_FLOAT)
+              REGNO (sub)))
+         && CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (sub))
+         && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
+         && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
        return 0;
 #endif
 
-      op = SUBREG_REG (op);
+      /* FLOAT_MODE subregs can't be paradoxical.  Combine will occasionally
+        create such rtl, and we must reject it.  */
+      if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
+         && GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
+       return 0;
+
+      op = sub;
     }
 
   /* If we have an ADDRESSOF, consider it valid since it will be