diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
| commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
| tree | 4def12e759965de927d963ac65840d663ef9d1ea /test/CodeGen/Mips/compactbranches | |
| parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
Notes
Diffstat (limited to 'test/CodeGen/Mips/compactbranches')
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 +} + |
