Index: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp @@ -3604,6 +3604,14 @@ 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: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -551,6 +551,8 @@ // 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: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td @@ -135,6 +135,7 @@ 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 @@ // __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: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -3525,6 +3525,11 @@ 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 && Index: llvm/trunk/test/CodeGen/AArch64/windows-trap1.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/windows-trap1.ll +++ llvm/trunk/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