https://github.com/LucasChollet updated 
https://github.com/llvm/llvm-project/pull/201834

>From df9d6b85153b564e8c63e824a5f2a52d93554a1d Mon Sep 17 00:00:00 2001
From: Lucas Chollet <[email protected]>
Date: Fri, 5 Jun 2026 14:52:44 +0200
Subject: [PATCH 1/2] [clang] Add more test coverage for "zero-call-used-regs"

In clang, the main function is treated as a special case and no
"zero-call-used-regs" attributes are emitted for it. This patch adds
proper unit testing for that functionality.

AFAIU, treating `main` as a special case was initially implemented in
the backend. However, during review [1] the logic was moved to clang
while the associated test case was never updated (and then copied over
to the AArch64 test file).

[1] https://reviews.llvm.org/D110869
More specifically this comment: https://reviews.llvm.org/D110869#3285932
---
 clang/test/CodeGen/zero-call-used-regs.c      | 28 +++++++++++++++++++
 .../CodeGen/AArch64/zero-call-used-regs.ll    | 11 --------
 llvm/test/CodeGen/X86/zero-call-used-regs.ll  | 16 -----------
 3 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/clang/test/CodeGen/zero-call-used-regs.c 
b/clang/test/CodeGen/zero-call-used-regs.c
index 4437751ba7b31..86dd1bfa6ac63 100644
--- a/clang/test/CodeGen/zero-call-used-regs.c
+++ b/clang/test/CodeGen/zero-call-used-regs.c
@@ -20,6 +20,7 @@
 // CHECK-SKIP:               define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-SKIP:               define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-SKIP:               define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-SKIP:               define {{.*}} @main({{.*}} #[[ATTR_NUM]]
 //
 // CHECK-SKIP-NOT:           attributes #[[ATTR_NUM]] = {{.*}} 
"zero-call-used-regs"=
 // CHECK-SKIP:               attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -44,6 +45,7 @@
 // CHECK-USED-GPR-ARG:       define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-USED-GPR-ARG:       define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-USED-GPR-ARG:       define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-USED-GPR-ARG:       define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-USED-GPR-ARG:       attributes #[[ATTR_NUM_USED_GPR_ARG]] = {{.*}} 
"zero-call-used-regs"="used-gpr-arg"
 // CHECK-USED-GPR-ARG:       attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -54,6 +56,8 @@
 // CHECK-USED-GPR-ARG:       attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-USED-GPR-ARG:       attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-USED-GPR-ARG:       attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-USED-GPR-ARG:       attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-USED-GPR-ARG-NOT:   "zero-call-used-regs"=
 
 // -fzero-call-used-regs=used-gpr:
 //
@@ -67,6 +71,7 @@
 // CHECK-USED-GPR:           define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-USED-GPR:           define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-USED-GPR:           define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-USED-GPR:           define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-USED-GPR:           attributes #[[ATTR_NUM_USED_GPR]] = {{.*}} 
"zero-call-used-regs"="used-gpr"
 // CHECK-USED-GPR:           attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -77,6 +82,8 @@
 // CHECK-USED-GPR:           attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-USED-GPR:           attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-USED-GPR:           attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-USED-GPR:           attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-USED-GPR-NOT:       "zero-call-used-regs"=
 
 // -fzero-call-used-regs=used-arg:
 //
@@ -90,6 +97,7 @@
 // CHECK-USED-ARG:           define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-USED-ARG:           define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-USED-ARG:           define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-USED-ARG:           define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-USED-ARG:           attributes #[[ATTR_NUM_USED_ARG]] = {{.*}} 
"zero-call-used-regs"="used-arg"
 // CHECK-USED-ARG:           attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -100,6 +108,8 @@
 // CHECK-USED-ARG:           attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-USED-ARG:           attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-USED-ARG:           attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-USED-ARG:           attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-USED-ARG-NOT:       "zero-call-used-regs"=
 
 // -fzero-call-used-regs=used:
 //
@@ -113,6 +123,7 @@
 // CHECK-USED:               define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-USED:               define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-USED:               define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-USED:               define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-USED:               attributes #[[ATTR_NUM_USED]] = {{.*}} 
