This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: ia32: cmov bug fix
- To: gcc-patches at gcc dot gnu dot org
- Subject: Re: ia32: cmov bug fix
- From: Richard Henderson <rth at cygnus dot com>
- Date: Tue, 24 Aug 1999 17:02:20 -0700
- References: <19990809165758.C7579@cygnus.com>
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),