aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/Mips/compactbranches
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /test/CodeGen/Mips/compactbranches
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
Notes
Diffstat (limited to 'test/CodeGen/Mips/compactbranches')
-rw-r--r--test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll55
-rw-r--r--test/CodeGen/Mips/compactbranches/compact-branch-policy.ll28
-rw-r--r--test/CodeGen/Mips/compactbranches/compact-branches.ll206
-rw-r--r--test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll53
4 files changed, 342 insertions, 0 deletions
diff --git a/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll b/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll
new file mode 100644
index 000000000000..3cec194a3786
--- /dev/null
+++ b/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll
@@ -0,0 +1,55 @@
+; RUN: llc -march=mips -mcpu=mips32r6 -O1 -start-after=dwarfehprepare < %s | FileCheck %s
+
+; beqc/bnec have the constraint that $rs < $rt && $rs != 0 && $rt != 0
+; Cases where $rs == 0 and $rt != 0 should be transformed into beqzc/bnezc.
+; Cases where $rs > $rt can have the operands swapped as ==,!= are commutative.
+
+; Cases where beq & bne where $rs == $rt have to inhibited from being turned
+; into compact branches but arguably should not occur. This test covers the
+; $rs == $rt case.
+
+; Starting from dwarf exception handling preparation skips optimizations that
+; may simplify out the crucical bnec $4, $4 instruction.
+
+define internal void @_ZL14TestRemoveLastv(i32* %alist.sroa.0.4) {
+entry:
+ %ascevgep = getelementptr i32, i32* %alist.sroa.0.4, i64 99
+ br label %do.body121
+
+for.cond117:
+ %alsr.iv.next = add nsw i32 %alsr.iv, -1
+ %ascevgep340 = getelementptr i32, i32* %alsr.iv339, i64 -1
+ %acmp118 = icmp sgt i32 %alsr.iv.next, 0
+ br i1 %acmp118, label %do.body121, label %if.then143
+
+do.body121:
+ %alsr.iv339 = phi i32* [ %ascevgep, %entry ], [ %ascevgep340, %for.cond117 ]
+ %alsr.iv = phi i32 [ 100, %entry ], [ %alsr.iv.next, %for.cond117 ]
+ %a9 = add i32 %alsr.iv, -1
+ %alnot124 = icmp eq i32 %alsr.iv, %alsr.iv
+ br i1 %alnot124, label %do.body134, label %if.then143, !prof !11
+
+do.body134:
+ %a10 = add i32 %alsr.iv, -1
+ %a11 = load i32, i32* %alsr.iv339, align 4, !tbaa !5
+; CHECK-NOT: bnec $[[R0:[0-9]+]], $[[R0]]
+; CHECK-NOT: beqc $[[R1:[0-9]+]], $[[R1]]
+ %alnot137 = icmp eq i32 %a9, %a11
+ br i1 %alnot137, label %do.end146, label %if.then143, !prof !11
+
+if.then143:
+ ret void
+ unreachable
+
+do.end146:
+ %alnot151 = icmp eq i32 %a9, %a10
+ br i1 %alnot151, label %for.cond117, label %if.then143, !prof !11
+
+}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C++ TBAA"}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !3, i64 0}
+!11 = !{!"branch_weights", i32 2000, i32 1}
+!12 = !{!"branch_weights", i32 -388717296, i32 7818360}
+
diff --git a/test/CodeGen/Mips/compactbranches/compact-branch-policy.ll b/test/CodeGen/Mips/compactbranches/compact-branch-policy.ll
new file mode 100644
index 000000000000..c819bf59ace6
--- /dev/null
+++ b/test/CodeGen/Mips/compactbranches/compact-branch-policy.ll
@@ -0,0 +1,28 @@
+; Check that -mips-compact-branches={never,optimal,always} is accepted and honoured.
+; RUN: llc -march=mips -mcpu=mips32r6 -mips-compact-branches=never < %s | FileCheck %s -check-prefix=NEVER
+; RUN: llc -march=mips -mcpu=mips32r6 -mips-compact-branches=optimal < %s | FileCheck %s -check-prefix=OPTIMAL
+; RUN: llc -march=mips -mcpu=mips32r6 -mips-compact-branches=always < %s | FileCheck %s -check-prefix=ALWAYS
+
+define i32 @l(i32 signext %a, i32 signext %b) {
+entry:
+ %add = add nsw i32 %b, %a
+ %cmp = icmp slt i32 %add, 100
+; NEVER: beq
+; OPTIMAL: beq
+; ALWAYS: beqzc
+; This nop is required for correct as having (j|b)al as the instruction
+; immediately following beqzc would cause a forbidden slot hazard.
+; ALWAYS: nop
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %call = tail call i32 @k()
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ %call.pn = phi i32 [ %call, %if.then ], [ -1, %entry ]
+ %c.0 = add nsw i32 %call.pn, %add
+ ret i32 %c.0
+}
+
+declare i32 @k() #1
diff --git a/test/CodeGen/Mips/compactbranches/compact-branches.ll b/test/CodeGen/Mips/compactbranches/compact-branches.ll
new file mode 100644
index 000000000000..75ff8a0bbcbb
--- /dev/null
+++ b/test/CodeGen/Mips/compactbranches/compact-branches.ll
@@ -0,0 +1,206 @@
+; RUN: llc -march=mipsel -mcpu=mips32r6 -relocation-model=static -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=STATIC32
+; RUN: llc -march=mipsel -mcpu=mips64r6 -target-abi n64 -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=PIC
+
+; Function Attrs: nounwind
+define void @l() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+; PIC: jalrc $25
+ %call1 = tail call i32 @j()
+ %cmp = icmp eq i32 %call, %call1
+; CHECK: bnec
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext -2)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret void
+}
+
+declare i32 @k()
+
+declare i32 @j()
+
+declare void @f(i32 signext)
+
+; Function Attrs: define void @l2() {
+define void @l2() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+; PIC: jalrc $25
+ %call1 = tail call i32 @i()
+ %cmp = icmp eq i32 %call, %call1
+; CHECK beqc
+ br i1 %cmp, label %if.end, label %if.then
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext -1)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+; CHECK: jrc $ra
+ ret void
+}
+
+declare i32 @i()
+
+; Function Attrs: nounwind
+define void @l3() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+ %cmp = icmp slt i32 %call, 0
+; CHECK : bgez
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext 0)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @l4() {
+entry:
+ %call = tail call i32 @k()
+ %cmp = icmp slt i32 %call, 1
+; CHECK: bgtzc
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+ tail call void @f(i32 signext 1)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @l5() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+; PIC: jalrc $25
+ %cmp = icmp sgt i32 %call, 0
+; CHECK: blezc
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext 2)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @l6() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+; PIC: jalrc $25
+ %cmp = icmp sgt i32 %call, -1
+; CHECK: bltzc
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext 3)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @l7() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+ %cmp = icmp eq i32 %call, 0
+; CHECK: bnezc
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext 4)
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @l8() {
+entry:
+; PIC: jalrc $25
+ %call = tail call i32 @k()
+ %cmp = icmp eq i32 %call, 0
+; CHECK: beqzc
+ br i1 %cmp, label %if.end, label %if.then
+
+if.then: ; preds = %entry:
+; STATIC: nop
+; STATIC: jal
+; PIC: jalrc $25
+ tail call void @f(i32 signext 5)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+; CHECK: jrc $ra
+ ret void
+}
+
+define i32 @l9(i8* ()* %i) #0 {
+entry:
+ %i.addr = alloca i8* ()*, align 4
+ store i8* ()* %i, i8* ()** %i.addr, align 4
+; STATIC32: jal
+; STATIC32: nop
+; PIC: jalrc $25
+ %call = call i32 @k()
+; PIC: jalrc $25
+ %cmp = icmp ne i32 %call, 0
+; CHECK: beqzc
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %0 = load i8* ()*, i8* ()** %i.addr, align 4
+; CHECK: jalrc $25
+ %call1 = call i8* %0()
+ br label %if.end
+
+if.end: ; preds = %if.then, %entry
+; CHECK: jrc $ra
+ ret i32 -1
+}
diff --git a/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll b/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll
new file mode 100644
index 000000000000..f6fef90d01b9
--- /dev/null
+++ b/test/CodeGen/Mips/compactbranches/no-beqzc-bnezc.ll
@@ -0,0 +1,53 @@
+; RUN: llc -march=mipsel -mcpu=mips32r6 -disable-mips-delay-filler < %s | FileCheck %s
+; RUN: llc -march=mips -mcpu=mips32r6 -disable-mips-delay-filler < %s \
+; RUN: -filetype=obj -o - | llvm-objdump -d - | FileCheck %s -check-prefix=ENCODING
+
+; bnezc and beqzc have restriction that $rt != 0
+
+define i32 @f() {
+; CHECK-LABEL: f
+; CHECK-NOT: bnezc $0
+
+ %cmp = icmp eq i32 1, 1
+ br i1 %cmp, label %if.then, label %if.end
+
+ if.then:
+ ret i32 1
+
+ if.end:
+ ret i32 0
+}
+
+define i32 @f1() {
+; CHECK-LABEL: f1
+; CHECK-NOT: beqzc $0
+
+ %cmp = icmp eq i32 0, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+ if.then:
+ ret i32 1
+
+ if.end:
+ ret i32 0
+}
+
+; We silently fixup cases where the register allocator or user has given us
+; an instruction with incorrect operands that is trivially acceptable.
+; beqc and bnec have the restriction that $rs < $rt.
+
+define i32 @f2(i32 %a, i32 %b) {
+; ENCODING-LABEL: f2
+; ENCODING-NOT: beqc $5, $4
+; ENCODING-NOT: bnec $5, $4
+
+ %cmp = icmp eq i32 %b, %a
+ br i1 %cmp, label %if.then, label %if.end
+
+ if.then:
+ ret i32 1
+
+ if.end:
+ ret i32 0
+}
+