From 78dc38ec94229f38c5de74a8930eed623a27350e Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Tue, 5 Feb 2019 17:21:57 +0000 Subject: [PATCH] [AArch64][Outliner] Don't outline BTI instructions We can't outline BTI instructions, because they need to be the very first instruction executed after an indirect call or branch. If we outline them, then an indirect call might go to the branch to the outlined function, which will fault. Differential revision: https://reviews.llvm.org/D57753 llvm-svn: 353190 --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 8 ++++++++ .../AArch64/machine-outliner-outline-bti.ll | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 4996f1c..e2018ab 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5330,6 +5330,14 @@ AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT, MI.modifiesRegister(AArch64::W30, &getRegisterInfo())) return outliner::InstrType::Illegal; + // Don't outline BTI instructions, because that will prevent the outlining + // site from being indirectly callable. + if (MI.getOpcode() == AArch64::HINT) { + int64_t Imm = MI.getOperand(0).getImm(); + if (Imm == 32 || Imm == 34 || Imm == 36 || Imm == 38) + return outliner::InstrType::Illegal; + } + return outliner::InstrType::Legal; } diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll b/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll new file mode 100644 index 0000000..bc1521c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll @@ -0,0 +1,22 @@ +; RUN: llc -mtriple aarch64--none-eabi < %s | FileCheck %s + +; The BTI instruction cannot be outlined, because it needs to be the very first +; instruction executed after an indirect call. + +@g = hidden global i32 0, align 4 + +define hidden void @foo() minsize "branch-target-enforcement" { +entry: +; CHECK: hint #34 +; CHECK: b OUTLINED_FUNCTION_0 + store volatile i32 1, i32* @g, align 4 + ret void +} + +define hidden void @bar() minsize "branch-target-enforcement" { +entry: +; CHECK: hint #34 +; CHECK: b OUTLINED_FUNCTION_0 + store volatile i32 1, i32* @g, align 4 + ret void +} -- 2.7.4