]> granicus.if.org Git - llvm/commitdiff
[COFF, ARM64] Fix encoding of debugtrap for Windows
authorTom Tan <Tom.Tan@microsoft.com>
Fri, 21 Jun 2019 23:38:05 +0000 (23:38 +0000)
committerTom Tan <Tom.Tan@microsoft.com>
Fri, 21 Jun 2019 23:38:05 +0000 (23:38 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364115 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64FastISel.cpp
lib/Target/AArch64/AArch64ISelLowering.cpp
lib/Target/AArch64/AArch64InstrInfo.td
lib/Target/AArch64/AArch64InstructionSelector.cpp
test/CodeGen/AArch64/windows-trap1.ll [new file with mode: 0644]

index 8b033ee63766077334de2153ee2abf54a6d1902b..911946111791be9bf0f60175a778d5659c551f81 100644 (file)
@@ -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();
index 60032cd797ae5296bdae049342d0baacc1b7e772..515da93cded089f1c15af4ff05f80bfc6dd64e3b 100644 (file)
@@ -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);
index 9c19e3cdf512d879024c8c032caded3aa66136ad..41497a6c4fbc078952e410245b83481daa6fe3d4 100644 (file)
@@ -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
index 03e2da68c4b5f4e87609f61e25fd5cac7db3ef46..415664a1f7443c93674597dd0fabeae0ab1583f4 100644 (file)
@@ -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/test/CodeGen/AArch64/windows-trap1.ll b/test/CodeGen/AArch64/windows-trap1.ll
new file mode 100644 (file)
index 0000000..6f6fa3a
--- /dev/null
@@ -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