-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[IR][ARM64EC] Fix setting of ARM64EC libcall names #144080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes llvm#142544, which incorrectly used #name in the `HANDLE_LIBCALL` macro. Since name is already a string, this led to extra quotes in the symbol name, resulting in calls like `b "#\"memcpy\""`. Some libcalls do not have an associated name and use nullptr instead. To handle these cases cleanly, introduce a new `HANDLE_NAMELESS_LIBCALL` macro that allows skipping them in the logic.
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-backend-aarch64 Author: Jacek Caban (cjacek) ChangesFixes #142544, which incorrectly used Some libcalls do not have an associated name and use nullptr instead. To handle these cases cleanly, introduce a new Full diff: https://github.com/llvm/llvm-project/pull/144080.diff 3 Files Affected:
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index 4ddae8e48193f..45c9d2acb649b 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -29,6 +29,10 @@
#error "HANDLE_LIBCALL must be defined"
#endif
+#ifndef HANDLE_NAMELESS_LIBCALL
+#define HANDLE_NAMELESS_LIBCALL(code) HANDLE_LIBCALL(code, nullptr)
+#endif
+
// Integer
HANDLE_LIBCALL(SHL_I16, "__ashlhi3")
HANDLE_LIBCALL(SHL_I32, "__ashlsi3")
@@ -70,16 +74,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_NAMELESS_LIBCALL(SDIVREM_I8)
+HANDLE_NAMELESS_LIBCALL(SDIVREM_I16)
+HANDLE_NAMELESS_LIBCALL(SDIVREM_I32)
+HANDLE_NAMELESS_LIBCALL(SDIVREM_I64)
+HANDLE_NAMELESS_LIBCALL(SDIVREM_I128)
+HANDLE_NAMELESS_LIBCALL(UDIVREM_I8)
+HANDLE_NAMELESS_LIBCALL(UDIVREM_I16)
+HANDLE_NAMELESS_LIBCALL(UDIVREM_I32)
+HANDLE_NAMELESS_LIBCALL(UDIVREM_I64)
+HANDLE_NAMELESS_LIBCALL(UDIVREM_I128)
HANDLE_LIBCALL(NEG_I32, "__negsi2")
HANDLE_LIBCALL(NEG_I64, "__negdi2")
HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
@@ -240,13 +244,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_NAMELESS_LIBCALL(SINCOS_F32)
+HANDLE_NAMELESS_LIBCALL(SINCOS_F64)
+HANDLE_NAMELESS_LIBCALL(SINCOS_F80)
+HANDLE_NAMELESS_LIBCALL(SINCOS_F128)
+HANDLE_NAMELESS_LIBCALL(SINCOS_PPCF128)
+HANDLE_NAMELESS_LIBCALL(SINCOS_STRET_F32)
+HANDLE_NAMELESS_LIBCALL(SINCOS_STRET_F64)
HANDLE_LIBCALL(POW_F32, "powf")
HANDLE_LIBCALL(POW_F64, "pow")
HANDLE_LIBCALL(POW_F80, "powl")
@@ -518,7 +522,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_NAMELESS_LIBCALL(BZERO)
// Element-wise unordered-atomic memory of different sizes
HANDLE_LIBCALL(MEMCPY_ELEMENT_UNORDERED_ATOMIC_1, "__llvm_memcpy_element_unordered_atomic_1")
@@ -669,10 +673,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_NAMELESS_LIBCALL(A##N##_RELAX) \
+ HANDLE_NAMELESS_LIBCALL(A##N##_ACQ) \
+ HANDLE_NAMELESS_LIBCALL(A##N##_REL) \
+ HANDLE_NAMELESS_LIBCALL(A##N##_ACQ_REL)
#define HLCALL5(A) \
HLCALLS(A, 1) HLCALLS(A, 2) HLCALLS(A, 4) HLCALLS(A, 8) HLCALLS(A, 16)
HLCALL5(OUTLINE_ATOMIC_CAS)
@@ -691,11 +695,12 @@ HANDLE_LIBCALL(STACKPROTECTOR_CHECK_FAIL, "__stack_chk_fail")
HANDLE_LIBCALL(DEOPTIMIZE, "__llvm_deoptimize")
// Return address
-HANDLE_LIBCALL(RETURN_ADDRESS, nullptr)
+HANDLE_NAMELESS_LIBCALL(RETURN_ADDRESS)
// Clear cache
HANDLE_LIBCALL(CLEAR_CACHE, "__clear_cache")
HANDLE_LIBCALL(RISCV_FLUSH_ICACHE, "__riscv_flush_icache")
-HANDLE_LIBCALL(UNKNOWN_LIBCALL, nullptr)
+HANDLE_NAMELESS_LIBCALL(UNKNOWN_LIBCALL)
+#undef HANDLE_NAMELESS_LIBCALL
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index d84c56f0af5c6..6031f7ba85faa 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -24,8 +24,9 @@ static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info,
{ \
const char *libcallName = Info.getLibcallName(RTLIB::code); \
if (libcallName && libcallName[0] != '#') \
- Info.setLibcallName(RTLIB::code, "#" #name); \
+ Info.setLibcallName(RTLIB::code, "#" name); \
}
+#define HANDLE_NAMELESS_LIBCALL(code)
#include "llvm/IR/RuntimeLibcalls.def"
#undef HANDLE_LIBCALL
}
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-libcalls.ll b/llvm/test/CodeGen/AArch64/arm64ec-libcalls.ll
new file mode 100644
index 0000000000000..a109a60303a20
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64ec-libcalls.ll
@@ -0,0 +1,47 @@
+; RUN: llc -filetype asm -o - %s | FileCheck %s
+
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "arm64ec-unknown-windows-msvc19.33.0"
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
+define dso_local void @test_memcpy(ptr noundef writeonly captures(none) %0, ptr noundef readonly captures(none) %1, i64 noundef %2) local_unnamed_addr #0 {
+ tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 %0, ptr align 1 %1, i64 %2, i1 false)
+; CHECK: b "#memcpy"
+ ret void
+}
+
+; Function Attrs: mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #1
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable
+define dso_local void @test_memmove(ptr noundef writeonly captures(none) %0, ptr noundef readonly captures(none) %1, i64 noundef %2) local_unnamed_addr #0 {
+ tail call void @llvm.memmove.p0.p0.i64(ptr align 1 %0, ptr align 1 %1, i64 %2, i1 false)
+; CHECK: b "#memmove"
+ret void
+}
+
+; Function Attrs: mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memmove.p0.p0.i64(ptr writeonly captures(none), ptr readonly captures(none), i64, i1 immarg) #1
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) uwtable
+define dso_local void @test_memset(ptr noundef writeonly captures(none) %0, i64 noundef %1) local_unnamed_addr #2 {
+ tail call void @llvm.memset.p0.i64(ptr align 1 %0, i8 0, i64 %1, i1 false)
+; CHECK: b "#memset"
+ ret void
+}
+
+; Function Attrs: mustprogress nocallback nofree nounwind willreturn memory(argmem: write)
+declare void @llvm.memset.p0.i64(ptr writeonly captures(none), i8, i64, i1 immarg) #3
+
+attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
+attributes #1 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+attributes #2 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) uwtable "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
+attributes #3 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: write) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 2}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"uwtable", i32 2}
+!3 = !{!"clang version 21.0.0git"}
|
It's addressed by #143977, closing. |
Fixes #142544, which incorrectly used
#name
in theHANDLE_LIBCALL
macro. Since name is already a string, this led to extra quotes in the symbol name, resulting in calls likeb "#\"memcpy\""
.Some libcalls do not have an associated name and use nullptr instead. To handle these cases cleanly, introduce a new
HANDLE_NAMELESS_LIBCALL
macro that allows skipping them in the logic.