From b11c5b1078eea128a2b2e80c7bf43017f2c4552b Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Mon, 27 Oct 2014 19:38:05 +0000 Subject: [PATCH] [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 --- lib/Target/AArch64/AArch64FastISel.cpp | 27 ++++++++++++-------------- test/CodeGen/AArch64/fast-isel-cbz.ll | 11 +++++++++++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/Target/AArch64/AArch64FastISel.cpp b/lib/Target/AArch64/AArch64FastISel.cpp index d6269284801..09bdab7fe8d 100644 --- a/lib/Target/AArch64/AArch64FastISel.cpp +++ b/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(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(LHS)) + if (const auto *C = dyn_cast(LHS)) if (C->isNullValue()) std::swap(LHS, RHS); - if (!isa(RHS)) + if (!isa(RHS)) return false; - if (!cast(RHS)->isNullValue()) + if (!cast(RHS)->isNullValue()) return false; if (const auto *AI = dyn_cast(LHS)) @@ -2134,10 +2134,10 @@ bool AArch64FastISel::emitCompareAndBranch(const BranchInst *BI) { } IsCmpNE = Predicate == CmpInst::ICMP_NE; } else if (Predicate == CmpInst::ICMP_SLT) { - if (!isa(RHS)) + if (!isa(RHS)) return false; - if (!cast(RHS)->isNullValue()) + if (!cast(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/test/CodeGen/AArch64/fast-isel-cbz.ll b/test/CodeGen/AArch64/fast-isel-cbz.ll index 4cd4b539401..20c5df105ad 100644 --- a/test/CodeGen/AArch64/fast-isel-cbz.ll +++ b/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 +} + -- 2.34.1