This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]