[PATCH] D15122: AArch64FastISel: Use cbz/cbnz to branch on i1

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 1 10:37:21 PST 2015


MatzeB created this revision.
MatzeB added reviewers: ributzka, t.p.northover.
MatzeB added a subscriber: llvm-commits.
MatzeB set the repository for this revision to rL LLVM.
Herald added subscribers: rengolin, aemerson.

In the case of a conditional branch without a preceding cmp or similar we
used to emit a "and; cmp; b.eq/b.ne" sequence, use cbnz/cbz instead.

rdar://18783875

Repository:
  rL LLVM

http://reviews.llvm.org/D15122

Files:
  lib/Target/AArch64/AArch64FastISel.cpp
  test/CodeGen/AArch64/fast-isel-branch-cond-split.ll

Index: test/CodeGen/AArch64/fast-isel-branch-cond-split.ll
===================================================================
--- test/CodeGen/AArch64/fast-isel-branch-cond-split.ll
+++ test/CodeGen/AArch64/fast-isel-branch-cond-split.ll
@@ -44,9 +44,7 @@
 ; CHECK-NEXT:  cmp   w1, #0
 ; CHECK-NEXT:  cset  w9, eq
 ; CHECK-NEXT:  orr   w8, w8, w9
-; CHECK-NEXT:  and   w8, w8, #0x1
-; CHECK-NEXT:  cmp   w8, #0
-; CHECK-NEXT:  b.ne 
+; CHECK-NEXT:  cbnz w8
 define i64 @test_or_unpredictable(i32 %a, i32 %b) {
 bb1:
   %0 = icmp eq i32 %a, 0
@@ -68,9 +66,7 @@
 ; CHECK-NEXT:  cmp   w1, #0
 ; CHECK-NEXT:  cset  w9, ne
 ; CHECK-NEXT:  and   w8, w8, w9
-; CHECK-NEXT:  and   w8, w8, #0x1
-; CHECK-NEXT:  cmp   w8, #0
-; CHECK-NEXT:  b.eq 
+; CHECK-NEXT:  cbz w8
 define i64 @test_and_unpredictable(i32 %a, i32 %b) {
 bb1:
   %0 = icmp ne i32 %a, 0
Index: lib/Target/AArch64/AArch64FastISel.cpp
===================================================================
--- lib/Target/AArch64/AArch64FastISel.cpp
+++ lib/Target/AArch64/AArch64FastISel.cpp
@@ -2411,19 +2411,17 @@
   // 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.
-  //
-  // 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);
 
+  // i1 conditions come as an i32 value which we can use as input for cbnzw.
+  assert(CC == AArch64CC::NE);
+  unsigned Opcode = AArch64::CBNZW;
   if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
     std::swap(TBB, FBB);
-    CC = AArch64CC::EQ;
+    Opcode = AArch64::CBZW;
   }
 
-  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::Bcc))
-      .addImm(CC)
+  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opcode))
+      .addReg(CondReg, getKillRegState(CondRegIsKill))
       .addMBB(TBB);
 
   finishCondBranch(BI->getParent(), TBB, FBB);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15122.41535.patch
Type: text/x-patch
Size: 2084 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151201/fbd88767/attachment.bin>


More information about the llvm-commits mailing list