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]

[RFA:] combine.c: Fold comparison in original mode. Fix for execute/960608-1.c and execute/20001009-1.c


I think I have the right fix for execute/960608-1.c and
execute/20001009-1.c which are giving failures on both
i686-pc-linux-gnu and cris-axis-none (or cris-axis-elf if you're
confused by "none") and it seems also a few other targets.

For CRIS and 960608-1.c, I get this coming in to try_combine:

  (insn 28 27 32 (set (reg:QI 34)
  	  (const_int -50 [0xffffffce])) 41 {movqi} (nil)
      (nil))
    
  (insn/i 36 32 37 (set (cc0)
  	  (compare (reg:QI 34)
  	      (const_int 206 [0xce]))) 11 {cmpqi} (insn_list 28 (nil))
      (expr_list:REG_DEAD (reg:QI 34)
  	  (nil)))
    
  (insn/i 37 36 43 (set (reg:SI 39)
  	  (ne:SI (cc0)
  	      (const_int 0 [0x0]))) 180 {sne} (nil)
      (nil))
    

This gets combined to:

  (set (reg:SI 39)
      (ne:SI (const_int -50 [0xffffffce])
  	  (const_int 206 [0xce])))

and folded as:

  (insn/i 37 36 43 (set (reg:SI 39)
  	  (const_int 1 [0x1])) 32 {movsi} (nil)
      (nil))

This happens when (const_int -50) is substituted into (reg:QI
34) because the comparison-folding is not done in QImode, but
instead in VOIDmode, i.e. "infinite precision", where -50 !=
206.  In QImode, the values are equal.  The mode of the
substituted operand is provided in op0_mode for what seems like
exactly the purpose of folding in the right mode.

I don't know if the incoming value 206 above should in fact have
been sign-extended, but I can't find an explicit assertion that
such an assumption can be done about bits outside the used type,
so I believe nothing should be assumed, and the incoming values
are ok.

Bootstrapped on i686-pc-linux-gnu with no new regressions, and
fixing the two failures (or seven, depending on how you count)
in execute/960608-1.c and execute/20001009-1.c.

Ok to commit?

	* combine.c (combine_simplify_rtx) <expression folding>: Do any
	simplification in op0_mode for a comparison of two constants.

Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.164
diff -c -p -c -p -5 -r1.164 combine.c
*** combine.c	2000/11/07 22:49:51	1.164
--- combine.c	2000/11/22 22:10:18
*************** combine_simplify_rtx (x, op0_mode, last,
*** 3636,3645 ****
--- 3636,3654 ----
      case '<':
        {
  	enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
  	if (cmp_mode == VOIDmode)
  	  cmp_mode = GET_MODE (XEXP (x, 1));
+ 
+ 	/* Both operands can now be constants.  This happens when
+ 	   substituting a constant into a register, when the other
+ 	   operand is a constant.  We must then use the original mode
+ 	   for operand 0 when simplifying the comparison, as the
+ 	   constants cannot be assumed to both be zero- or sign-extended
+ 	   outside that mode.  */
+ 	if (cmp_mode == VOIDmode)
+ 	  cmp_mode = op0_mode;
  	temp = simplify_relational_operation (code, cmp_mode,
  					      XEXP (x, 0), XEXP (x, 1));
        }
  #ifdef FLOAT_STORE_FLAG_VALUE
        if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)

brgds, H-P

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