"zero-call-used-regs"="used"
 // CHECK-USED:               attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -123,6 +134,8 @@
 // CHECK-USED:               attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-USED:               attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-USED:               attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-USED:               attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-USED-NOT:           "zero-call-used-regs"=
 
 // -fzero-call-used-regs=all-gpr-arg:
 //
@@ -136,6 +149,7 @@
 // CHECK-ALL-GPR-ARG:        define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-ALL-GPR-ARG:        define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-ALL-GPR-ARG:        define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-ALL-GPR-ARG:        define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-ALL-GPR-ARG:        attributes #[[ATTR_NUM_ALL_GPR_ARG]] = {{.*}} 
"zero-call-used-regs"="all-gpr-arg"
 // CHECK-ALL-GPR-ARG:        attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -146,6 +160,8 @@
 // CHECK-ALL-GPR-ARG:        attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-ALL-GPR-ARG:        attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-ALL-GPR-ARG:        attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-ALL-GPR-ARG:        attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-ALL-GPR-ARG-NOT:    "zero-call-used-regs"=
 
 // -fzero-call-used-regs=all-gpr:
 //
@@ -159,6 +175,7 @@
 // CHECK-ALL-GPR:            define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR]]
 // CHECK-ALL-GPR:            define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-ALL-GPR:            define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-ALL-GPR:            define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-ALL-GPR:            attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-ALL-GPR:            attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -169,6 +186,8 @@
 // CHECK-ALL-GPR:            attributes #[[ATTR_NUM_ALL_GPR_ARG]] = {{.*}} 
"zero-call-used-regs"="all-gpr-arg"
 // CHECK-ALL-GPR:            attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-ALL-GPR:            attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-ALL-GPR:            attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-ALL-GPR-NOT:        "zero-call-used-regs"=
 
 // -fzero-call-used-regs=all-arg:
 //
@@ -182,6 +201,7 @@
 // CHECK-ALL-ARG:            define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-ALL-ARG:            define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG]]
 // CHECK-ALL-ARG:            define {{.*}} @all_test({{.*}} 
#[[ATTR_NUM_ALL:[0-9]*]]
+// CHECK-ALL-ARG:            define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-ALL-ARG:            attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
 // CHECK-ALL-ARG:            attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -192,6 +212,8 @@
 // CHECK-ALL-ARG:            attributes #[[ATTR_NUM_ALL_GPR_ARG]] = {{.*}} 
"zero-call-used-regs"="all-gpr-arg"
 // CHECK-ALL-ARG:            attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-ALL-ARG:            attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
+// CHECK-ALL-ARG:            attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-ALL-ARG-NOT:        "zero-call-used-regs"=
 
 // -fzero-call-used-regs=all:
 //
@@ -205,6 +227,7 @@
 // CHECK-ALL:                define {{.*}} @all_gpr_test({{.*}} 
#[[ATTR_NUM_ALL_GPR:[0-9]*]]
 // CHECK-ALL:                define {{.*}} @all_arg_test({{.*}} 
#[[ATTR_NUM_ALL_ARG:[0-9]*]]
 // CHECK-ALL:                define {{.*}} @all_test({{.*}} #[[ATTR_NUM_ALL]]
+// CHECK-ALL:                define {{.*}} @main({{.*}} 
#[[ATTR_NUM_MAIN:[0-9]*]]
 //
 // CHECK-ALL:                attributes #[[ATTR_NUM_ALL]] = {{.*}} 
"zero-call-used-regs"="all"
 // CHECK-ALL:                attributes #[[ATTR_NUM_SKIP]] = {{.*}} 
"zero-call-used-regs"="skip"
@@ -215,6 +238,8 @@
 // CHECK-ALL:                attributes #[[ATTR_NUM_ALL_GPR_ARG]] = {{.*}} 
"zero-call-used-regs"="all-gpr-arg"
 // CHECK-ALL:                attributes #[[ATTR_NUM_ALL_GPR]] = {{.*}} 
