re PR target/53961 (internal compiler error: in memory_address_length, at config...
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 23 Jul 2012 16:04:23 +0000 (18:04 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 23 Jul 2012 16:04:23 +0000 (18:04 +0200)
PR target/53961
* config/i386/i386.md (*lea): Add asserts to detect invalid addresses.
* config/i386/i386.c (ix86_print_operand_address): Ditto.
(ix86_decompose_address): Allow (zero_extend:DI (subreg:SI (...)))
addresses.  Prevent zero extensions of CONST_INT operands.

From-SVN: r189787

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 6ab125c..a34897f 100644 (file)
@@ -1,3 +1,11 @@
+2012-07-23  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/53961
+       * config/i386/i386.md (*lea): Add asserts to detect invalid addresses.
+       * config/i386/i386.c (ix86_print_operand_address): Ditto.
+       (ix86_decompose_address): Allow (zero_extend:DI (subreg:SI (...)))
+       addresses.  Prevent zero extensions of CONST_INT operands.
+
 2012-07-22  Steven Bosscher  <steven@gcc.gnu.org>
 
        * sbitmap.h (struct int_list): Remove.
@@ -50,7 +58,7 @@
 
 2012-07-22  Steven Bosscher <steven@gcc.gnu.org>
 
-       * opts.c (common_handle_option): Do not set 
+       * opts.c (common_handle_option): Do not set
        flag_value_profile_transformations for -fprofile-generate.
        * profile.c (instrument_values): Use COUNTER_FOR_HIST_TYPE.
        (BB_TO_GCOV_INDEX): Remove.
index 06ef5db..13e0fdc 100644 (file)
@@ -11576,22 +11576,17 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
   int retval = 1;
   enum ix86_address_seg seg = SEG_DEFAULT;
 
-  /* Allow SImode subregs of DImode addresses,
-     they will be emitted with addr32 prefix.  */
-  if (TARGET_64BIT && GET_MODE (addr) == SImode)
-    {
-      if (GET_CODE (addr) == SUBREG
-         && GET_MODE (XEXP (addr, 0)) == DImode)
-       addr = SUBREG_REG (addr);
-    }
-
   /* Allow zero-extended SImode addresses,
      they will be emitted with addr32 prefix.  */
-  else if (TARGET_64BIT && GET_MODE (addr) == DImode)
+  if (TARGET_64BIT && GET_MODE (addr) == DImode)
     {
       if (GET_CODE (addr) == ZERO_EXTEND
          && GET_MODE (XEXP (addr, 0)) == SImode)
-       addr = XEXP (addr, 0);
+       {
+         addr = XEXP (addr, 0);
+         if (CONST_INT_P (addr))
+           return 0;
+       }             
       else if (GET_CODE (addr) == AND
               && const_32bit_mask (XEXP (addr, 1), DImode))
        {
@@ -11600,7 +11595,11 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
          /* Adjust SUBREGs.  */
          if (GET_CODE (addr) == SUBREG
              && GET_MODE (SUBREG_REG (addr)) == SImode)
-           addr = SUBREG_REG (addr);
+           {
+             addr = SUBREG_REG (addr);
+             if (CONST_INT_P (addr))
+               return 0;
+           }
          else if (GET_MODE (addr) == DImode)
            addr = gen_rtx_SUBREG (SImode, addr, 0);
          else if (GET_MODE (addr) != VOIDmode)
@@ -11608,6 +11607,19 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
        }
     }
 
+  /* Allow SImode subregs of DImode addresses,
+     they will be emitted with addr32 prefix.  */
+  if (TARGET_64BIT && GET_MODE (addr) == SImode)
+    {
+      if (GET_CODE (addr) == SUBREG
+         && GET_MODE (SUBREG_REG (addr)) == DImode)
+       {
+         addr = SUBREG_REG (addr);
+         if (CONST_INT_P (addr))
+           return 0;
+       }
+    }
+
   if (REG_P (addr))
     base = addr;
   else if (GET_CODE (addr) == SUBREG)
@@ -14765,11 +14777,19 @@ ix86_print_operand_address (FILE *file, rtx addr)
   else
     {
       /* Print SImode register names to force addr32 prefix.  */
-      if (TARGET_64BIT
-         && (GET_CODE (addr) == SUBREG
-             || GET_CODE (addr) == ZERO_EXTEND
-             || GET_CODE (addr) == AND))
+      if (GET_CODE (addr) == SUBREG)
+       {
+         gcc_assert (TARGET_64BIT);
+         gcc_assert (GET_MODE (addr) == SImode);
+         gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
+         gcc_assert (!code);
+         code = 'l';
+       }
+      else if (GET_CODE (addr) == ZERO_EXTEND
+              || GET_CODE (addr) == AND)
        {
+         gcc_assert (TARGET_64BIT);
+         gcc_assert (GET_MODE (addr) == DImode);
          gcc_assert (!code);
          code = 'l';
        }
index f559ff2..114ad13 100644 (file)
   rtx addr = operands[1];
 
   if (GET_CODE (addr) == SUBREG)
-    return "lea{l}\t{%E1, %0|%0, %E1}";
+    {
+      gcc_assert (TARGET_64BIT);
+      gcc_assert (<MODE>mode == SImode);
+      gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
+      return "lea{l}\t{%E1, %0|%0, %E1}";
+    }
   else if (GET_CODE (addr) == ZERO_EXTEND
           || GET_CODE (addr) == AND)
-    return "lea{l}\t{%E1, %k0|%k0, %E1}";
+    {
+      gcc_assert (TARGET_64BIT);
+      gcc_assert (<MODE>mode == DImode);
+      return "lea{l}\t{%E1, %k0|%k0, %E1}";
+    }
   else 
     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
 }