[SystemZ] Improve optimizeCompareZero()
More conversions to load-and-test can be made with this patch by adding a
forward search in optimizeCompareZero().
Review: Ulrich Weigand
https://reviews.llvm.org/D38076
llvm-svn: 313877
diff --git a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
index d70f9e9..5f75b13 100644
--- a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
@@ -110,12 +110,8 @@
return false;
}
-// Return true if any CC result of MI would reflect the value of Reg.
-static bool resultTests(MachineInstr &MI, unsigned Reg) {
- if (MI.getNumOperands() > 0 && MI.getOperand(0).isReg() &&
- MI.getOperand(0).isDef() && MI.getOperand(0).getReg() == Reg)
- return true;
-
+// Returns true if MI is an instruction whose output equals the value in Reg.
+static bool preservesValueOf(MachineInstr &MI, unsigned Reg) {
switch (MI.getOpcode()) {
case SystemZ::LR:
case SystemZ::LGR:
@@ -136,6 +132,16 @@
return false;
}
+// Return true if any CC result of MI would (perhaps after conversion)
+// reflect the value of Reg.
+static bool resultTests(MachineInstr &MI, unsigned Reg) {
+ if (MI.getNumOperands() > 0 && MI.getOperand(0).isReg() &&
+ MI.getOperand(0).isDef() && MI.getOperand(0).getReg() == Reg)
+ return true;
+
+ return (preservesValueOf(MI, Reg));
+}
+
// Describe the references to Reg or any of its aliases in MI.
Reference SystemZElimCompare::getRegReferences(MachineInstr &MI, unsigned Reg) {
Reference Ref;
@@ -421,11 +427,34 @@
}
SrcRefs |= getRegReferences(MI, SrcReg);
if (SrcRefs.Def)
- return false;
+ break;
CCRefs |= getRegReferences(MI, SystemZ::CC);
if (CCRefs.Use && CCRefs.Def)
+ break;
+ }
+
+ // Also do a forward search to handle cases where an instruction after the
+ // compare can be converted like
+ //
+ // LTEBRCompare %F0S, %F0S, %CC<imp-def> LTEBRCompare %F0S, %F0S, %CC<imp-def>
+ // %F2S<def> = LER %F0S
+ //
+ MBBI = Compare, MBBE = MBB.end();
+ while (++MBBI != MBBE) {
+ MachineInstr &MI = *MBBI;
+ if (preservesValueOf(MI, SrcReg)) {
+ // Try to eliminate Compare by reusing a CC result from MI.
+ if (convertToLoadAndTest(MI)) {
+ EliminatedComparisons += 1;
+ return true;
+ }
+ }
+ if (getRegReferences(MI, SrcReg).Def)
+ return false;
+ if (getRegReferences(MI, SystemZ::CC))
return false;
}
+
return false;
}