[clang] ae7ab04 - Add __hlt intrinsic for Windows ARM. (#96578)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 8 12:59:08 PDT 2024
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
More information about the cfe-commits
mailing list