From 1f081ffb7d73ee48914f604cc0cc38d9f4521701 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@cygnus.com>
Date: Tue, 24 Aug 1999 17:00:03 -0700
Subject: [PATCH] jump.c (jump_optimize_1): Do cmov opt on any single-set;
 force B into a register before emit_conditional_move.

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

From-SVN: r28830
---
 gcc/ChangeLog |  5 +++++
 gcc/jump.c    | 33 ++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b6817cfb5017..4920ebe8f874 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Tue Aug 24 16:58:15 1999  Richard Henderson  <rth@cygnus.com>
+
+	* jump.c (jump_optimize_1): Do cmov opt on any single-set; force
+	B into a register before emit_conditional_move.
+
 Tue Aug 24 15:37:03 1999  Richard Henderson  <rth@cygnus.com>
 
 	* fold-const.c (fold): Reassociate (+ (+ (* a b) c) (* d e))
diff --git a/gcc/jump.c b/gcc/jump.c
index e60286d332ac..9a9e9b252bf2 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -874,12 +874,13 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
 
 	     INSN here is the jump around the store.  We set:
 
-	     TEMP to the "x = b;" insn.
+	     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.  */
+	     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
@@ -887,11 +888,11 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
 	      /* 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
+	      && (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 (PATTERN (temp)))
+	      && ! 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
@@ -936,7 +937,7 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
 		enum rtx_code code = GET_CODE (temp4);
 		rtx var = temp1;
 		rtx cond0, cond1, aval, bval;
-		rtx target;
+		rtx target, new_insn;
 
 		/* Copy the compared variables into cond0 and cond1, so that
 		   any side effects performed in or after the old comparison,
@@ -955,10 +956,28 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
 		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;
-		bval = temp2;
 
 		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),
-- 
GitLab