re PR target/49920 (unable to find a register to spill in class ‘DIREG’)
authorUros Bizjak <uros@gcc.gnu.org>
Sun, 31 Jul 2011 17:50:08 +0000 (19:50 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sun, 31 Jul 2011 17:50:08 +0000 (19:50 +0200)
PR target/49920
* config/i386/i386.md (strset): Do not expand strset_singleop
when %eax or $edi are fixed.
(*strsetdi_rex_1): Disable when %eax or %edi are fixed.
(*strsetsi_1): Ditto.
(*strsethi_1): Ditto.
(*strsetqi_1): Ditto.
(*rep_stosdi_rex64): Disable when %eax, %ecx or %edi are fixed.
(*rep_stossi): Ditto.
(*rep_stosqi): 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.
(*strmovqi_1): Ditto.
(*rep_movdi_rex64): Disable when %ecx, %esi or %edi are fixed.
(*rep_movsi): Ditto.
(*rep_movqi): Ditto.

testsuite/ChangeLog:

PR target/49920
* gcc.target/i386/pr49920.c: New test.

From-SVN: r176979

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

index b637de28a07b5c25227e082123bcc34e6dff078b..e092d00873d45e2f70c4a4070669c449f60843a3 100644 (file)
@@ -1,3 +1,27 @@
+2011-07-31  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/49920
+       * config/i386/i386.md (strset): Do not expand strset_singleop
+       when %eax or $edi are fixed.
+       (*strsetdi_rex_1): Disable when %eax or %edi are fixed.
+       (*strsetsi_1): Ditto.
+       (*strsethi_1): Ditto.
+       (*strsetqi_1): Ditto.
+       (*rep_stosdi_rex64): Disable when %eax, %ecx or %edi are fixed.
+       (*rep_stossi): Ditto.
+       (*rep_stosqi): 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.
+       (*strmovqi_1): Ditto.
+       (*rep_movdi_rex64): Disable when %ecx, %esi or %edi are fixed.
+       (*rep_movsi): Ditto.
+       (*rep_movqi): Ditto.
+
 2011-07-31  Mikael Pettersson  <mikpe@it.uu.se>
 
        PR target/47908
@@ -40,8 +64,7 @@
        Use scaninvent instead of /proc/cpuinfo if __sgi__.
        * config.host: Also use driver-native.o, mips/x-native on
        mips-sgi-irix*.
-       * config/mips/iris6.h [__mips__] (host_detect_local_cpu):
-       Declare.
+       * config/mips/iris6.h [__mips__] (host_detect_local_cpu): Declare.
        (EXTRA_SPEC_FUNCTIONS, MARCH_MTUNE_NATIVE_SPECS): Define.
        (DRIVER_SELF_SPECS): Add MARCH_MTUNE_NATIVE_SPECS.
 
index 2210bc819d9e0b4b84536fe930d4a9c911aa6587..5dfa43ee427e6fc93f349f0023fd8c492a1cf7d3 100644 (file)
    (set (match_operand:DI 1 "register_operand" "=S")
        (plus:DI (match_dup 3)
                 (const_int 8)))]
-  "TARGET_64BIT"
+  "TARGET_64BIT
+   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "movsq"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
    (set (match_operand:P 1 "register_operand" "=S")
        (plus:P (match_dup 3)
                (const_int 4)))]
-  ""
+  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "movs{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
    (set (match_operand:P 1 "register_operand" "=S")
        (plus:P (match_dup 3)
                (const_int 2)))]
-  ""
+  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "movsw"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
    (set (match_operand:P 1 "register_operand" "=S")
        (plus:P (match_dup 3)
                (const_int 1)))]
-  ""
+  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "movsb"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
    (set (mem:BLK (match_dup 3))
        (mem:BLK (match_dup 4)))
    (use (match_dup 5))]
-  "TARGET_64BIT"
+  "TARGET_64BIT
+   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "rep{%;} movsq"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set (mem:BLK (match_dup 3))
        (mem:BLK (match_dup 4)))
    (use (match_dup 5))]
-  ""
+  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "rep{%;} movs{l|d}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set (mem:BLK (match_dup 3))
        (mem:BLK (match_dup 4)))
    (use (match_dup 5))]
-  ""
+  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "rep{%;} movsb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
                              GEN_INT (GET_MODE_SIZE (GET_MODE
                                                      (operands[2]))));
-  if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
+  /* Can't use this if the user has appropriated eax or edi.  */
+  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
+      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
     {
       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
                                      operands[3]));
    (set (match_operand:DI 0 "register_operand" "=D")
        (plus:DI (match_dup 1)
                 (const_int 8)))]
-  "TARGET_64BIT"
+  "TARGET_64BIT
+   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
   "stosq"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set (match_operand:P 0 "register_operand" "=D")
        (plus:P (match_dup 1)
                (const_int 4)))]
-  ""
+  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
   "stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set (match_operand:P 0 "register_operand" "=D")
        (plus:P (match_dup 1)
                (const_int 2)))]
-  ""
+  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
   "stosw"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set (match_operand:P 0 "register_operand" "=D")
        (plus:P (match_dup 1)
                (const_int 1)))]
-  ""
+  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
   "stosb"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
        (const_int 0))
    (use (match_operand:DI 2 "register_operand" "a"))
    (use (match_dup 4))]
-  "TARGET_64BIT"
+  "TARGET_64BIT
+   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
   "rep{%;} stosq"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
        (const_int 0))
    (use (match_operand:SI 2 "register_operand" "a"))
    (use (match_dup 4))]
-  ""
+  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
   "rep{%;} stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
        (const_int 0))
    (use (match_operand:QI 2 "register_operand" "a"))
    (use (match_dup 4))]
-  ""
+  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
   "rep{%;} stosb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
     FAIL;
 
-  /* Can't use this if the user has appropriated esi or edi.  */
-  if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
+  /* Can't use this if the user has appropriated ecx, esi or edi.  */
+  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
     FAIL;
 
   out = operands[0];
    (clobber (match_operand:P 0 "register_operand" "=S"))
    (clobber (match_operand:P 1 "register_operand" "=D"))
    (clobber (match_operand:P 2 "register_operand" "=c"))]
-  ""
+  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "repz{%;} cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
    (clobber (match_operand:P 0 "register_operand" "=S"))
    (clobber (match_operand:P 1 "register_operand" "=D"))
    (clobber (match_operand:P 2 "register_operand" "=c"))]
-  ""
+  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
   "repz{%;} cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
                   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
    (clobber (match_operand:P 1 "register_operand" "=D"))
    (clobber (reg:CC FLAGS_REG))]
-  ""
+  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
   "repnz{%;} scasb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
index 3a78ad1454f7113817fcf4be56ab5bbdefd013c2..e6beacd7f2510ffd1a48814844be0e925f4d1df8 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-31  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/49920
+       * gcc.target/i386/pr49920.c: New test.
+
 2011-07-31  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.dg/tree-ssa/20050314-1.c: Dump and cleanup lim1 pass only.
diff --git a/gcc/testsuite/gcc.target/i386/pr49920.c b/gcc/testsuite/gcc.target/i386/pr49920.c
new file mode 100644 (file)
index 0000000..ef2a185
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target ia32 } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void *malloc (size_t);
+
+register unsigned int MR_mr0 asm ("esi");
+register unsigned int MR_mr1 asm ("edi");
+
+void ml_backend__ml_closure_gen_module11 (void)
+{
+  unsigned int MR_tempr1, MR_tempr2, MR_tempr3;
+
+  MR_tempr1 = (unsigned int)((char *) malloc (sizeof (unsigned int)) + 4);
+  MR_tempr3 = ((unsigned int *) MR_mr0)[0];
+
+  ((unsigned int *) (MR_tempr1 - 4))[0] = MR_tempr3;
+
+  MR_tempr2 = (unsigned int)((char *) malloc (2 * sizeof (unsigned int)));
+
+  ((unsigned int *) MR_tempr2)[1] = MR_tempr1;
+}