[AArch64][FastISel] Always use AND before checking the branch flag.
authorJuergen Ributzka <juergen@apple.com>
Thu, 6 Aug 2015 22:44:15 +0000 (22:44 +0000)
committerJuergen Ributzka <juergen@apple.com>
Thu, 6 Aug 2015 22:44:15 +0000 (22:44 +0000)
When we are not emitting the condition for the branch, because the condition is
in another BB or SDAG did the selection for us, then we have to mask the flag in
the register with AND.

This is required when the condition comes from a truncate, because SDAG only
truncates down to a legal size of i32.

This fixes rdar://problem/22161062.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244291 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64FastISel.cpp
test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll [new file with mode: 0644]

index 280e5fc2b5023dfdf3bd3fbcfc51b6cf04dbf679..ab24fe4454e7a493eef2275d78b111267d327c4f 100644 (file)
@@ -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/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll b/test/CodeGen/AArch64/fast-isel-branch-cond-mask.ll
new file mode 100644 (file)
index 0000000..c018b27
--- /dev/null
@@ -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
+}