summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Tan <Tom.Tan@microsoft.com>2019-06-21 23:38:05 +0000
committerTom Tan <Tom.Tan@microsoft.com>2019-06-21 23:38:05 +0000
commit7ecb5145bae57fce44c53f3e8eacea76078e3825 (patch)
tree9f664fe9f45471f1a87c438fab1b6665d294c1db
parent51a741c87fa8f87c8b37015dac4bce2b10d1ce81 (diff)
downloadbcm5719-llvm-7ecb5145bae57fce44c53f3e8eacea76078e3825.tar.gz
bcm5719-llvm-7ecb5145bae57fce44c53f3e8eacea76078e3825.zip
[COFF, ARM64] Fix encoding of debugtrap for Windows
On Windows ARM64, intrinsic __debugbreak is compiled into brk #0xF000 which is mapped to llvm.debugtrap in Clang. Instruction brk #F000 is the defined break point instruction on ARM64 which is recognized by Windows debugger and exception handling code, so llvm.debugtrap should map to it instead of redirecting to llvm.trap (brk #1) as the default implementation. Differential Revision: https://reviews.llvm.org/D63635 llvm-svn: 364115
-rw-r--r--llvm/lib/Target/AArch64/AArch64FastISel.cpp8
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp2
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td2
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp5
-rw-r--r--llvm/test/CodeGen/AArch64/windows-trap1.ll13
5 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index 8b033ee6376..91194611179 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -3604,6 +3604,14 @@ bool AArch64FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
.addImm(1);
return true;
+ case Intrinsic::debugtrap: {
+ if (Subtarget->isTargetWindows()) {
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::BRK))
+ .addImm(0xF000);
+ return true;
+ }
+ break;
+ }
case Intrinsic::sqrt: {
Type *RetTy = II->getCalledFunction()->getReturnType();
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 60032cd797a..515da93cded 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -551,6 +551,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
// Trap.
setOperationAction(ISD::TRAP, MVT::Other, Legal);
+ if (Subtarget->isTargetWindows())
+ setOperationAction(ISD::DEBUGTRAP, MVT::Other, Legal);
// We combine OR nodes for bitfield operations.
setTargetDAGCombine(ISD::OR);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 9c19e3cdf51..41497a6c4fb 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -135,6 +135,7 @@ def HasMTE : Predicate<"Subtarget->hasMTE()">,
AssemblerPredicate<"FeatureMTE", "mte">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
+def IsWindows : Predicate<"Subtarget->isTargetWindows()">;
def UseAlternateSExtLoadCVTF32
: Predicate<"Subtarget->useAlternateSExtLoadCVTF32Pattern()">;
@@ -6116,6 +6117,7 @@ def : Pat<(i32 (trunc GPR64sp:$src)),
// __builtin_trap() uses the BRK instruction on AArch64.
def : Pat<(trap), (BRK 1)>;
+def : Pat<(debugtrap), (BRK 0xF000)>, Requires<[IsWindows]>;
// Multiply high patterns which multiply the lower subvector using smull/umull
// and the upper subvector with smull2/umull2. Then shuffle the high the high
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 03e2da68c4b..415664a1f74 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -3525,6 +3525,11 @@ bool AArch64InstructionSelector::selectIntrinsicWithSideEffects(
case Intrinsic::trap:
MIRBuilder.buildInstr(AArch64::BRK, {}, {}).addImm(1);
break;
+ case Intrinsic::debugtrap:
+ if (!STI.isTargetWindows())
+ return false;
+ MIRBuilder.buildInstr(AArch64::BRK, {}, {}).addImm(0xF000);
+ break;
case Intrinsic::aarch64_stlxr:
unsigned StatReg = I.getOperand(0).getReg();
assert(RBI.getSizeInBits(StatReg, MRI, TRI) == 32 &&
diff --git a/llvm/test/CodeGen/AArch64/windows-trap1.ll b/llvm/test/CodeGen/AArch64/windows-trap1.ll
new file mode 100644
index 00000000000..6f6fa3a6609
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/windows-trap1.ll
@@ -0,0 +1,13 @@
+; RUN: llc -mtriple=aarch64-windows %s -o -| FileCheck %s
+; RUN: llc -mtriple=aarch64-windows -fast-isel %s -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-windows -global-isel %s -o - | FileCheck %s
+
+; CHECK-LABEL: test1:
+; CHECK: brk #0xf000
+define void @test1() noreturn nounwind {
+entry:
+ tail call void @llvm.debugtrap( )
+ ret void
+}
+
+declare void @llvm.debugtrap() nounwind
OpenPOWER on IntegriCloud