@@ -150,6 +150,30 @@ Reference SystemZElimCompare::getRegReferences(MachineInstr &MI, unsigned Reg) {
150150 return Ref;
151151}
152152
153+ // Return true if this is a load and test which can be optimized the
154+ // same way as compare instruction.
155+ static bool isLoadAndTestAsCmp (MachineInstr &MI) {
156+ // If we during isel used a load-and-test as a compare with 0, the
157+ // def operand is dead.
158+ return (MI.getOpcode () == SystemZ::LTEBR ||
159+ MI.getOpcode () == SystemZ::LTDBR ||
160+ MI.getOpcode () == SystemZ::LTXBR) &&
161+ MI.getOperand (0 ).isDead ();
162+ }
163+
164+ // Return the source register of Compare, which is the unknown value
165+ // being tested.
166+ static unsigned getCompareSourceReg (MachineInstr &Compare) {
167+ unsigned reg = 0 ;
168+ if (Compare.isCompare ())
169+ reg = Compare.getOperand (0 ).getReg ();
170+ else if (isLoadAndTestAsCmp (Compare))
171+ reg = Compare.getOperand (1 ).getReg ();
172+ assert (reg);
173+
174+ return reg;
175+ }
176+
153177// Compare compares the result of MI against zero. If MI is an addition
154178// of -1 and if CCUsers is a single branch on nonzero, eliminate the addition
155179// and convert the branch to a BRCT(G) or BRCTH. Return true on success.
@@ -182,7 +206,7 @@ bool SystemZElimCompare::convertToBRCT(
182206 // We already know that there are no references to the register between
183207 // MI and Compare. Make sure that there are also no references between
184208 // Compare and Branch.
185- unsigned SrcReg = TII-> getCompareSourceReg (Compare);
209+ unsigned SrcReg = getCompareSourceReg (Compare);
186210 MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
187211 for (++MBBI; MBBI != MBBE; ++MBBI)
188212 if (getRegReferences (*MBBI, SrcReg))
@@ -229,7 +253,7 @@ bool SystemZElimCompare::convertToLoadAndTrap(
229253 // We already know that there are no references to the register between
230254 // MI and Compare. Make sure that there are also no references between
231255 // Compare and Branch.
232- unsigned SrcReg = TII-> getCompareSourceReg (Compare);
256+ unsigned SrcReg = getCompareSourceReg (Compare);
233257 MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
234258 for (++MBBI; MBBI != MBBE; ++MBBI)
235259 if (getRegReferences (*MBBI, SrcReg))
@@ -470,17 +494,25 @@ bool SystemZElimCompare::adjustCCMasksForInstr(
470494 return true ;
471495}
472496
497+ // Return true if Compare is a comparison against zero.
498+ static bool isCompareZero (MachineInstr &Compare) {
499+ if (isLoadAndTestAsCmp (Compare))
500+ return true ;
501+ return Compare.getNumExplicitOperands () == 2 &&
502+ Compare.getOperand (1 ).isImm () && Compare.getOperand (1 ).getImm () == 0 ;
503+ }
504+
473505// Try to optimize cases where comparison instruction Compare is testing
474506// a value against zero. Return true on success and if Compare should be
475507// deleted as dead. CCUsers is the list of instructions that use the CC
476508// value produced by Compare.
477509bool SystemZElimCompare::optimizeCompareZero (
478510 MachineInstr &Compare, SmallVectorImpl<MachineInstr *> &CCUsers) {
479- if (!TII-> isCompareZero (Compare))
511+ if (!isCompareZero (Compare))
480512 return false ;
481513
482514 // Search back for CC results that are based on the first operand.
483- unsigned SrcReg = TII-> getCompareSourceReg (Compare);
515+ unsigned SrcReg = getCompareSourceReg (Compare);
484516 MachineBasicBlock &MBB = *Compare.getParent ();
485517 Reference CCRefs;
486518 Reference SrcRefs;
@@ -669,7 +701,7 @@ bool SystemZElimCompare::processBlock(MachineBasicBlock &MBB) {
669701 MachineBasicBlock::iterator MBBI = MBB.end ();
670702 while (MBBI != MBB.begin ()) {
671703 MachineInstr &MI = *--MBBI;
672- if (CompleteCCUsers && (MI.isCompare () || TII-> isLoadAndTestAsCmp (MI)) &&
704+ if (CompleteCCUsers && (MI.isCompare () || isLoadAndTestAsCmp (MI)) &&
673705 (optimizeCompareZero (MI, CCUsers) ||
674706 fuseCompareOperations (MI, CCUsers))) {
675707 ++MBBI;
0 commit comments