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]

i386 fix



Hi
This testcase was reported by Andre Weilert some time ago.  It gets
misscompiled on i386.

unsigned int buggy (unsigned int *param) {
    unsigned int accu, zero=0, borrow;
    accu    = - *param;
    borrow  = - (accu > zero);
    *param += accu;
    return borrow;
}
int main (int i, char **c) {
    unsigned int param = 1;
    if (1 + buggy( &param ))
      abort();
    return 0;
}

The problem is condition (accu > zero).  Combine translates it into
x <= 0 unsigned.  This noncanonical form gets wrong CCmode (CCNOmode)
and gets combined with CCNOmode neg pattern. NEG instruction (according
to Zack comments) don't set carry flag and resulting code don't work.

There are 3 failures in this process.  First is the noncanonical form, second
is the wrong mode and third is the NEG pattern.  NEG pattern contains also
CCmode version, that is obviously wrong, so I've removed it.  SELECT_CC_MODE
ought IMO to work for noncanonical forms safely too, so I've added missing
codes and finally combine outght to canonize the expression.

I've tracked down the combine problem too, but I don't think it is possible
to fix it easilly.  The problem is with rtl code like this:

(insn 55 18 56 (set (reg:SI 36)
        (const_int 0 [0x0])) 37 {*movsi_1} (nil)
    (expr_list:REG_EQUAL (const_int 0 [0x0])
        (nil)))

(insn 56 55 57 (set (reg:CC 17 flags)
        (compare:CC (reg/v:SI 27)
            (const_int 0 [0x0]))) 5 {cmpsi_1} (nil)
    (nil))

(insn 57 56 58 (set (strict_low_part (subreg:QI (reg:SI 36) 0))
        (leu:QI (reg:CC 17 flags)
            (const_int 0 [0x0]))) 421 {*setcc_2} (nil)
    (nil))

Sadly, combine is smart enought to always remove strict_low_part from
the set in insn 57, since it knows that all the values are zero.
Trivial pattern like this is always synthetized (even when combining only
the insn 56 and 57)

(set (reg:SI 36)
    (eq:SI (reg/v:SI 27)
        (const_int 0 [0x0])))

and this pattern can't be easilly split into matching insns (always
require 3 insns), so the canonized versions of condition never match.

*** i386.h.old	Sat Mar 25 20:58:14 2000
--- i386.h	Sun Mar 26 14:32:04 2000
*************** while (0)
*** 2176,2185 ****
     For integer comparisons against zero, reduce to CCNOmode if
     possible, to allow for more combinations.  */
  
! #define SELECT_CC_MODE(OP,X,Y)				\
!   (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT		\
!    ? (OP) == EQ || (OP) == NE ? CCFPUmode : CCFPmode	\
!    : (OP) == LE || (OP) == GT ? CCmode			\
     : (Y) != const0_rtx ? CCmode				\
     : CCNOmode)
  
--- 2181,2191 ----
     For integer comparisons against zero, reduce to CCNOmode if
     possible, to allow for more combinations.  */
  
! #define SELECT_CC_MODE(OP,X,Y)					\
!   (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT			\
!    ? (OP) == EQ || (OP) == NE ? CCFPUmode : CCFPmode		\
!    : (OP) != EQ && (OP) != NE && (OP) != LT && (OP) != GE	\
!    ? CCmode							\
     : (Y) != const0_rtx ? CCmode				\
     : CCNOmode)
  
*** i386.md.old	Sun Mar 26 12:09:47 2000
--- i386.md	Sun Mar 26 12:16:46 2000
***************
*** 4963,4977 ****
    "neg{l}\\t%0"
    [(set_attr "type" "negnot")])
  
! (define_insn "*negsi2_cmp"
!   [(set (reg:CC 17)
! 	(compare:CC (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
! 		 (const_int 0)))
!    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
! 	(neg:SI (match_dup 1)))]
!   "ix86_unary_operator_ok (NEG, SImode, operands)"
!   "neg{l}\\t%0"
!   [(set_attr "type" "negnot")])
  
  (define_expand "neghi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
--- 4963,4970 ----
    "neg{l}\\t%0"
    [(set_attr "type" "negnot")])
  
! ;; Neg instruction don't set carry flag correctly, so we can't include
! ;; CCmode pattern.
  
  (define_expand "neghi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")

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