ARM: Fix optimizeCompare to correctly check safe condition.

It is safe if CPSR is killed or re-defined.
When we are done with the basic block, check whether CPSR is live-out.
Do not optimize away cmp if CPSR is live-out.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160090 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Manman Ren 2012-07-11 22:51:44 +00:00
parent 1d82115042
commit 45ed19499b
2 changed files with 33 additions and 9 deletions

View File

@ -1974,10 +1974,10 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
case ARM::t2EORri: {
// Scan forward for the use of CPSR
// When checking against MI: if it's a conditional code requires
// checking of V bit, then this is not safe to do. If we can't find the
// CPSR use (i.e. used in another block), then it's not safe to perform
// the optimization.
// When checking against Sub, we handle the condition codes GE, LT, GT, LE.
// checking of V bit, then this is not safe to do.
// It is safe to remove CmpInstr if CPSR is redefined or killed.
// If we are done with the basic block, we need to check whether CPSR is
// live-out.
SmallVector<std::pair<MachineOperand*, ARMCC::CondCodes>, 4>
OperandsToUpdate;
bool isSafe = false;
@ -2017,7 +2017,7 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
else
switch (CC) {
default:
isSafe = true;
// CPSR can be used mutliple times, we should continue.
break;
case ARMCC::VS:
case ARMCC::VC:
@ -2030,10 +2030,15 @@ optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2,
}
}
// If the candidate is Sub, we may exit the loop at end of the basic block.
// In that case, it is still safe to remove CmpInstr.
if (!isSafe && !Sub)
return false;
// If CPSR is not killed nor re-defined, we should check whether it is
// live-out. If it is live-out, do not optimize.
if (!isSafe) {
MachineBasicBlock *MBB = CmpInstr->getParent();
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
SE = MBB->succ_end(); SI != SE; ++SI)
if ((*SI)->isLiveIn(ARM::CPSR))
return false;
}
// Toggle the optional operand to CPSR.
MI->getOperand(5).setReg(ARM::CPSR);

View File

@ -44,3 +44,22 @@ entry:
%sub. = select i1 %cmp, i32 %sub, i32 0
ret i32 %sub.
}
; If CPSR is live-out, we can't remove cmp if there exists
; a swapped sub.
define i32 @j(i32 %a, i32 %b) nounwind {
entry:
; CHECK: j:
; CHECK: sub
; CHECK: cmp
%cmp = icmp eq i32 %b, %a
%sub = sub nsw i32 %a, %b
br i1 %cmp, label %if.then, label %if.else
if.then:
%cmp2 = icmp sgt i32 %b, %a
%sel = select i1 %cmp2, i32 %sub, i32 %a
ret i32 %sel
if.else:
ret i32 %sub
}