summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2016-05-03 04:54:16 +0000
committerMatthias Braun <matze@braunis.de>2016-05-03 04:54:16 +0000
commite25bbd0bb82bb6fe2c04d0789d7896ea24086166 (patch)
tree3a1c25978b14cf429860a9d9500cc1b31a93f303
parent95b632d4b9bfeec40e9ef9c66c9adf29c72f092c (diff)
downloadbcm5719-llvm-e25bbd0bb82bb6fe2c04d0789d7896ea24086166.tar.gz
bcm5719-llvm-e25bbd0bb82bb6fe2c04d0789d7896ea24086166.zip
AArch64/optimizeCondBranch: Remove earlier kill flag when forming TBZ
This fixes -verify-machineinstrs complaints when compiling test-suite/SingleSource/Benchmarks/Shootout-C++/wordfreq.cpp llvm-svn: 268360
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.cpp2
-rw-r--r--llvm/test/CodeGen/AArch64/optimize-cond-branch.ll48
2 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index f152854546a..46d90abbe2a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -3888,6 +3888,8 @@ bool AArch64InstrInfo::optimizeCondBranch(MachineInstr *MI) const {
.addReg(NewReg)
.addImm(Imm)
.addMBB(TBB);
+ // Register lives on to the CBZ now.
+ MO.setIsKill(false);
// For immediate smaller than 32, we need to use the 32-bit
// variant (W) in all cases. Indeed the 64-bit variant does not
diff --git a/llvm/test/CodeGen/AArch64/optimize-cond-branch.ll b/llvm/test/CodeGen/AArch64/optimize-cond-branch.ll
new file mode 100644
index 00000000000..ef6e31baa71
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/optimize-cond-branch.ll
@@ -0,0 +1,48 @@
+; RUN: llc -verify-machineinstrs -o - %s | FileCHeck %s
+target triple = "arm64--"
+
+; AArch64InstrInfo::optimizeCondBranch() optimizes the
+; "x = and y, 256; cmp x, 0; br" from an "and; cbnz" to a tbnz instruction.
+; It forgot to clear the a flag resulting in a MachineVerifier complaint.
+;
+; Writing a stable/simple test is tricky since most tbz instructions are already
+; formed in SelectionDAG, optimizeCondBranch() only triggers if the and
+; instruction is in a different block than the conditional jump.
+;
+; CHECK-LABEL: func
+; CHECK-NOT: and
+; CHECK: tbnz
+define void @func() {
+ %c0 = icmp sgt i64 0, 0
+ br i1 %c0, label %b1, label %b6
+
+b1:
+ br i1 undef, label %b3, label %b2
+
+b2:
+ %v0 = tail call i32 @extfunc()
+ br label %b5
+
+b3:
+ %v1 = load i32, i32* undef, align 4
+ %v2 = and i32 %v1, 256
+ br label %b5
+
+b5:
+ %v3 = phi i32 [ %v2, %b3 ], [ %v0, %b2 ]
+ %c1 = icmp eq i32 %v3, 0
+ br i1 %c1, label %b8, label %b7
+
+b6:
+ tail call i32 @extfunc()
+ ret void
+
+b7:
+ tail call i32 @extfunc()
+ ret void
+
+b8:
+ ret void
+}
+
+declare i32 @extfunc()
OpenPOWER on IntegriCloud