diff options
author | Pengxuan Zheng <pzheng@quicinc.com> | 2022-04-15 14:57:40 -0700 |
---|---|---|
committer | Pengxuan Zheng <pzheng@quicinc.com> | 2022-04-20 11:20:26 -0700 |
commit | 8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05 (patch) | |
tree | ddd7c03307a53bd4e51ac087d0aba1b336ebce9a | |
parent | c79e6007edef4b0044be93c4ffff64dc806ac687 (diff) | |
download | llvm-8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.zip llvm-8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.tar.gz llvm-8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.tar.bz2 |
[COFF, ARM64] Add __break intrinsic
https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170
Reviewed By: rnk, mstorsjo
Differential Revision: https://reviews.llvm.org/D124032
-rw-r--r-- | clang/include/clang/Basic/BuiltinsAArch64.def | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Headers/intrin.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/arm64-microsoft-intrinsics.c | 7 | ||||
-rw-r--r-- | clang/test/Sema/builtins-microsoft-arm64.c | 6 | ||||
-rw-r--r-- | llvm/include/llvm/IR/IntrinsicsAArch64.td | 3 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrFormats.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 3 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/arm64-break.ll | 10 |
10 files changed, 47 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 0869b87..cebd1c0 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -249,6 +249,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LA TARGET_HEADER_BUILTIN(__mulh, "SLLiSLLiSLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__break, "vi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN #undef TARGET_HEADER_BUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 464dcc2..fc2d32f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -9823,6 +9823,15 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F, Metadata); } + if (BuiltinID == AArch64::BI__break) { + Expr::EvalResult Result; + if (!E->getArg(0)->EvaluateAsInt(Result, CGM.getContext())) + llvm_unreachable("Sema will ensure that the parameter is constant"); + + llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::aarch64_break); + return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0))}); + } + if (BuiltinID == AArch64::BI__builtin_arm_clrex) { Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex); return Builder.CreateCall(F); diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index 741b21e..07fcae3 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -560,6 +560,8 @@ unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val); __int64 __mulh(__int64 __a, __int64 __b); unsigned __int64 __umulh(unsigned __int64 __a, unsigned __int64 __b); + +void __break(int); #endif /*----------------------------------------------------------------------------*\ diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f575c07..467edd3 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2948,6 +2948,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, if (BuiltinID == AArch64::BI__getReg) return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31); + if (BuiltinID == AArch64::BI__break) + return SemaBuiltinConstantArgRange(TheCall, 0, 0, 0xffff); + if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) return true; diff --git a/clang/test/CodeGen/arm64-microsoft-intrinsics.c b/clang/test/CodeGen/arm64-microsoft-intrinsics.c index 2dd2f6c..044a6a1 100644 --- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c +++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c @@ -103,6 +103,13 @@ unsigned long long check_umulh(unsigned long long a, unsigned long long b) { // CHECK-MSVC: %[[RES:.*]] = trunc i128 %[[HIGH]] to i64 // CHECK-LINUX: error: call to undeclared function '__umulh' +void check__break() { + __break(0); +} + +// CHECK-MSVC: call void @llvm.aarch64.break(i32 0) +// CHECK-LINUX: error: implicit declaration of function '__break' + unsigned __int64 check__getReg(void) { unsigned volatile __int64 reg; reg = __getReg(18); diff --git a/clang/test/Sema/builtins-microsoft-arm64.c b/clang/test/Sema/builtins-microsoft-arm64.c index 3b5bd9b..6d0dc09 100644 --- a/clang/test/Sema/builtins-microsoft-arm64.c +++ b/clang/test/Sema/builtins-microsoft-arm64.c @@ -3,6 +3,12 @@ #include <intrin.h> +void check__break(int x) { + __break(-1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + __break(65536); // expected-error-re {{argument value {{.*}} is outside the valid range}} + __break(x); // expected-error {{argument to '__break' must be a constant integer}} +} + void check__getReg(void) { __getReg(-1); // expected-error-re {{argument value {{.*}} is outside the valid range}} __getReg(32); // expected-error-re {{argument value {{.*}} is outside the valid range}} diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index a65ddff..3032254 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -62,6 +62,9 @@ def int_aarch64_frint64x def int_aarch64_hint : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>; +def int_aarch64_break : Intrinsic<[], [llvm_i32_ty], + [IntrNoMem, IntrHasSideEffects, IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>; + //===----------------------------------------------------------------------===// // Data Barrier Instructions diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index e7d37c3..37928aa 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -4529,8 +4529,9 @@ multiclass MemTagStore<bits<2> opc1, string insn> { //--- let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in -class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm> - : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", []>, +class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm, + list<dag> pattern = []> + : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>, Sched<[WriteSys]> { bits<16> imm; let Inst{31-24} = 0b11010100; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index d626bf8..baf6b5e 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2432,7 +2432,8 @@ def : Pat<(AArch64call texternalsym:$func), (BL texternalsym:$func)>; // Exception generation instructions. //===----------------------------------------------------------------------===// let isTrap = 1 in { -def BRK : ExceptionGeneration<0b001, 0b00, "brk">; +def BRK : ExceptionGeneration<0b001, 0b00, "brk", + [(int_aarch64_break timm32_0_65535:$imm)]>; } def DCPS1 : ExceptionGeneration<0b101, 0b01, "dcps1">; def DCPS2 : ExceptionGeneration<0b101, 0b10, "dcps2">; diff --git a/llvm/test/CodeGen/AArch64/arm64-break.ll b/llvm/test/CodeGen/AArch64/arm64-break.ll new file mode 100644 index 0000000..3b8b14b --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-break.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s + +define void @foo() nounwind { +; CHECK-LABEL: foo +; CHECK: brk #0x2 + tail call void @llvm.aarch64.break(i32 2) + ret void +} + +declare void @llvm.aarch64.break(i32 immarg) nounwind |