re PR target/49927 (ice in spill_failure, at reload1.c:2120)
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 1 Aug 2011 17:13:30 +0000 (19:13 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 1 Aug 2011 17:13:30 +0000 (19:13 +0200)
PR target/49927
* config/i386/i386.c (ix86_address_subreg_operand): New.
(ix86_decompose_address): Use ix86_address_subreg_operand.
(ix86_legitimate_address_p): Do not assert that subregs satisfy
register_no_elim_operand in DImode.

testsuite/ChangeLog:

PR target/49927
* gcc.target/i386/pr49927.c: New test.

From-SVN: r177064

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr49927.c [new file with mode: 0644]

index 1b5e6de57cd9c84dfe6c051b463b3cb5b75244f3..c3d1b3a14d6bc1cc7828dc2caa2acd2e930cd54b 100644 (file)
@@ -1,3 +1,11 @@
+2011-08-01  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/49927
+       * config/i386/i386.c (ix86_address_subreg_operand): New.
+       (ix86_decompose_address): Use ix86_address_subreg_operand.
+       (ix86_legitimate_address_p): Do not assert that subregs satisfy
+       register_no_elim_operand in DImode.
+
 2011-08-01  Ira Rosen  <ira.rosen@linaro.org>
 
        PR tree-optimization/49926
@@ -5,7 +13,7 @@
        in a chain doesn't have uses both inside and outside the loop.
 
 2011-08-01  Georg-Johann Lay  <avr@gjlay.de>
-       
+
        * config/avr/avr.h (mcu_type_s): Add errata_skip field.
        * config/avr/avr-devices.c (avr_mcu_types): Use it.
        * config/avr/avr-mcus.def (AVR_MCU): Use it.
@@ -17,7 +25,8 @@
 
 2011-08-02  Alan Modra  <amodra@gmail.com>
 
-       * config/rs6000/rs6000-protos.h (rs6000_save_toc_in_prologue_p): Delete.
+       * config/rs6000/rs6000-protos.h (rs6000_save_toc_in_prologue_p):
+       Delete.
        * config/rs6000/rs6000.c (rs6000_save_toc_in_prologue_p): Make static.
        (rs6000_emit_prologue): Don't prematurely return when
        TARGET_SINGLE_PIC_BASE.  Don't emit eh_frame info in
 2011-08-01  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        PR target/49547
-       * config.gcc (i[34567]86-*-*): Replace abmintrin.h with
-       lzcntintrin.h.
+       * config.gcc (i[34567]86-*-*): Replace abmintrin.h with lzcntintrin.h.
        (x86_64-*-*): Likewise.
        * config/i386/i386.opt (mlzcnt): New.
        * config/i386/abmintrin.h: File removed.
        (__lzcnt_u16, __lzcnt, __lzcnt_u64): Moved to ...
-       * config/i386/lzcntintrin.h: ... here. New file.
+       * config/i386/lzcntintrin.h: ... here.  New file.
        (__lzcnt): Rename to ...
        (__lzcnt32): ... this.
        * config/i386/bmiintrin.h (head): Update copyright year.
        (*rep_stosdi_rex64): Disable when %eax, %ecx or %edi are fixed.
        (*rep_stossi): Ditto.
        (*rep_stosqi): Ditto.
+       (*strlenqi_1): Ditto.
        (cmpstrnsi): Also fail when %ecx is fixed.
        (*cmpstrnqi_nz_1): Disable when %ecx, %esi or %edi are fixed.
        (*cmpstrnqi_1): Ditto.
-       (*strlenqi_1): Ditto.
        (*strmovdi_rex_1): Disable when %esi or %edi are fixed.
        (*strmovsi_1): Ditto.
        (*strmovhi_1): Ditto.
index c8ea48f7cd807041d9411daa92094a25462065c0..0e4f3f46de69f1921b9a562a6e8d5490e27b5e81 100644 (file)
@@ -11096,6 +11096,30 @@ ix86_live_on_entry (bitmap regs)
     }
 }
 \f
+/* Determine if op is suitable SUBREG RTX for address.  */
+
+static bool
+ix86_address_subreg_operand (rtx op)
+{
+  enum machine_mode mode;
+
+  if (!REG_P (op))
+    return false;
+
+  mode = GET_MODE (op);
+
+  if (GET_MODE_CLASS (mode) != MODE_INT)
+    return false;
+
+  /* Don't allow SUBREGs that span more than a word.  It can lead to spill
+     failures when the register is one word out of a two word structure.  */
+  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+    return false;
+
+  /* Allow only SUBREGs of non-eliminable hard registers.  */
+  return register_no_elim_operand (op, mode);
+}
+
 /* Extract the parts of an RTL expression that is a valid memory address
    for an instruction.  Return 0 if the structure of the address is
    grossly off.  Return -1 if the address contains ASHIFT, so it is not
@@ -11116,8 +11140,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
     base = addr;
   else if (GET_CODE (addr) == SUBREG)
     {
-      /* Allow only subregs of DImode hard regs.  */
-      if (register_no_elim_operand (SUBREG_REG (addr), DImode))
+      if (ix86_address_subreg_operand (SUBREG_REG (addr)))
        base = addr;
       else
        return 0;
@@ -11175,8 +11198,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
              break;
 
            case SUBREG:
-             /* Allow only subregs of DImode hard regs in PLUS chains.  */
-             if (!register_no_elim_operand (SUBREG_REG (op), DImode))
+             if (!ix86_address_subreg_operand (SUBREG_REG (op)))
                return 0;
              /* FALLTHRU */
 
@@ -11228,9 +11250,8 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
     {
       if (REG_P (index))
        ;
-      /* Allow only subregs of DImode hard regs.  */
       else if (GET_CODE (index) == SUBREG
-              && register_no_elim_operand (SUBREG_REG (index), DImode))
+              && ix86_address_subreg_operand (SUBREG_REG (index)))
        ;
       else
        return 0;
@@ -11677,10 +11698,7 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
       if (REG_P (base))
        reg = base;
       else if (GET_CODE (base) == SUBREG && REG_P (SUBREG_REG (base)))
-       {
-         reg = SUBREG_REG (base);
-         gcc_assert (register_no_elim_operand (reg, DImode));
-       }
+       reg = SUBREG_REG (base);
       else
        /* Base is not a register.  */
        return false;
@@ -11702,10 +11720,7 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
       if (REG_P (index))
        reg = index;
       else if (GET_CODE (index) == SUBREG && REG_P (SUBREG_REG (index)))
-       {
-         reg = SUBREG_REG (index);
-         gcc_assert (register_no_elim_operand (reg, DImode));
-       }
+       reg = SUBREG_REG (index);
       else
        /* Index is not a register.  */
        return false;
index b1a31221b78cdb268af1d73ace54c559a4335bef..7a5d30f47e98e9cbf76b913dcbdee1e2b56957fe 100644 (file)
@@ -1,3 +1,8 @@
+2011-08-01  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/49927
+       * gcc.target/i386/pr49927.c: New test.
+
 2011-08-01  Ira Rosen  <ira.rosen@linaro.org>
 
        PR tree-optimization/49926
diff --git a/gcc/testsuite/gcc.target/i386/pr49927.c b/gcc/testsuite/gcc.target/i386/pr49927.c
new file mode 100644 (file)
index 0000000..5850597
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+char a[1][1];
+long long b;
+
+void
+foo (void)
+{
+  --a[b][b];
+}