Skip to content

[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

Closed
wants to merge 1 commit into from

Conversation

cjacek
Copy link
Contributor

@cjacek cjacek commented Jun 13, 2025

Fixes #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.

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.
@llvmbot
Copy link
Member

llvmbot commented Jun 13, 2025

@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-backend-aarch64

Author: Jacek Caban (cjacek)

Changes

Fixes #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.


Full diff: https://github.com/llvm/llvm-project/pull/144080.diff

3 Files Affected:

  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.def (+29-24)
  • (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+2-1)
  • (added) llvm/test/CodeGen/AArch64/arm64ec-libcalls.ll (+47)
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"}

@cjacek
Copy link
Contributor Author

cjacek commented Jun 13, 2025

It's addressed by #143977, closing.

@cjacek cjacek closed this Jun 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants