================
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir
-clangir-enable-call-conv-lowering -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir
-clangir-enable-call-conv-lowering -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefixes=LLVM,LLVM-CIR --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefixes=LLVM,LLVM-OGCG --input-file=%t.ll %s
+
+typedef struct { int x; int y; } Pair2;
+typedef struct { long a; long b; } Pair16;
+typedef struct { long a, b, c, d; } Big;
+typedef struct { __int128 w; } Wide;
+typedef struct { __int128 w; char c; } WideChar;
+
+int vf(Pair2 p, ...);
+
+// CIR: cir.func private @vf(!u64i, ...) -> !s32i
+
+int call_scalar(Pair2 p, int a, double d) { return vf(p, a, d); }
+
+// CIR-LABEL: cir.func {{.*}}@call_scalar(%arg0: !u64i loc({{.+}}), %arg1:
!s32i {llvm.noundef} loc({{.+}}), %arg2: !cir.double {llvm.noundef}
loc({{.+}})) -> !s32i
+// CIR: cir.call @vf(%{{.+}}, %{{.+}}, %{{.+}}) : (!u64i, !s32i
{llvm.noundef}, !cir.double {llvm.noundef}) -> !s32i
+
+// LLVM-LABEL: i32 @call_scalar(i64 %{{.+}}, i32 noundef %{{.+}}, double
noundef %{{.+}})
+// LLVM: call i32 (i64, ...) @vf(i64 %{{.+}}, i32 noundef %{{.+}}, double
noundef %{{.+}})
+
+// A two-eightbyte record at the ellipsis is flattened into two INTEGER
+// registers while registers remain.
+int call_small(Pair2 p, Pair16 q) { return vf(p, q); }
+
+// CIR-LABEL: cir.func {{.*}}@call_small(%arg0: !u64i loc({{.+}}), %arg1:
!s64i loc({{.+}}), %arg2: !s64i loc({{.+}})) -> !s32i
----------------
adams381 wrote:
I reworked the whole file rather than just this function, since every check had
the same hole. `call_small` now captures the two incoming registers at the
label and asserts that the
1) first is stored to member 0 and the second to member 1 on entry
2) call operands are reloaded from members 0 and 1 in that order
3) named parameter stays in position one
`ell_bitint96` gets the same treatment for its register pair. The byval cases
pin the slot alignment, and on the OGCG side they also pin that the incoming
pointer is forwarded rather than copied into a fresh slot.
The previous version would have accepted the two halves arriving at the call in
either order, which is what prompted the rewrite.
https://github.com/llvm/llvm-project/pull/213315
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits