diff mbox

[i386] : Fix PR49920, unable to find a register to spill in class ‘DIREG’

Message ID CAFULd4YkQpURYgMEWy18G7NunUX_2DZHbCBEUq1-wqOb0t0gVg@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak July 31, 2011, 6:06 p.m. UTC
Hello!

The problem is similar to PR11001, where we should not expand to
special x86 stringop insn when one of necessary registers is marked
fixed.

In this particular PR, the problem was, that combine synthesized an
instruction that exactly matched stringop insn. However, special
registers were also marked fixed, so reload (obviously) didn't manage
to get one.

Attached patch disables stringop patterns when one of needed registers
is marked fixed and this way prevents combine to synthesize stringop
insn. Since nothing prevents combine to synthesize other stringop
patterns, the patch conditionally disables these as well.

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.

testsuite/ChangeLog:

2011-07-31  Uros Bizjak  <ubizjak@gmail.com>

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

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu
{,-m32}.  Patch was committed to mainline SVN and will be backported
to release branches.

Uros.
diff mbox

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 176960)
+++ config/i386/i386.md	(working copy)
@@ -15421,7 +15421,8 @@ 
    (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")
@@ -15436,7 +15437,7 @@ 
    (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")
@@ -15451,7 +15452,7 @@ 
    (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")
@@ -15466,7 +15467,7 @@ 
    (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")
@@ -15501,7 +15502,8 @@ 
    (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")
@@ -15520,7 +15522,7 @@ 
    (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")
@@ -15537,7 +15539,7 @@ 
    (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")
@@ -15580,7 +15582,9 @@ 
   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]));
@@ -15602,7 +15606,8 @@ 
    (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")
@@ -15614,7 +15619,7 @@ 
    (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")
@@ -15626,7 +15631,7 @@ 
    (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")
@@ -15638,7 +15643,7 @@ 
    (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")
@@ -15669,7 +15674,8 @@ 
 	(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")
@@ -15686,7 +15692,7 @@ 
 	(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")
@@ -15702,7 +15708,7 @@ 
 	(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")
@@ -15727,8 +15733,8 @@ 
   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];
@@ -15823,7 +15829,7 @@ 
    (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")
@@ -15863,7 +15869,7 @@ 
    (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")
@@ -15904,7 +15910,7 @@ 
 		   (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: testsuite/gcc.target/i386/pr49920.c
===================================================================
--- testsuite/gcc.target/i386/pr49920.c	(revision 0)
+++ testsuite/gcc.target/i386/pr49920.c	(revision 0)
@@ -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;
+}