Author: Amy Huang Date: 2024-07-08T12:59:02-07:00 New Revision: ae7ab043f2d8077ed00bb2d3239da4b96ad4b387
URL: https://github.com/llvm/llvm-project/commit/ae7ab043f2d8077ed00bb2d3239da4b96ad4b387 DIFF: https://github.com/llvm/llvm-project/commit/ae7ab043f2d8077ed00bb2d3239da4b96ad4b387.diff LOG: Add __hlt intrinsic for Windows ARM. (#96578) Add __hlt, which is a MSVC ARM64 intrinsic. This intrinsic is just the HLT instruction. MSVC's version seems to return something undefined; in this patch it will just return zero. MSVC intrinsics are defined here https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics. I used unsigned int as the return type, because that is what the MSVC intrin.h header uses, even though it conflicts with the documentation. Added: llvm/test/CodeGen/AArch64/arm64-hlt.ll Modified: clang/include/clang/Basic/BuiltinsAArch64.def clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Headers/intrin.h clang/lib/Sema/SemaARM.cpp clang/test/CodeGen/arm64-microsoft-intrinsics.c clang/test/Sema/builtins-microsoft-arm64.c llvm/include/llvm/IR/IntrinsicsAArch64.td llvm/lib/Target/AArch64/AArch64InstrInfo.td Removed: ################################################################################ diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 5fb199b1b2b032..36bd2b69dbbcb9 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -292,6 +292,8 @@ TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGE TARGET_HEADER_BUILTIN(__prefetch, "vvC*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__hlt, "UiUi.", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN #undef TARGET_BUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 268137b319f76f..6cc0d9485720c0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -11506,6 +11506,15 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(F, {Address, RW, Locality, Data}); } + if (BuiltinID == AArch64::BI__hlt) { + Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hlt); + Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0))}); + + // Return 0 for convenience, even though MSVC returns some other undefined + // value. + return ConstantInt::get(Builder.getInt32Ty(), 0); + } + // Handle MSVC intrinsics before argument evaluation to prevent double // evaluation. if (std::optional<MSVCIntrin> MsvcIntId = diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index d2250926ce5e10..6308c865ca9136 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -408,7 +408,10 @@ unsigned int _CountLeadingSigns64(__int64); unsigned int _CountOneBits(unsigned long); unsigned int _CountOneBits64(unsigned __int64); +unsigned int __hlt(unsigned int, ...); + void __cdecl __prefetch(const void *); + #endif /*----------------------------------------------------------------------------*\ diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index 281d5341520547..370db341e997ec 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -1112,6 +1112,9 @@ bool SemaARM::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, if (BuiltinID == AArch64::BI__break) return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 0xffff); + if (BuiltinID == AArch64::BI__hlt) + return SemaRef.BuiltinConstantArgRange(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 a354ed948ca5f1..7953618d2f9d13 100644 --- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c +++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c @@ -127,6 +127,15 @@ void check__break() { // CHECK-MSVC: call void @llvm.aarch64.break(i32 0) // CHECK-LINUX: error: call to undeclared function '__break' +void check__hlt() { + __hlt(0); + __hlt(1, 2, 3, 4, 5); + int x = __hlt(0); +} + +// CHECK-MSVC: call void @llvm.aarch64.hlt(i32 0) +// CHECK-LINUX: error: call to undeclared function '__hlt' + 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 6d0dc09c9ed83f..322cf7542f43a6 100644 --- a/clang/test/Sema/builtins-microsoft-arm64.c +++ b/clang/test/Sema/builtins-microsoft-arm64.c @@ -9,6 +9,11 @@ void check__break(int x) { __break(x); // expected-error {{argument to '__break' must be a constant integer}} } +void check__hlt() { + __hlt(-1); // expected-error-re {{argument value {{.*}} is outside the valid range}} + __hlt(65536); // expected-error-re {{argument value {{.*}} is outside the valid range}} +} + 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 6f3694cf952d47..65e3403fbf1524 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -57,6 +57,7 @@ def int_aarch64_frint64x : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ], [ LLVMMatchType<0> ], [ IntrNoMem ]>; + //===----------------------------------------------------------------------===// // HINT @@ -65,6 +66,8 @@ def int_aarch64_hint : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>; def int_aarch64_break : Intrinsic<[], [llvm_i32_ty], [IntrNoMem, IntrHasSideEffects, IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>; +def int_aarch64_hlt : Intrinsic<[], [llvm_i32_ty], + [IntrNoMem, IntrHasSideEffects, IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>; def int_aarch64_prefetch : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 1e06d5fdc7562e..78c8bf1e323aba 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -3111,7 +3111,8 @@ def BRK : ExceptionGeneration<0b001, 0b00, "brk", def DCPS1 : ExceptionGeneration<0b101, 0b01, "dcps1">; def DCPS2 : ExceptionGeneration<0b101, 0b10, "dcps2">; def DCPS3 : ExceptionGeneration<0b101, 0b11, "dcps3">, Requires<[HasEL3]>; -def HLT : ExceptionGeneration<0b010, 0b00, "hlt">; +def HLT : ExceptionGeneration<0b010, 0b00, "hlt", + [(int_aarch64_hlt timm32_0_65535:$imm)]>; def HVC : ExceptionGeneration<0b000, 0b10, "hvc">; def SMC : ExceptionGeneration<0b000, 0b11, "smc">, Requires<[HasEL3]>; def SVC : ExceptionGeneration<0b000, 0b01, "svc">; diff --git a/llvm/test/CodeGen/AArch64/arm64-hlt.ll b/llvm/test/CodeGen/AArch64/arm64-hlt.ll new file mode 100644 index 00000000000000..b16d9a0426f0d4 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-hlt.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s + +define void @foo() nounwind { +; CHECK-LABEL: foo +; CHECK: hlt #0x2 + tail call void @llvm.aarch64.hlt(i32 2) + ret void +} + +declare void @llvm.aarch64.hlt(i32 immarg) nounwind _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits