When then and else are reversed, we would swap new_val and old_val.
The same has to be done for our new code paths.
Also, emit_conditional_move may perform swapping.  In case we need to
swap, the cc comparison also needs to be swapped and for this we pass
the reversed cc comparison directly.  An alternative would be to pass
the constituents of the compare directly, but the functions have more
than enough parameters already.
---
 gcc/ifcvt.c  | 37 ++++++++++++++++++++++++++-----------
 gcc/optabs.c |  4 +++-
 gcc/optabs.h |  2 +-
 3 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 09bf443656c..d3959b870f6 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -777,7 +777,7 @@ static int noce_try_addcc (struct noce_if_info *);
 static int noce_try_store_flag_constants (struct noce_if_info *);
 static int noce_try_store_flag_mask (struct noce_if_info *);
 static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
-                           rtx, rtx, rtx, rtx = NULL);
+                           rtx, rtx, rtx, rtx = NULL, rtx = NULL);
 static int noce_try_cmove (struct noce_if_info *);
 static int noce_try_cmove_arith (struct noce_if_info *);
 static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
@@ -1660,7 +1660,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
 
 static rtx
 noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
-                rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue, rtx cc_cmp)
+                rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue, rtx cc_cmp,
+                rtx rev_cc_cmp)
 {
   rtx target ATTRIBUTE_UNUSED;
   int unsignedp ATTRIBUTE_UNUSED;
@@ -1708,7 +1709,7 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, 
enum rtx_code code,
 
   target = emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
                                  vtrue, vfalse, GET_MODE (x),
-                                 unsignedp, cc_cmp);
+                                 unsignedp, cc_cmp, rev_cc_cmp);
   if (target)
     return target;
 
@@ -3197,6 +3198,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
   rtx_code cond_code = GET_CODE (cond);
 
   rtx cc_cmp = noce_get_compare (jump, false);
+  rtx rev_cc_cmp = noce_get_compare (jump, if_info->then_else_reversed);
 
   /* The true targets for a conditional move.  */
   auto_vec<rtx> targets;
@@ -3313,7 +3315,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
       */
 
       rtx_insn *seq, *seq1 = 0, *seq2 = 0;
-      rtx temp_dest, temp_dest1, temp_dest2;
+      rtx temp_dest, temp_dest1 = NULL_RTX, temp_dest2 = NULL_RTX;
       unsigned int cost1 = 0, cost2 = 0;
       bool speed_p = if_info->speed_p;
       push_topmost_sequence ();
@@ -3324,7 +3326,13 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
          temp_dest1 = noce_emit_cmove (if_info, temp, cond_code,
              x, y, new_val, old_val, NULL_RTX);
        else
-         noce_emit_move_insn (target, new_val);
+         {
+           temp_dest1 = target;
+           if (if_info->then_else_reversed)
+             noce_emit_move_insn (target, old_val);
+           else
+             noce_emit_move_insn (target, new_val);
+         }
 
        /* If we failed to expand the conditional move, drop out and don't
           try to continue.  */
@@ -3352,9 +3360,15 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
        start_sequence ();
        if (!need_no_cmovs.get (insn))
          temp_dest2 = noce_emit_cmove (if_info, target, cond_code,
-             x, y, new_val, old_val, cc_cmp);
+             x, y, new_val, old_val, cc_cmp, rev_cc_cmp);
        else
-         noce_emit_move_insn (target, new_val);
+         {
+           temp_dest2 = target;
+           if (if_info->then_else_reversed)
+             noce_emit_move_insn (target, old_val);
+           else
+             noce_emit_move_insn (target, new_val);
+         }
 
        /* If we failed to expand the conditional move, drop out and don't
           try to continue.  */
@@ -3386,7 +3400,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
          /* We do not require a temp register, so remove it from the list.  */
          seq = seq2;
          temp_dest = temp_dest2;
-         temps_created.remove (temp);
+         if (temps_created.get (temp))
+           temps_created.remove (temp);
        }
       else
        {
@@ -3436,7 +3451,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
   /* Mark all our temporaries and targets as used.  */
   for (int i = 0; i < count; i++)
     {
-      set_used_flags (temporaries[i]);
+      if (temps_created.get(targets[i]))
+       set_used_flags (temporaries[i]);
       set_used_flags (targets[i]);
     }
 
@@ -3941,7 +3957,7 @@ check_need_temps (basic_block bb, hash_map<rtx, bool> 
*need_temp, rtx cond)
 
   FOR_BB_INSNS (bb, insn)
     {
-      rtx set, src, dest;
+      rtx set, dest;
 
       if (!active_insn_p (insn))
        continue;
@@ -3950,7 +3966,6 @@ check_need_temps (basic_block bb, hash_map<rtx, bool> 
*need_temp, rtx cond)
       if (set == NULL_RTX)
        continue;
 
-      src = SET_SRC (set);
       dest = SET_DEST (set);
 
       /* noce_emit_cmove will emit the condition check every time it is called
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 3ce6f8cdd30..b1d88fd58b4 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4325,7 +4325,8 @@ emit_indirect_jump (rtx loc)
 rtx
 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
                       machine_mode cmode, rtx op2, rtx op3,
-                      machine_mode mode, int unsignedp, rtx cc_cmp)
+                      machine_mode mode, int unsignedp, rtx cc_cmp,
+                      rtx rev_cc_cmp)
 {
   rtx comparison;
   rtx_insn *last;
@@ -4372,6 +4373,7 @@ emit_conditional_move (rtx target, enum rtx_code code, 
rtx op0, rtx op1,
       std::swap (op2, op3);
       code = reversed;
       swapped = true;
+      cc_cmp = rev_cc_cmp;
     }
 
   if (mode == VOIDmode)
diff --git a/gcc/optabs.h b/gcc/optabs.h
index c4540f87144..17b4e71ffd4 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -258,7 +258,7 @@ extern void emit_indirect_jump (rtx);
 
 /* Emit a conditional move operation.  */
 rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, machine_mode,
-                          rtx, rtx, machine_mode, int, rtx = NULL);
+                          rtx, rtx, machine_mode, int, rtx = NULL, rtx = NULL);
 
 /* Emit a conditional negate or bitwise complement operation.  */
 rtx emit_conditional_neg_or_complement (rtx, rtx_code, machine_mode, rtx,
-- 
2.17.0

Reply via email to