[FastISel][AArch64] Use 'cbz' also for null values (pointers).

The pattern matching for a 'ConstantInt' value was too restrictive. Checking for
a 'Constant' with a bull value is sufficient for using an 'cbz/cbnz' instruction.

This fixes rdar://problem/18784732.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220709 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Juergen Ributzka 2014-10-27 19:38:05 +00:00
parent 5745cad861
commit b11c5b1078
2 changed files with 23 additions and 15 deletions

View File

@ -2087,12 +2087,12 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
const Value *LHS = CI->getOperand(0); const Value *LHS = CI->getOperand(0);
const Value *RHS = CI->getOperand(1); const Value *RHS = CI->getOperand(1);
Type *Ty = LHS->getType(); MVT VT;
if (!Ty->isIntegerTy()) if (!isTypeSupported(LHS->getType(), VT))
return false; return false;
unsigned BW = cast<IntegerType>(Ty)->getBitWidth(); unsigned BW = VT.getSizeInBits();
if (BW != 1 && BW != 8 && BW != 16 && BW != 32 && BW != 64) if (BW > 64)
return false; return false;
MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)]; MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
@ -2107,14 +2107,14 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
int TestBit = -1; int TestBit = -1;
bool IsCmpNE; bool IsCmpNE;
if ((Predicate == CmpInst::ICMP_EQ) || (Predicate == CmpInst::ICMP_NE)) { if ((Predicate == CmpInst::ICMP_EQ) || (Predicate == CmpInst::ICMP_NE)) {
if (const auto *C = dyn_cast<ConstantInt>(LHS)) if (const auto *C = dyn_cast<Constant>(LHS))
if (C->isNullValue()) if (C->isNullValue())
std::swap(LHS, RHS); std::swap(LHS, RHS);
if (!isa<ConstantInt>(RHS)) if (!isa<Constant>(RHS))
return false; return false;
if (!cast<ConstantInt>(RHS)->isNullValue()) if (!cast<Constant>(RHS)->isNullValue())
return false; return false;
if (const auto *AI = dyn_cast<BinaryOperator>(LHS)) if (const auto *AI = dyn_cast<BinaryOperator>(LHS))
@ -2134,10 +2134,10 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
} }
IsCmpNE = Predicate == CmpInst::ICMP_NE; IsCmpNE = Predicate == CmpInst::ICMP_NE;
} else if (Predicate == CmpInst::ICMP_SLT) { } else if (Predicate == CmpInst::ICMP_SLT) {
if (!isa<ConstantInt>(RHS)) if (!isa<Constant>(RHS))
return false; return false;
if (!cast<ConstantInt>(RHS)->isNullValue()) if (!cast<Constant>(RHS)->isNullValue())
return false; return false;
TestBit = BW - 1; TestBit = BW - 1;
@ -2178,11 +2178,8 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill, SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill,
AArch64::sub_32); AArch64::sub_32);
if ((BW < 32) && !IsBitTest) { if ((BW < 32) && !IsBitTest)
EVT CmpEVT = TLI.getValueType(Ty, true); SrcReg = emitIntExt(VT, SrcReg, MVT::i32, /*IsZExt=*/true);
SrcReg =
emitIntExt(CmpEVT.getSimpleVT(), SrcReg, MVT::i32, /*isZExt*/ true);
}
// Emit the combined compare and branch instruction. // Emit the combined compare and branch instruction.
SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs()); SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs());

View File

@ -58,3 +58,14 @@ bb1:
ret i32 0 ret i32 0
} }
define i32 @icmp_eq_ptr(i8* %a) {
; CHECK-LABEL: icmp_eq_ptr
; CHECK: cbz x0, {{LBB.+_2}}
%1 = icmp eq i8* %a, null
br i1 %1, label %bb1, label %bb2
bb2:
ret i32 1
bb1:
ret i32 0
}