summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll')
-rw-r--r--llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll151
1 files changed, 151 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll b/llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll
new file mode 100644
index 00000000000..bdbff4ac89b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/callbr-asm-branch-folding.ll
@@ -0,0 +1,151 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+; This test hung in the BranchFolding pass during asm-goto bring up
+
+@e = global i32 0
+@j = global i32 0
+
+define void @n(i32* %o, i32 %p, i32 %u) nounwind {
+; CHECK-LABEL: n:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: pushq %rbp
+; CHECK-NEXT: pushq %r15
+; CHECK-NEXT: pushq %r14
+; CHECK-NEXT: pushq %r13
+; CHECK-NEXT: pushq %r12
+; CHECK-NEXT: pushq %rbx
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: movl %edx, %ebx
+; CHECK-NEXT: movl %esi, %r12d
+; CHECK-NEXT: movq %rdi, %r15
+; CHECK-NEXT: callq c
+; CHECK-NEXT: movl %eax, %r13d
+; CHECK-NEXT: movq %r15, %rdi
+; CHECK-NEXT: callq l
+; CHECK-NEXT: testl %eax, %eax
+; CHECK-NEXT: je .LBB0_1
+; CHECK-NEXT: .LBB0_10: # %cleanup
+; CHECK-NEXT: addq $8, %rsp
+; CHECK-NEXT: popq %rbx
+; CHECK-NEXT: popq %r12
+; CHECK-NEXT: popq %r13
+; CHECK-NEXT: popq %r14
+; CHECK-NEXT: popq %r15
+; CHECK-NEXT: popq %rbp
+; CHECK-NEXT: retq
+; CHECK-NEXT: .LBB0_1: # %if.end
+; CHECK-NEXT: movl %ebx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT: cmpl $0, {{.*}}(%rip)
+; CHECK-NEXT: # implicit-def: $ebx
+; CHECK-NEXT: # implicit-def: $r14d
+; CHECK-NEXT: je .LBB0_4
+; CHECK-NEXT: # %bb.2: # %if.then4
+; CHECK-NEXT: movslq %r12d, %rdi
+; CHECK-NEXT: callq m
+; CHECK-NEXT: # implicit-def: $ebx
+; CHECK-NEXT: # implicit-def: $ebp
+; CHECK-NEXT: .LBB0_3: # %r
+; CHECK-NEXT: callq c
+; CHECK-NEXT: movl %ebp, %r14d
+; CHECK-NEXT: .LBB0_4: # %if.end8
+; CHECK-NEXT: movl %ebx, %edi
+; CHECK-NEXT: callq i
+; CHECK-NEXT: movl %eax, %ebp
+; CHECK-NEXT: orl %r14d, %ebp
+; CHECK-NEXT: testl %r13d, %r13d
+; CHECK-NEXT: je .LBB0_6
+; CHECK-NEXT: # %bb.5:
+; CHECK-NEXT: andl $4, %ebx
+; CHECK-NEXT: jmp .LBB0_3
+; CHECK-NEXT: .LBB0_6: # %if.end12
+; CHECK-NEXT: testl %ebp, %ebp
+; CHECK-NEXT: je .LBB0_9
+; CHECK-NEXT: # %bb.7: # %if.then14
+; CHECK-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %eax # 4-byte Reload
+; CHECK-NEXT: #APP
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: jmp .LBB0_10
+; CHECK-NEXT: .Ltmp0: # Block address taken
+; CHECK-NEXT: .LBB0_8: # %if.then20.critedge
+; CHECK-NEXT: movl {{.*}}(%rip), %edi
+; CHECK-NEXT: movslq %eax, %rcx
+; CHECK-NEXT: movl $1, %esi
+; CHECK-NEXT: movq %r15, %rdx
+; CHECK-NEXT: addq $8, %rsp
+; CHECK-NEXT: popq %rbx
+; CHECK-NEXT: popq %r12
+; CHECK-NEXT: popq %r13
+; CHECK-NEXT: popq %r14
+; CHECK-NEXT: popq %r15
+; CHECK-NEXT: popq %rbp
+; CHECK-NEXT: jmp k # TAILCALL
+; CHECK-NEXT: .LBB0_9: # %if.else
+; CHECK-NEXT: incq 0
+; CHECK-NEXT: jmp .LBB0_10
+entry:
+ %call = tail call i32 @c()
+ %call1 = tail call i32 @l(i32* %o)
+ %tobool = icmp eq i32 %call1, 0
+ br i1 %tobool, label %if.end, label %cleanup
+
+if.end: ; preds = %entry
+ %0 = load i32, i32* @e
+ %tobool3 = icmp eq i32 %0, 0
+ br i1 %tobool3, label %if.end8, label %if.then4, !prof !0
+
+if.then4: ; preds = %if.end
+ %conv5 = sext i32 %p to i64
+ %call6 = tail call i32 @m(i64 %conv5)
+ br label %r
+
+r: ; preds = %if.end8, %if.then4
+ %flags.0 = phi i32 [ undef, %if.then4 ], [ %and, %if.end8 ]
+ %major.0 = phi i32 [ undef, %if.then4 ], [ %or, %if.end8 ]
+ %call7 = tail call i32 @c()
+ br label %if.end8
+
+if.end8: ; preds = %r, %if.end
+ %flags.1 = phi i32 [ %flags.0, %r ], [ undef, %if.end ]
+ %major.1 = phi i32 [ %major.0, %r ], [ undef, %if.end ]
+ %call9 = tail call i32 @i(i32 %flags.1)
+ %or = or i32 %call9, %major.1
+ %and = and i32 %flags.1, 4
+ %tobool10 = icmp eq i32 %call, 0
+ br i1 %tobool10, label %if.end12, label %r
+
+if.end12: ; preds = %if.end8
+ %tobool13 = icmp eq i32 %or, 0
+ br i1 %tobool13, label %if.else, label %if.then14
+
+if.then14: ; preds = %if.end12
+ callbr void asm sideeffect "", "X,~{dirflag},~{fpsr},~{flags}"(i8* blockaddress(@n, %if.then20.critedge))
+ to label %cleanup [label %if.then20.critedge]
+
+if.then20.critedge: ; preds = %if.then14
+ %1 = load i32, i32* @j
+ %conv21 = sext i32 %u to i64
+ %call22 = tail call i32 @k(i32 %1, i64 1, i32* %o, i64 %conv21)
+ br label %cleanup
+
+if.else: ; preds = %if.end12
+ %2 = load i64, i64* null
+ %inc = add i64 %2, 1
+ store i64 %inc, i64* null
+ br label %cleanup
+
+cleanup: ; preds = %if.else, %if.then20.critedge, %if.then14, %entry
+ ret void
+}
+
+declare i32 @c()
+
+declare i32 @l(i32*)
+
+declare i32 @m(i64)
+
+declare i32 @i(i32)
+
+declare i32 @k(i32, i64, i32*, i64)
+
+!0 = !{!"branch_weights", i32 2000, i32 1}
OpenPOWER on IntegriCloud