This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix compile/20030224-1.c



Whee, this is so much fun.  This was a bug originally only triggered by
the gimplification processs, but after some hackery I've managed to 
construct a testcase which fails with the mainline sources
(compile/20030224-1.c).

The key concept here is that %eax is unusable as a reload register as it
is live throughout the entire function (due to the calls with VLAs as
arguments).  Once you've got that it's simply a matter of arranging for
the right set of conditions to get an insn like this:

(insn 50 48 51 2 0x401937c0 (set (reg:CCNO 17 flags)
        (compare:CCNO (and:SI (reg/v:SI 63 [ z ])
                (const_int 3 [0x3]))
            (const_int 0 [0x0]))) 293 {testsi_1} (nil)
    (expr_list:REG_DEAD (reg/v:SI 63 [ z ])
        (nil)))


Where (reg 63) does not get a hard register, but is known to be equivalent to
a constant.


That insn matches this pattern:

(define_insn "testsi_1"
  [(set (reg 17)
        (compare
          (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
                  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
          (const_int 0)))]
  "ix86_match_ccmode (insn, CCNOmode)"
  "test{l}\t{%1, %0|%0, %1}"
  [(set_attr "type" "test")
   (set_attr "modrm" "0,1,1")
   (set_attr "mode" "SI")
   (set_attr "pent_pair" "uv,np,uv")])


Reload selects the first alternative as its goal.  Meaning that it's stuck
trying to reload something into eax, but eax is never going to be available
as a reload reg (again, because it's live throughout the function).  Boom.

We certainly want to continue to have a separate alternative with eax as
the first argument.  However, the primary purpose of that alternative is
to allow us to set modrm and pent_pair more accurately.  ie, that
alternative should not affect register preferencing and it should not
be exposed as a target for the register reloader.  ie, instead of
using just '*' to hide the alternative from register preferencing, the
constraints should be using !*. 

I fixed the various test patterns which obviously had this set of
problems.  However, there are other patterns in i386.md which may 
also be susceptible to similar failures.  Search for "*a".  Hopefully
someone with more intimate knowledge of the ia32 backend can comment
on whether or not similar changes are needed for those patterns.

Bootstrapped and regression tested.  No regressions, and it of course fixes
the testcase for this bug (compile/20030224-1.c -O1).

	* i386.md (testdi_1_rex64): Discourage reload from using the %eax
	alternative.
	(testsi_1, testhi_1, testqi_1): Likewise.

Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.443
diff -c -3 -p -r1.443 i386.md
*** config/i386/i386.md	23 Feb 2003 06:10:02 -0000	1.443
--- config/i386/i386.md	24 Feb 2003 18:43:25 -0000
***************
*** 8043,8049 ****
  (define_insn "*testdi_1_rex64"
    [(set (reg 17)
  	(compare
! 	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
  		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
  	  (const_int 0)))]
    "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
--- 8043,8049 ----
  (define_insn "*testdi_1_rex64"
    [(set (reg 17)
  	(compare
! 	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
  		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
  	  (const_int 0)))]
    "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
***************
*** 8061,8067 ****
  (define_insn "testsi_1"
    [(set (reg 17)
  	(compare
! 	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
  		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
  	  (const_int 0)))]
    "ix86_match_ccmode (insn, CCNOmode)"
--- 8061,8067 ----
  (define_insn "testsi_1"
    [(set (reg 17)
  	(compare
! 	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
  		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
  	  (const_int 0)))]
    "ix86_match_ccmode (insn, CCNOmode)"
***************
*** 8082,8088 ****
  
  (define_insn "*testhi_1"
    [(set (reg 17)
!         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
  			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
  		 (const_int 0)))]
    "ix86_match_ccmode (insn, CCNOmode)"
--- 8082,8088 ----
  
  (define_insn "*testhi_1"
    [(set (reg 17)
!         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
  			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
  		 (const_int 0)))]
    "ix86_match_ccmode (insn, CCNOmode)"
***************
*** 8102,8108 ****
  
  (define_insn "*testqi_1"
    [(set (reg 17)
!         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
  			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
  		 (const_int 0)))]
    "ix86_match_ccmode (insn, CCNOmode)"
--- 8102,8108 ----
  
  (define_insn "*testqi_1"
    [(set (reg 17)
!         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
  			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
  		 (const_int 0)))]
    "ix86_match_ccmode (insn, CCNOmode)"




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]