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: ia32: cmov bug fix


On Mon, Aug 09, 1999 at 04:57:58PM -0700, Richard Henderson wrote:
> 	* jump.c (jump_optimize_1): Copy cmov expression B to a register
> 	before emit_conditional_move.

I just committed a variant of this.  The change is to avoid creating
a new register in the case B is already in a register.

The quoted changelog above is also misleading, since the patch also
introduced the ability to do the cmov on non-simple sets.  Somehow
I thought that was already in mainline...


r~


        * jump.c (jump_optimize_1): Do cmov opt on any single-set; force
        B into a register before emit_conditional_move.

Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.70
diff -c -p -d -r1.70 jump.c
*** jump.c	1999/08/24 08:44:47	1.70
--- jump.c	1999/08/24 23:57:11
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 874,885 ****
  
  	     INSN here is the jump around the store.  We set:
  
! 	     TEMP to the "x = b;" insn.
  	     TEMP1 to X.
  	     TEMP2 to B.
  	     TEMP3 to A (X in the second case).
  	     TEMP4 to the condition being tested.
! 	     TEMP5 to the earliest insn used to find the condition.  */
  
  	  if (/* We can't do this after reload has completed.  */
  	      ! reload_completed
--- 874,886 ----
  
  	     INSN here is the jump around the store.  We set:
  
! 	     TEMP to the "x op= b;" insn.
  	     TEMP1 to X.
  	     TEMP2 to B.
  	     TEMP3 to A (X in the second case).
  	     TEMP4 to the condition being tested.
! 	     TEMP5 to the earliest insn used to find the condition.
! 	     TEMP6 to the SET of TEMP.  */
  
  	  if (/* We can't do this after reload has completed.  */
  	      ! reload_completed
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 887,897 ****
  	      /* Set TEMP to the "x = b;" insn.  */
  	      && (temp = next_nonnote_insn (insn)) != 0
  	      && GET_CODE (temp) == INSN
! 	      && GET_CODE (PATTERN (temp)) == SET
! 	      && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG
  	      && (! SMALL_REGISTER_CLASSES
  		  || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)
! 	      && ! side_effects_p (temp2 = SET_SRC (PATTERN (temp)))
  	      && ! may_trap_p (temp2)
  	      /* Allow either form, but prefer the former if both apply. 
  		 There is no point in using the old value of TEMP1 if
--- 888,898 ----
  	      /* Set TEMP to the "x = b;" insn.  */
  	      && (temp = next_nonnote_insn (insn)) != 0
  	      && GET_CODE (temp) == INSN
! 	      && (temp6 = single_set (temp)) != NULL_RTX
! 	      && GET_CODE (temp1 = SET_DEST (temp6)) == REG
  	      && (! SMALL_REGISTER_CLASSES
  		  || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)
! 	      && ! side_effects_p (temp2 = SET_SRC (temp6))
  	      && ! may_trap_p (temp2)
  	      /* Allow either form, but prefer the former if both apply. 
  		 There is no point in using the old value of TEMP1 if
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 936,942 ****
  		enum rtx_code code = GET_CODE (temp4);
  		rtx var = temp1;
  		rtx cond0, cond1, aval, bval;
! 		rtx target;
  
  		/* Copy the compared variables into cond0 and cond1, so that
  		   any side effects performed in or after the old comparison,
--- 937,943 ----
  		enum rtx_code code = GET_CODE (temp4);
  		rtx var = temp1;
  		rtx cond0, cond1, aval, bval;
! 		rtx target, new_insn;
  
  		/* Copy the compared variables into cond0 and cond1, so that
  		   any side effects performed in or after the old comparison,
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 955,964 ****
  		else
  		  cond1 = gen_reg_rtx (GET_MODE (XEXP (temp4, 1)));
  
  		aval = temp3;
- 		bval = temp2;
  
  		start_sequence ();
  		target = emit_conditional_move (var, code,
  						cond0, cond1, VOIDmode,
  						aval, bval, GET_MODE (var),
--- 956,983 ----
  		else
  		  cond1 = gen_reg_rtx (GET_MODE (XEXP (temp4, 1)));
  
+ 		/* Careful about copying these values -- an IOR or what may
+ 		   need to do other things, like clobber flags.  */
+ 		/* ??? Assume for the moment that AVAL is ok.  */
  		aval = temp3;
  
  		start_sequence ();
+ 
+ 		/* If we're not dealing with a register or the insn is more
+ 		   complex than a simple SET, duplicate the computation and
+ 		   replace the destination with a new temporary.  */
+ 		if (register_operand (temp2, GET_MODE (var))
+ 		    && GET_CODE (PATTERN (temp)) == SET)
+ 		  bval = temp2;
+ 		else
+ 		  {
+ 		    bval = gen_reg_rtx (GET_MODE (var));
+ 		    new_insn = copy_rtx (temp);
+ 		    temp6 = single_set (new_insn);
+ 		    SET_DEST (temp6) = bval;
+ 		    emit_insn (PATTERN (new_insn));
+ 		  }
+ 		  
  		target = emit_conditional_move (var, code,
  						cond0, cond1, VOIDmode,
  						aval, bval, GET_MODE (var),


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