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 target/17025


The problem here had nothing to do with regparm at all, really.

The actual problem is that we promoted a QImode operation to an
SImode operation, and in the process promoted the comparison to
SImode, which meant that we got the wrong answer for the following
"branch if sign bit set".

Fixed by being much more cautious about when we allow promotion
to SImode.  The CCmode plus the constant must together indicate
that we are only asking the question "zero or nonzero".

The given test case I couldn't convince to fail on mainline, only
with the 3.4 branch, but clearly the problem was still latent.



r~


        * config/i386/i386.md (testqi_1_maybe_si, andqi_2_maybe_si): New.
        (test_qi_1, andqi_2): Do not promote to simode.

Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.568
diff -c -p -d -r1.568 i386.md
*** gcc/config/i386/i386.md	9 Dec 2004 07:21:19 -0000	1.568
--- gcc/config/i386/i386.md	9 Dec 2004 17:30:58 -0000
***************
*** 7834,7851 ****
    ""
    "")
  
! (define_insn "*testqi_1"
    [(set (reg FLAGS_REG)
!         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
! 			 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
! 		 (const_int 0)))]
!   "ix86_match_ccmode (insn, CCNOmode)
!    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  {
    if (which_alternative == 3)
      {
!       if (GET_CODE (operands[1]) == CONST_INT
! 	  && (INTVAL (operands[1]) & 0xffffff00))
  	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
        return "test{l}\t{%1, %k0|%k0, %1}";
      }
--- 7834,7854 ----
    ""
    "")
  
! (define_insn "*testqi_1_maybe_si"
    [(set (reg FLAGS_REG)
!         (compare
! 	  (and:QI
! 	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
! 	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
! 	  (const_int 0)))]
!    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!     && ix86_match_ccmode (insn,
!  			 GET_CODE (operands[1]) == CONST_INT
!  			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
  {
    if (which_alternative == 3)
      {
!       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
  	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
        return "test{l}\t{%1, %k0|%k0, %1}";
      }
***************
*** 7856,7861 ****
--- 7859,7879 ----
     (set_attr "mode" "QI,QI,QI,SI")
     (set_attr "pent_pair" "uv,np,uv,np")])
  
+ (define_insn "*testqi_1"
+   [(set (reg FLAGS_REG)
+         (compare
+ 	  (and:QI
+ 	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
+ 	    (match_operand:QI 1 "general_operand" "n,n,qn"))
+ 	  (const_int 0)))]
+   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+    && ix86_match_ccmode (insn, CCNOmode)"
+   "test{b}\t{%1, %0|%0, %1}"
+   [(set_attr "type" "test")
+    (set_attr "modrm" "0,1,1")
+    (set_attr "mode" "QI")
+    (set_attr "pent_pair" "uv,np,uv")])
+ 
  (define_expand "testqi_ext_ccno_0"
    [(set (reg:CCNO FLAGS_REG)
  	(compare:CCNO
***************
*** 8343,8363 ****
    [(set_attr "type" "alu1")
     (set_attr "mode" "QI")])
  
! (define_insn "*andqi_2"
    [(set (reg FLAGS_REG)
  	(compare (and:QI
! 		   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
! 		   (match_operand:QI 2 "general_operand" "qim,qi,i"))
  		 (const_int 0)))
     (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
  	(and:QI (match_dup 1) (match_dup 2)))]
!   "ix86_match_ccmode (insn, CCNOmode)
!    && ix86_binary_operator_ok (AND, QImode, operands)"
  {
    if (which_alternative == 2)
      {
!       if (GET_CODE (operands[2]) == CONST_INT
!           && (INTVAL (operands[2]) & 0xffffff00))
          operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
        return "and{l}\t{%2, %k0|%k0, %2}";
      }
--- 8361,8382 ----
    [(set_attr "type" "alu1")
     (set_attr "mode" "QI")])
  
! (define_insn "*andqi_2_maybe_si"
    [(set (reg FLAGS_REG)
  	(compare (and:QI
! 		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
! 		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
  		 (const_int 0)))
     (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
  	(and:QI (match_dup 1) (match_dup 2)))]
!   "ix86_binary_operator_ok (AND, QImode, operands)
!    && ix86_match_ccmode (insn,
! 			 GET_CODE (operands[2]) == CONST_INT
! 			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
  {
    if (which_alternative == 2)
      {
!       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
          operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
        return "and{l}\t{%2, %k0|%k0, %2}";
      }
***************
*** 8366,8371 ****
--- 8385,8404 ----
    [(set_attr "type" "alu")
     (set_attr "mode" "QI,QI,SI")])
  
+ (define_insn "*andqi_2"
+   [(set (reg FLAGS_REG)
+ 	(compare (and:QI
+ 		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+ 		   (match_operand:QI 2 "general_operand" "qim,qi"))
+ 		 (const_int 0)))
+    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
+ 	(and:QI (match_dup 1) (match_dup 2)))]
+   "ix86_match_ccmode (insn, CCNOmode)
+    && ix86_binary_operator_ok (AND, QImode, operands)"
+   "and{b}\t{%2, %0|%0, %2}"
+   [(set_attr "type" "alu")
+    (set_attr "mode" "QI")])
+ 
  (define_insn "*andqi_2_slp"
    [(set (reg FLAGS_REG)
  	(compare (and:QI


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