[clang] [CIR] Classify empty records as Ignore in x86_64 callconv (PR #211078)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 21 14:55:04 PDT 2026
================
@@ -0,0 +1,50 @@
+// RUN: cir-opt %s -cir-call-conv-lowering=target=x86_64 | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+!rec_E0 = !cir.struct<"E0" {}>
+
+module attributes {
+ dlti.dl_spec = #dlti.dl_spec<
+ #dlti.dl_entry<i32, dense<32>: vector<2xi64>>,
+ #dlti.dl_entry<i64, dense<64>: vector<2xi64>>>
+} {
+
+ // A zero-field record (a C empty struct) classifies as Ignore: the argument
+ // is dropped from the lowered signature.
+ cir.func @take_empty(%arg0: !rec_E0) {
+ cir.return
+ }
+
+ // CHECK: cir.func{{.*}} @take_empty()
+ // CHECK-NEXT: cir.return
+
+ // The empty argument is dropped even when a real argument remains; the real
+ // argument shifts down to the first slot.
+ cir.func @take_mixed(%arg0: !rec_E0, %arg1: !s32i) -> !s32i {
+ cir.return %arg1 : !s32i
+ }
+
+ // CHECK: cir.func{{.*}} @take_mixed(%arg0: !s32i) -> !s32i
+ // CHECK-NEXT: cir.return %arg0 : !s32i
+
+ // An empty-record return is dropped: the function returns void.
+ cir.func @ret_empty() -> !rec_E0 {
+ %0 = cir.alloca "r" align(1) : !cir.ptr<!rec_E0>
+ %1 = cir.load %0 : !cir.ptr<!rec_E0>, !rec_E0
+ cir.return %1 : !rec_E0
+ }
+
+ // CHECK: cir.func{{.*}} @ret_empty()
+ // CHECK-NOT: -> !rec_E0
+ // CHECK: cir.return
+
+ // The empty argument is also dropped at call sites: the caller's own empty
+ // argument is dropped, and the call to take_mixed drops it too.
+ cir.func @caller(%arg0: !rec_E0, %arg1: !s32i) -> !s32i {
+ %0 = cir.call @take_mixed(%arg0, %arg1) : (!rec_E0, !s32i) -> !s32i
----------------
adams381 wrote:
Added a local-alloca case. The alloca survives the rewrite, the argument is still dropped.
https://github.com/llvm/llvm-project/pull/211078
More information about the cfe-commits
mailing list