================
@@ -344,3 +344,149 @@ void arg_b4v16(b4v16 v) {}
 typedef _BitInt(32) b32v2 __attribute__((ext_vector_type(2)));
 void arg_b32v2(b32v2 v) {}
 // CHECK: define{{.*}} void @arg_b32v2(<2 x i32> noundef %{{.*}})
+
+// Aggregates of at most 16 bytes are passed directly. The slot is 8 bytes
+// (GPR64) when the controlling alignment is below 16, and 16 bytes otherwise.
+// AAPCS uses the unadjusted alignment. Other ABIs use the larger of the ABI
+// alignment and the pointer width, so ILP32 uses 4-byte slots. A record of
+// 64-bit pointers in an 8-byte slot is coerced to a pointer or an array of
+// pointers. Larger aggregates are passed indirectly.
+
+typedef struct {
+  int a, b;
+} TwoInts;
+void arg_two_ints(TwoInts s) {}
+// GPR64: define{{.*}} void @arg_two_ints(i64 %{{.*}})
+// ILP32: define{{.*}} void @arg_two_ints([2 x i32] %{{.*}})
+
+typedef struct {
+  char c;
+} OneChar;
+void arg_one_char(OneChar s) {}
+// GPR64: define{{.*}} void @arg_one_char(i64 %{{.*}})
+// ILP32: define{{.*}} void @arg_one_char(i32 %{{.*}})
+
+typedef struct {
+  int a, b, c;
+} ThreeInts;
+void arg_three_ints(ThreeInts s) {}
+// GPR64: define{{.*}} void @arg_three_ints([2 x i64] %{{.*}})
+// ILP32: define{{.*}} void @arg_three_ints([3 x i32] %{{.*}})
+
+typedef struct {
+  int a[3];
+} IntArray3;
+void arg_int_array3(IntArray3 s) {}
+// GPR64: define{{.*}} void @arg_int_array3([2 x i64] %{{.*}})
+// ILP32: define{{.*}} void @arg_int_array3([3 x i32] %{{.*}})
+
+typedef struct {
+  int a, b, c, d;
+} FourInts;
+void arg_four_ints(FourInts s) {}
+// GPR64: define{{.*}} void @arg_four_ints([2 x i64] %{{.*}})
+// ILP32: define{{.*}} void @arg_four_ints([4 x i32] %{{.*}})
+
+typedef struct {
+  __int128 x;
+} OneI128;
+void arg_i128(OneI128 s) {}
+// CHECK: define{{.*}} void @arg_i128(i128 %{{.*}})
+
+// alignas(16) raises the ABI alignment and leaves the unadjusted alignment
+// unchanged, so AAPCS still uses 8-byte slots. Other ABIs use an i128 slot.
+typedef struct __attribute__((aligned(16))) {
+  int a;
+} OveralignedInt;
+void arg_overaligned_int(OveralignedInt s) {}
+// AAPCS64: define{{.*}} void @arg_overaligned_int([2 x i64] %{{.*}})
+// NOHFAALIGN: define{{.*}} void @arg_overaligned_int(i128 %{{.*}})
+
+typedef struct {
+  void *p;
+} OnePtr;
+void arg_one_ptr(OnePtr s) {}
+// GPR64: define{{.*}} void @arg_one_ptr(ptr %{{.*}})
+// ILP32: define{{.*}} void @arg_one_ptr(i32 %{{.*}})
+
+typedef struct {
+  void *p, *q;
+} TwoPtrs;
+void arg_two_ptrs(TwoPtrs s) {}
+// GPR64: define{{.*}} void @arg_two_ptrs([2 x ptr] %{{.*}})
+// ILP32: define{{.*}} void @arg_two_ptrs([2 x i32] %{{.*}})
+
+typedef struct {
+  void *p;
+  int i;
+} PtrAndInt;
+void arg_ptr_and_int(PtrAndInt s) {}
+// GPR64: define{{.*}} void @arg_ptr_and_int([2 x i64] %{{.*}})
+// ILP32: define{{.*}} void @arg_ptr_and_int([2 x i32] %{{.*}})
+
+typedef struct {
+  void *a[2];
+} PtrArrayField;
+void arg_ptr_array_field(PtrArrayField s) {}
+// GPR64: define{{.*}} void @arg_ptr_array_field([2 x ptr] %{{.*}})
+// ILP32: define{{.*}} void @arg_ptr_array_field([2 x i32] %{{.*}})
+
+typedef struct {
+  OnePtr inner;
+} NestedPtr;
+void arg_nested_ptr(NestedPtr s) {}
+// GPR64: define{{.*}} void @arg_nested_ptr(ptr %{{.*}})
+// ILP32: define{{.*}} void @arg_nested_ptr(i32 %{{.*}})
+
+typedef struct {
+  OnePtr a[2];
+} PtrArray;
+void arg_ptr_array(PtrArray s) {}
+// GPR64: define{{.*}} void @arg_ptr_array([2 x ptr] %{{.*}})
+// ILP32: define{{.*}} void @arg_ptr_array([2 x i32] %{{.*}})
+
+typedef union {
+  void *p;
+  void *q;
+} PtrUnion;
+void arg_ptr_union(PtrUnion u) {}
+// GPR64: define{{.*}} void @arg_ptr_union(ptr %{{.*}})
+// ILP32: define{{.*}} void @arg_ptr_union(i32 %{{.*}})
+
+typedef union {
+  void *p;
+  int i;
+} MixedUnion;
+void arg_mixed_union(MixedUnion u) {}
+// GPR64: define{{.*}} void @arg_mixed_union(i64 %{{.*}})
+// ILP32: define{{.*}} void @arg_mixed_union(i32 %{{.*}})
+
+typedef struct __attribute__((aligned(16))) {
+  void *p;
+} OveralignedPtr;
+void arg_overaligned_ptr(OveralignedPtr s) {}
+// AAPCS64: define{{.*}} void @arg_overaligned_ptr([2 x ptr] %{{.*}})
+// NOHFAALIGN: define{{.*}} void @arg_overaligned_ptr(i128 %{{.*}})
+
+// A pointer to an address-space-qualified type is coerced to an integer.
----------------
madhur13490 wrote:

Could you add an address_space(0) case next to this one? It's the edge case 
that would catch the issue above.

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

Reply via email to