summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-10-27 19:38:05 +0000
committerJuergen Ributzka <juergen@apple.com>2014-10-27 19:38:05 +0000
commit90f741a2ce6422ad7fc6db111a470f3da5b5942b (patch)
tree87a77761e85877da294ea547fe2165be357ef4c9 /llvm
parent68c29da4c5a6e3f5443c3b2bfc0ee6d2f44002c8 (diff)
downloadbcm5719-llvm-90f741a2ce6422ad7fc6db111a470f3da5b5942b.tar.gz
bcm5719-llvm-90f741a2ce6422ad7fc6db111a470f3da5b5942b.zip
[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. llvm-svn: 220709
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/AArch64/AArch64FastISel.cpp27
-rw-r--r--llvm/test/CodeGen/AArch64/fast-isel-cbz.ll11
2 files changed, 23 insertions, 15 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index d6269284801..09bdab7fe8d 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -2087,12 +2087,12 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
const Value *LHS = CI->getOperand(0);
const Value *RHS = CI->getOperand(1);
- Type *Ty = LHS->getType();
- if (!Ty->isIntegerTy())
- return false;
+ MVT VT;
+ if (!isTypeSupported(LHS->getType(), VT))
+ return false;
- unsigned BW = cast<IntegerType>(Ty)->getBitWidth();
- if (BW != 1 && BW != 8 && BW != 16 && BW != 32 && BW != 64)
+ unsigned BW = VT.getSizeInBits();
+ if (BW > 64)
return false;
MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
@@ -2107,14 +2107,14 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
int TestBit = -1;
bool IsCmpNE;
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())
std::swap(LHS, RHS);
- if (!isa<ConstantInt>(RHS))
+ if (!isa<Constant>(RHS))
return false;
- if (!cast<ConstantInt>(RHS)->isNullValue())
+ if (!cast<Constant>(RHS)->isNullValue())
return false;
if (const auto *AI = dyn_cast<BinaryOperator>(LHS))
@@ -2134,10 +2134,10 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
}
IsCmpNE = Predicate == CmpInst::ICMP_NE;
} else if (Predicate == CmpInst::ICMP_SLT) {
- if (!isa<ConstantInt>(RHS))
+ if (!isa<Constant>(RHS))
return false;
- if (!cast<ConstantInt>(RHS)->isNullValue())
+ if (!cast<Constant>(RHS)->isNullValue())
return false;
TestBit = BW - 1;
@@ -2178,11 +2178,8 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) {
SrcReg = fastEmitInst_extractsubreg(MVT::i32, SrcReg, SrcIsKill,
AArch64::sub_32);
- if ((BW < 32) && !IsBitTest) {
- EVT CmpEVT = TLI.getValueType(Ty, true);
- SrcReg =
- emitIntExt(CmpEVT.getSimpleVT(), SrcReg, MVT::i32, /*isZExt*/ true);
- }
+ if ((BW < 32) && !IsBitTest)
+ SrcReg = emitIntExt(VT, SrcReg, MVT::i32, /*IsZExt=*/true);
// Emit the combined compare and branch instruction.
SrcReg = constrainOperandRegClass(II, SrcReg, II.getNumDefs());
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-cbz.ll b/llvm/test/CodeGen/AArch64/fast-isel-cbz.ll
index 4cd4b539401..20c5df105ad 100644
--- a/llvm/test/CodeGen/AArch64/fast-isel-cbz.ll
+++ b/llvm/test/CodeGen/AArch64/fast-isel-cbz.ll
@@ -58,3 +58,14 @@ bb1:
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
+}
+
OpenPOWER on IntegriCloud