summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/AArch64/AArch64FastISel.cpp6
-rw-r--r--llvm/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll20
2 files changed, 25 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index 280e5fc2b50..ab24fe4454e 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -2413,7 +2413,11 @@ bool AArch64FastISel::selectBranch(const Instruction *I) {
// Regardless, the compare has been done in the predecessor block,
// and it left a value for us in a virtual register. Ergo, we test
// the one-bit value left in the virtual register.
- emitICmp_ri(MVT::i32, CondReg, CondRegIsKill, 0);
+ //
+ // FIXME: Optimize this with TBZW/TBZNW.
+ unsigned ANDReg = emitAnd_ri(MVT::i32, CondReg, CondRegIsKill, 1);
+ assert(ANDReg && "Unexpected AND instruction emission failure.");
+ emitICmp_ri(MVT::i32, ANDReg, /*IsKill=*/true, 0);
if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
std::swap(TBB, FBB);
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll b/llvm/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll
new file mode 100644
index 00000000000..c018b2778b0
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll
@@ -0,0 +1,20 @@
+; RUN: llc -mtriple=aarch64-apple-darwin -O0 -fast-isel -fast-isel-abort=0 -verify-machineinstrs < %s | FileCheck %s
+
+define void @test(i64 %a, i64 %b, i2* %c) {
+; CHECK-LABEL: test
+; CHECK: and [[REG1:w[0-9]+]], w8, #0x3
+; CHECK-NEXT: strb [[REG1]], {{\[}}x2{{\]}}
+; CHECK: and [[REG2:w[0-9]+]], w8, #0x1
+; CHECK-NEXT: cmp [[REG2]], #0
+ %1 = trunc i64 %a to i2
+ %2 = trunc i64 %b to i1
+; Force fast-isel to fall back to SDAG.
+ store i2 %1, i2* %c, align 8
+ br i1 %2, label %bb1, label %bb2
+
+bb1:
+ ret void
+
+bb2:
+ ret void
+}
OpenPOWER on IntegriCloud