diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp --- a/llvm/lib/CodeGen/TailDuplicator.cpp +++ b/llvm/lib/CodeGen/TailDuplicator.cpp @@ -799,6 +799,8 @@ return false; if (!PredCond.empty()) return false; + if (TailBB->isInlineAsmBrIndirectTarget()) + return false; return true; } diff --git a/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll b/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll --- a/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll +++ b/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll @@ -1,20 +1,35 @@ -; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -filetype=obj -o - \ -; RUN: | llvm-objdump --triple=aarch64-unknown-linux-gnu -d - \ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc %s -mtriple=aarch64-unknown-linux-gnu -o - \ ; RUN: | FileCheck %s %struct.c = type { i1 (...)* } @l = common hidden local_unnamed_addr global i32 0, align 4 -; CHECK-LABEL: : -; CHECK-LABEL: <$d.1>: -; CHECK-LABEL: <$x.2>: -; CHECK-NEXT: b 0x2c <$x.4> -; CHECK-LABEL: <$x.4>: +define hidden i32 @test1() { +; CHECK-LABEL: test1: +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 +; CHECK-NEXT: bl g +; CHECK-NEXT: cbz w0, .LBB0_2 +; CHECK-NEXT: // %bb.1: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: b i +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: //APP +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: nop +; CHECK-NEXT: .xword a +; CHECK-NEXT: b .Ltmp0 +; CHECK-NEXT: .xword 0 +; CHECK-NEXT: //NO_APP +; CHECK-NEXT: .Ltmp0: // Block address taken +; CHECK-NEXT: // %bb.3: ; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ldr x30, [sp], #16 +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-NEXT: ret -define hidden i32 @test1() { %1 = tail call i32 bitcast (i32 (...)* @g to i32 ()*)() %2 = icmp eq i32 %1, 0 br i1 %2, label %3, label %5 @@ -39,12 +54,33 @@ declare dso_local i32 @i(...) local_unnamed_addr -; CHECK-LABEL: : -; CHECK: bl {{.*}} -; CHECK-LABEL: <$d.5>: -; CHECK-LABEL: <$x.6>: -; CHECK-NEXT: b {{.*}} define hidden i32 @test2() local_unnamed_addr { +; CHECK-LABEL: test2: +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 +; CHECK-NEXT: adrp x8, l +; CHECK-NEXT: ldr w8, [x8, :lo12:l] +; CHECK-NEXT: cbz w8, .LBB1_4 +; CHECK-NEXT: // %bb.1: +; CHECK-NEXT: bl g +; CHECK-NEXT: cbz w0, .LBB1_3 +; CHECK-NEXT: .Ltmp2: // Block address taken +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: bl i +; CHECK-NEXT: b .LBB1_4 +; CHECK-NEXT: .LBB1_3: +; CHECK-NEXT: //APP +; CHECK-NEXT: .Ltmp3: +; CHECK-NEXT: nop +; CHECK-NEXT: .xword b +; CHECK-NEXT: b .Ltmp2 +; CHECK-NEXT: .xword 0 +; CHECK-NEXT: //NO_APP +; CHECK-NEXT: .LBB1_4: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret %1 = load i32, i32* @l, align 4 %2 = icmp eq i32 %1, 0 br i1 %2, label %10, label %3 @@ -69,14 +105,31 @@ ret i32 undef } -; CHECK-LABEL: : -; CHECK-LABEL: <$d.9>: -; CHECK-LABEL: <$x.10>: -; CHECK-NEXT: b {{.*}} -; CHECK-LABEL: <$x.12>: -; CHECK-NEXT: ldr x30, [sp], #16 -; CHECK-NEXT: ret define internal i1 @test3() { +; CHECK-LABEL: test3: +; CHECK: // %bb.0: +; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: .cfi_offset w30, -16 +; CHECK-NEXT: bl g +; CHECK-NEXT: cbz w0, .LBB2_2 +; CHECK-NEXT: // %bb.1: +; CHECK-NEXT: bl i +; CHECK-NEXT: cmp w0, #0 +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: b .LBB2_3 +; CHECK-NEXT: .LBB2_2: +; CHECK-NEXT: //APP +; CHECK-NEXT: .Ltmp5: +; CHECK-NEXT: nop +; CHECK-NEXT: .xword c +; CHECK-NEXT: b .Ltmp4 +; CHECK-NEXT: .xword 0 +; CHECK-NEXT: //NO_APP +; CHECK-NEXT: .Ltmp4: // Block address taken +; CHECK-NEXT: .LBB2_3: +; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; CHECK-NEXT: ret %1 = tail call i32 bitcast (i32 (...)* @g to i32 ()*)() %2 = icmp eq i32 %1, 0 br i1 %2, label %3, label %5 diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll --- a/llvm/test/CodeGen/X86/callbr-asm-outputs.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs.ll @@ -174,13 +174,13 @@ ; CHECK-NEXT: # %bb.2: # %asm.fallthrough2 ; CHECK-NEXT: addl %edx, %ecx ; CHECK-NEXT: movl %ecx, %eax +; CHECK-NEXT: .Ltmp5: # Block address taken +; CHECK-NEXT: .LBB3_4: # %return ; CHECK-NEXT: retl ; CHECK-NEXT: .Ltmp4: # Block address taken ; CHECK-NEXT: .LBB3_3: # %label_true ; CHECK-NEXT: movl $-2, %eax -; CHECK-NEXT: .Ltmp5: # Block address taken -; CHECK-NEXT: .LBB3_4: # %return -; CHECK-NEXT: retl +; CHECK-NEXT: jmp .LBB3_4 entry: %0 = callbr { i32, i32 } asm sideeffect "testl $0, $0; testl $1, $2; jne ${3:l}", "=r,=r,r,!i,!i,~{dirflag},~{fpsr},~{flags}"(i32 %out1) to label %asm.fallthrough [label %label_true, label %return]