[llvm] [aarch64] Fix Arm64EC libcall lowering after recent refactoring. (PR #143977)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 12 14:37:00 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Eli Friedman (efriedma-quic)
<details>
<summary>Changes</summary>
The refactored code accidentally tokenized a string instead of just concatenating it.
Add a regression test and some assertions to ensure consistency.
Fixes #<!-- -->143890 .
---
Full diff: https://github.com/llvm/llvm-project/pull/143977.diff
4 Files Affected:
- (modified) llvm/include/llvm/IR/RuntimeLibcalls.def (+24-24)
- (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+11-4)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp (+2)
- (added) llvm/test/CodeGen/AArch64/arm64ec-builtins.ll (+31)
``````````diff
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index 4ddae8e48193f..247643525ff48 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -70,16 +70,16 @@ HANDLE_LIBCALL(UREM_I16, "__umodhi3")
HANDLE_LIBCALL(UREM_I32, "__umodsi3")
HANDLE_LIBCALL(UREM_I64, "__umoddi3")
HANDLE_LIBCALL(UREM_I128, "__umodti3")
-HANDLE_LIBCALL(SDIVREM_I8, nullptr)
-HANDLE_LIBCALL(SDIVREM_I16, nullptr)
-HANDLE_LIBCALL(SDIVREM_I32, nullptr)
-HANDLE_LIBCALL(SDIVREM_I64, nullptr)
-HANDLE_LIBCALL(SDIVREM_I128, nullptr)
-HANDLE_LIBCALL(UDIVREM_I8, nullptr)
-HANDLE_LIBCALL(UDIVREM_I16, nullptr)
-HANDLE_LIBCALL(UDIVREM_I32, nullptr)
-HANDLE_LIBCALL(UDIVREM_I64, nullptr)
-HANDLE_LIBCALL(UDIVREM_I128, nullptr)
+HANDLE_LIBCALL(SDIVREM_I8, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SDIVREM_I16, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SDIVREM_I32, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SDIVREM_I64, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SDIVREM_I128, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(UDIVREM_I8, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(UDIVREM_I16, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(UDIVREM_I32, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(UDIVREM_I64, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(UDIVREM_I128, LIBCALL_NO_NAME)
HANDLE_LIBCALL(NEG_I32, "__negsi2")
HANDLE_LIBCALL(NEG_I64, "__negdi2")
HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
@@ -240,13 +240,13 @@ HANDLE_LIBCALL(ATAN2_F64, "atan2")
HANDLE_LIBCALL(ATAN2_F80, "atan2l")
HANDLE_LIBCALL(ATAN2_F128,"atan2l")
HANDLE_LIBCALL(ATAN2_PPCF128, "atan2l")
-HANDLE_LIBCALL(SINCOS_F32, nullptr)
-HANDLE_LIBCALL(SINCOS_F64, nullptr)
-HANDLE_LIBCALL(SINCOS_F80, nullptr)
-HANDLE_LIBCALL(SINCOS_F128, nullptr)
-HANDLE_LIBCALL(SINCOS_PPCF128, nullptr)
-HANDLE_LIBCALL(SINCOS_STRET_F32, nullptr)
-HANDLE_LIBCALL(SINCOS_STRET_F64, nullptr)
+HANDLE_LIBCALL(SINCOS_F32, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SINCOS_F64, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SINCOS_F80, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SINCOS_F128, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SINCOS_PPCF128, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SINCOS_STRET_F32, LIBCALL_NO_NAME)
+HANDLE_LIBCALL(SINCOS_STRET_F64, LIBCALL_NO_NAME)
HANDLE_LIBCALL(POW_F32, "powf")
HANDLE_LIBCALL(POW_F64, "pow")
HANDLE_LIBCALL(POW_F80, "powl")
@@ -518,7 +518,7 @@ HANDLE_LIBCALL(MEMMOVE, "memmove")
HANDLE_LIBCALL(MEMSET, "memset")
// DSEPass can emit calloc if it finds a pair of malloc/memset
HANDLE_LIBCALL(CALLOC, "calloc")
-HANDLE_LIBCALL(BZERO, nullptr)
+HANDLE_LIBCALL(BZERO, LIBCALL_NO_NAME)
// Element-wise unordered-atomic memory of different sizes
HANDLE_LIBCALL(MEMCPY_ELEMENT_UNORDERED_ATOMIC_1, "__llvm_memcpy_element_unordered_atomic_1")
@@ -669,10 +669,10 @@ HANDLE_LIBCALL(ATOMIC_FETCH_NAND_16, "__atomic_fetch_nand_16")
// Out-of-line atomics libcalls
#define HLCALLS(A, N) \
- HANDLE_LIBCALL(A##N##_RELAX, nullptr) \
- HANDLE_LIBCALL(A##N##_ACQ, nullptr) \
- HANDLE_LIBCALL(A##N##_REL, nullptr) \
- HANDLE_LIBCALL(A##N##_ACQ_REL, nullptr)
+ HANDLE_LIBCALL(A##N##_RELAX, LIBCALL_NO_NAME) \
+ HANDLE_LIBCALL(A##N##_ACQ, LIBCALL_NO_NAME) \
+ HANDLE_LIBCALL(A##N##_REL, LIBCALL_NO_NAME) \
+ HANDLE_LIBCALL(A##N##_ACQ_REL, LIBCALL_NO_NAME)
#define HLCALL5(A) \
HLCALLS(A, 1) HLCALLS(A, 2) HLCALLS(A, 4) HLCALLS(A, 8) HLCALLS(A, 16)
HLCALL5(OUTLINE_ATOMIC_CAS)
@@ -691,11 +691,11 @@ HANDLE_LIBCALL(STACKPROTECTOR_CHECK_FAIL, "__stack_chk_fail")
HANDLE_LIBCALL(DEOPTIMIZE, "__llvm_deoptimize")
// Return address
-HANDLE_LIBCALL(RETURN_ADDRESS, nullptr)
+HANDLE_LIBCALL(RETURN_ADDRESS, LIBCALL_NO_NAME)
// Clear cache
HANDLE_LIBCALL(CLEAR_CACHE, "__clear_cache")
HANDLE_LIBCALL(RISCV_FLUSH_ICACHE, "__riscv_flush_icache")
-HANDLE_LIBCALL(UNKNOWN_LIBCALL, nullptr)
+HANDLE_LIBCALL(UNKNOWN_LIBCALL, LIBCALL_NO_NAME)
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index d84c56f0af5c6..5cce688595b94 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -21,13 +21,17 @@ static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info,
if (TT.isWindowsArm64EC()) {
// FIXME: are there calls we need to exclude from this?
#define HANDLE_LIBCALL(code, name) \
- { \
+ if (sizeof(name) != 1) { \
const char *libcallName = Info.getLibcallName(RTLIB::code); \
- if (libcallName && libcallName[0] != '#') \
- Info.setLibcallName(RTLIB::code, "#" #name); \
+ if (libcallName && libcallName[0] != '#') { \
+ assert(strcmp(libcallName, name) == 0 && "Unexpected name"); \
+ Info.setLibcallName(RTLIB::code, "#" name); \
+ } \
}
+#define LIBCALL_NO_NAME ""
#include "llvm/IR/RuntimeLibcalls.def"
#undef HANDLE_LIBCALL
+#undef LIBCALL_NO_NAME
}
}
@@ -223,8 +227,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
nullptr);
#define HANDLE_LIBCALL(code, name) setLibcallName(RTLIB::code, name);
+#define LIBCALL_NO_NAME nullptr
#include "llvm/IR/RuntimeLibcalls.def"
#undef HANDLE_LIBCALL
+#undef LIBCALL_NO_NAME
// Initialize calling conventions to their default.
for (int LC = 0; LC < RTLIB::UNKNOWN_LIBCALL; ++LC)
@@ -462,7 +468,8 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
}
// Setup Windows compiler runtime calls.
- if (TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment()) {
+ if (TT.getArch() == Triple::x86 &&
+ (TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment())) {
static const struct {
const RTLIB::Libcall Op;
const char *const Name;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
index ce795d3dedc6a..d5c4532824c07 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
@@ -531,8 +531,10 @@ struct StaticLibcallNameMap {
StaticLibcallNameMap() {
static const std::pair<const char *, RTLIB::Libcall> NameLibcalls[] = {
#define HANDLE_LIBCALL(code, name) {(const char *)name, RTLIB::code},
+#define LIBCALL_NO_NAME nullptr
#include "llvm/IR/RuntimeLibcalls.def"
#undef HANDLE_LIBCALL
+#undef LIBCALL_NO_NAME
};
for (const auto &NameLibcall : NameLibcalls) {
if (NameLibcall.first != nullptr &&
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-builtins.ll b/llvm/test/CodeGen/AArch64/arm64ec-builtins.ll
new file mode 100644
index 0000000000000..60b4bf7f39dd8
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64ec-builtins.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s
+
+define void @f1(ptr %p, i64 %n) {
+; CHECK-LABEL: "#f1":
+; CHECK: bl "#memset"
+ call void @llvm.memset.p0.i64(ptr %p, i8 0, i64 %n, i1 false)
+ ret void
+}
+
+define void @f2(ptr %p1, ptr %p2, i64 %n) {
+; CHECK-LABEL: "#f2":
+; CHECK: bl "#memcpy"
+ call void @llvm.memcpy.p0.i64(ptr %p1, ptr %p2, i64 %n, i1 false)
+ ret void
+}
+
+define double @f3(double %x, double %y) {
+; CHECK-LABEL: "#f3":
+; CHECK: b "#fmod"
+ %r = frem double %x, %y
+ ret double %r
+}
+
+
+define i128 @f4(i128 %x, i128 %y) {
+; CHECK-LABEL: "#f4":
+; CHECK: bl "#__divti3"
+ %r = sdiv i128 %x, %y
+ ret i128 %r
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/143977
More information about the llvm-commits
mailing list