This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] S/390: Avoid true-complementary bypass problem for reg-reg compares
- From: Joern Rennecke <amylaar at spamcop dot net>
- To: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 Feb 2009 12:26:22 -0500
- Subject: [Committed] S/390: Avoid true-complementary bypass problem for reg-reg compares
+ if (prev_insn != NULL_RTX && INSN_P (prev_insn)
+ && reg_referenced_p (*op1, PATTERN (prev_insn)))
+ s390_swap_cmp (cond, op0, op1, insn);
+
+ /* Check if there is a conflict with the next insn. If there
+ was no conflict with the previous insn, then swap the
+ COMPARE arguments and its mask. If we already swapped
+ the operands, or if swapping them would cause a conflict
+ with the previous insn, issue a NOP after the COMPARE in
+ order to separate the two instuctions. */
+ next_insn = NEXT_INSN (insn);
+ if (next_insn != NULL_RTX && INSN_P (next_insn)
+ && s390_non_addr_reg_read_p (*op1, next_insn))
+ {
+ if (prev_insn != NULL_RTX && INSN_P (prev_insn)
+ && s390_non_addr_reg_read_p (*op0, prev_insn))
It is curious that you do the first swap depending on reg_mentioned_p,
but the second one only depending on s390_non_addr_reg_read_p.
s390_non_addr_reg_read_p itself is strange because it will return
false for a store that stores a register to an address containing
that register.
Finally, it would seem that if both op0 and op1 potentially conflict
with prev_insn, you end up with a the original op0 now in op1 and
thus conflicting. (op0 and op1 would usually be different, and
they may be used as input to a binary operator in the other insn,
but I would assume they may even be identical unless you can prove
otherwise).
Likewise, if both op0 and op1 don't conflict with prev_insn, but
potentially conflict with next_insn, you can end up with the original
op0 in op1 and thus conflicting.