[clang] [llvm] Add __hlt intrinsic for Windows ARM. (PR #96578)
Amy Huang via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 26 11:27:28 PDT 2024
https://github.com/amykhuang updated https://github.com/llvm/llvm-project/pull/96578
>From 1b436900146e1a91efac95416077485571722517 Mon Sep 17 00:00:00 2001
From: Amy Huang <akhuang at google.com>
Date: Mon, 24 Jun 2024 16:55:08 -0700
Subject: [PATCH 1/2] Add __hlt intrinsic for Windows ARM.
---
clang/include/clang/Basic/BuiltinsAArch64.def | 1 +
clang/lib/CodeGen/CGBuiltin.cpp | 5 +++++
clang/lib/Headers/intrin.h | 3 +++
clang/test/CodeGen/arm64-microsoft-intrinsics.c | 7 +++++++
llvm/include/llvm/IR/IntrinsicsAArch64.td | 3 +++
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 3 ++-
llvm/test/CodeGen/AArch64/arm64-hlt.ll | 10 ++++++++++
7 files changed, 31 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AArch64/arm64-hlt.ll
diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def
index 5f53c98167dfb..668c4296208de 100644
--- a/clang/include/clang/Basic/BuiltinsAArch64.def
+++ b/clang/include/clang/Basic/BuiltinsAArch64.def
@@ -291,6 +291,7 @@ TARGET_HEADER_BUILTIN(_CountOneBits, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES,
TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__prefetch, "vvC*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__hlt, "iUi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 08a89bd123d03..c646614333499 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -11475,6 +11475,11 @@ 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);
+ return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(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 1227f45d5432b..a8a3463a78494 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -397,7 +397,10 @@ unsigned int _CountLeadingSigns64(__int64);
unsigned int _CountOneBits(unsigned long);
unsigned int _CountOneBits64(unsigned __int64);
+int __hlt(unsigned int);
+
void __cdecl __prefetch(const void *);
+
#endif
/*----------------------------------------------------------------------------*\
diff --git a/clang/test/CodeGen/arm64-microsoft-intrinsics.c b/clang/test/CodeGen/arm64-microsoft-intrinsics.c
index a354ed948ca5f..5d17cc1ca6162 100644
--- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c
+++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -127,6 +127,13 @@ 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);
+}
+
+// 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/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index 9a71aaa9f4434..d7c3189280de7 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 91e5bc3caa102..f4434525afecc 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -3076,7 +3076,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 0000000000000..b16d9a0426f0d
--- /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
>From f5ae6094aa9e67b36dde86fbb0b462fab0c76772 Mon Sep 17 00:00:00 2001
From: Amy Huang <akhuang at google.com>
Date: Wed, 26 Jun 2024 11:26:48 -0700
Subject: [PATCH 2/2] Updates
---
clang/include/clang/Basic/BuiltinsAArch64.def | 3 ++-
clang/lib/CodeGen/CGBuiltin.cpp | 6 +++++-
clang/lib/Headers/intrin.h | 2 +-
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def
index 668c4296208de..f7453847d049f 100644
--- a/clang/include/clang/Basic/BuiltinsAArch64.def
+++ b/clang/include/clang/Basic/BuiltinsAArch64.def
@@ -291,7 +291,8 @@ TARGET_HEADER_BUILTIN(_CountOneBits, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES,
TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(__prefetch, "vvC*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__hlt, "iUi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__hlt, "UiUi.", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c646614333499..22038489153cb 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -11477,7 +11477,11 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
if (BuiltinID == AArch64::BI__hlt) {
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hlt);
- return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0))});
+ 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
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index a8a3463a78494..dcc7c55b18770 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -397,7 +397,7 @@ unsigned int _CountLeadingSigns64(__int64);
unsigned int _CountOneBits(unsigned long);
unsigned int _CountOneBits64(unsigned __int64);
-int __hlt(unsigned int);
+unsigned int __hlt(unsigned int, ...);
void __cdecl __prefetch(const void *);
More information about the cfe-commits
mailing list