diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -8408,6 +8408,14 @@ bool AArch64InstrInfo::isMBBSafeToSplitToCold( const MachineBasicBlock &MBB) const { + // Asm Goto blocks can contain conditional branches to goto labels, which can + // get moved out of range of the branch instruction. + auto isAsmGoto = [](const MachineInstr &MI) { + return MI.getOpcode() == AArch64::INLINEASM_BR; + }; + if (llvm::any_of(MBB, isAsmGoto) || MBB.isInlineAsmBrIndirectTarget()) + return false; + // Because jump tables are label-relative instead of table-relative, they all // must be in the same section or relocation fixup handling will fail. diff --git a/llvm/test/CodeGen/Generic/machine-function-splitter.ll b/llvm/test/CodeGen/Generic/machine-function-splitter.ll --- a/llvm/test/CodeGen/Generic/machine-function-splitter.ll +++ b/llvm/test/CodeGen/Generic/machine-function-splitter.ll @@ -602,6 +602,33 @@ ret i32 %4 } +define void @foo20(i1 zeroext %0) !prof !14 !section_prefix !15 { +;; Check that blocks containing or targeted by asm goto aren't split. +; MFS-DEFAULTS-LABEL: foo20 +; MFS-DEFAULTS-AARCH64-NOT: foo20.cold: +; MFS-DEFAULTS-X86: .section .text.split.foo20 +; MFS-DEFAULTS-X86: foo20.cold: +; MFS-DEFAULTS-X86-DAG: # %cold_asm +; MFS-DEFAULTS-X86-DAG: # %cold_asm_target + + br i1 %0, label %hot, label %cold_asm, !prof !17 + +hot: + %2 = call i32 @bar() + ret void + +cold_asm: + callbr void asm sideeffect "nop", "!i"() #3 + to label %asm.fallthrough [label %cold_asm_target] + +asm.fallthrough: + br label %cold_asm_target + +cold_asm_target: + %3 = call i32 @baz() + ret void +} + declare i32 @bar() declare i32 @baz() declare i32 @bam()