"zero-call-used-regs"="all-gpr"
 // CHECK-ALL:                attributes #[[ATTR_NUM_ALL_ARG]] = {{.*}} 
"zero-call-used-regs"="all-arg"
+// CHECK-ALL:                attributes #[[ATTR_NUM_MAIN]] =
+// CHECK-ALL-NOT:            "zero-call-used-regs"=
 
 #define __zero_call_used_regs(kind) __attribute__((zero_call_used_regs(kind)))
 
@@ -247,3 +272,6 @@ void __zero_call_used_regs("all-arg") all_arg_test(void) {
 
 void __zero_call_used_regs("all") all_test(void) {
 }
+
+int main() {
+}
diff --git a/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll 
b/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll
index 986666e015e9e..1a13270bf7856 100644
--- a/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll
+++ b/llvm/test/CodeGen/AArch64/zero-call-used-regs.ll
@@ -780,15 +780,4 @@ entry:
   ret double %mul
 }
 
-; Don't emit zeroing registers in "main" function.
-define dso_local i32 @main() local_unnamed_addr #0 {
-; CHECK-LABEL: main:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    mov w0, wzr
-; CHECK-NEXT:    ret
-
-entry:
-  ret i32 0
-}
-
 attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone 
willreturn uwtable "frame-pointer"="non-leaf" "min-legal-vector-width"="0" 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="generic" "target-features"="+neon,+v8a" }
diff --git a/llvm/test/CodeGen/X86/zero-call-used-regs.ll 
b/llvm/test/CodeGen/X86/zero-call-used-regs.ll
index 97ad5ce9c8cbb..84d71e2d57453 100644
--- a/llvm/test/CodeGen/X86/zero-call-used-regs.ll
+++ b/llvm/test/CodeGen/X86/zero-call-used-regs.ll
@@ -255,21 +255,5 @@ define dso_local void @tailcall(ptr %p) local_unnamed_addr 
#0 "zero-call-used-re
   ret void
 }
 
-; Don't emit zeroing registers in "main" function.
-define dso_local i32 @main() local_unnamed_addr #1 {
-; I386-LABEL: main:
-; I386:       # %bb.0: # %entry
-; I386-NEXT:    xorl %eax, %eax
-; I386-NEXT:    retl
-;
-; X86-64-LABEL: main:
-; X86-64:       # %bb.0: # %entry
-; X86-64-NEXT:    xorl %eax, %eax
-; X86-64-NEXT:    retq
-
-entry:
-  ret i32 0
-}
-
 attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone 
uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" 
"tune-cpu"="generic" }
 attributes #1 = { nofree norecurse nounwind uwtable "frame-pointer"="none" 
"min-legal-vector-width"="0" "no-trapping-math"="true" 
"stack-protector-buffer-size"="8" "target-cpu"="x86-64" 
"target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

>From 6a6d888174fb1e8273fc644a0c6900a90e303f12 Mon Sep 17 00:00:00 2001
From: Lucas Chollet <[email protected]>
Date: Tue, 9 Jun 2026 08:58:31 +0200
Subject: [PATCH 2/2] Remove unused attributes #1

---
 llvm/test/CodeGen/X86/zero-call-used-regs.ll | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/CodeGen/X86/zero-call-used-regs.ll 
b/llvm/test/CodeGen/X86/zero-call-used-regs.ll
index 84d71e2d57453..bc59796389e8e 100644
--- a/llvm/test/CodeGen/X86/zero-call-used-regs.ll
+++ b/llvm/test/CodeGen/X86/zero-call-used-regs.ll
@@ -256,4 +256,3 @@ define dso_local void @tailcall(ptr %p) local_unnamed_addr 
#0 "zero-call-used-re
 }
 
 attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone 
uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" 
"no-trapping-math"="true" "stack-protector-buffer-size"="8" 
"target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" 
"tune-cpu"="generic" }
-attributes #1 = { nofree norecurse nounwind uwtable "frame-pointer"="none" 
"min-legal-vector-width"="0" "no-trapping-math"="true" 
"stack-protector-buffer-size"="8" "target-cpu"="x86-64" 
"target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to