Robin Dapp <[email protected]> writes:
> 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.
The changes to emit_conditional_move shouldn't be needed if we pass
the condition directly to a new overload, as per the 6/9 comments.
Let me know if that's not true.
> ---
> 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
> @@ -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
It looks like these changes are really fixes for previous patches in the
series. It'd be clearer to fold them into the relevant previous patch
if possible.
Thanks,
Richard