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]

Re: A patch for a bad combine bug



  In message <m0ykbCQ-00026AC@ocean.lucon.org>you write:
  > The bug is introduced by
  > 
  > Wed Mar 18 05:54:25 1998  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
  > 
  > 	* combine.c (simplify_comparison, case AND): Commute AND and
  > 	SUBREG.
  > 
  > I am not sure if my patch is correct. But Kenner's change is wrong.
Agreed.  It isn't safe to commute AND into a paradoxical subreg if
WORD_REGISTER_OPERATIONS is not defined.

Consider

(and:SI (subreg:SI (reg:QI) 0) (const_int 127)

This states quite clearly that only the low 7 bits can possibly have nonzero
values after evaluation of this expression.

However, the current combiner can turn that into

(subreg:SI (and:QI (reg:QI 24) (const_int 127)) 0)

Which allows the upper 24 bits to have undetermined values after evaluation.

I'll check in this fix to egcs asap if nobody beat me to this bug over
the weekend:

	* combine.c (simplify_comparison, case AND): Do not commute
	AND into a paradoxical SUBREG if WORD_REGISTER_OPERATIONS is
	not defined.

*** combine.c.ORIG	Fri Jul  3 21:49:34 1998
--- combine.c	Fri Jul  3 21:49:44 1998
*************** simplify_comparison (code, pop0, pop1)
*** 10154,10159 ****
--- 10154,10169 ----
  		  || subreg_lowpart_p (XEXP (op0, 0))
  #endif
  		  )
+ #ifndef WORD_REGISTER_OPERATIONS
+ 	      /* It is unsafe to commute the AND into the SUBREG if the SUBREG
+ 		 is paradoxical and WORD_REGISTER_OPERATIONS is not defined.
+ 		 As originally written the upper bits have a defined value
+ 		 due to the AND operation.  However, if we commute the AND
+ 		 inside the SUBREG then they no longer have defined values
+ 		 and the meaning of the code has been changed.  */
+ 	      && (GET_MODE_SIZE (GET_MODE (XEXP (op0, 0)))
+ 		  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))
+ #endif
  	      && GET_CODE (XEXP (op0, 1)) == CONST_INT
  	      && mode_width <= HOST_BITS_PER_WIDE_INT
  	      && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))

jeff


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