Skip to content
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

[Clang] Set writable and dead_on_unwind attributes on sret arguments #77116

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2612,6 +2612,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
if (IRFunctionArgs.hasSRetArg()) {
llvm::AttrBuilder SRETAttrs(getLLVMContext());
SRETAttrs.addStructRetAttr(getTypes().ConvertTypeForMem(RetTy));
SRETAttrs.addAttribute(llvm::Attribute::Writable);
SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
hasUsedSRet = true;
if (RetAI.getInReg())
SRETAttrs.addAttribute(llvm::Attribute::InReg);
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/2006-05-19-SingleEltReturn.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct Y bar(void) {


// X86_32: define{{.*}} void @foo(ptr noundef %P)
// X86_32: call void @bar(ptr sret(%struct.Y) align 4 %{{[^),]*}})
// X86_32: call void @bar(ptr dead_on_unwind writable sret(%struct.Y) align 4 %{{[^),]*}})

// X86_32: define{{.*}} void @bar(ptr noalias sret(%struct.Y) align 4 %{{[^,)]*}})
// X86_32: define{{.*}} void @bar(ptr dead_on_unwind noalias writable sret(%struct.Y) align 4 %{{[^,)]*}})
// X86_32: ret void
22 changes: 11 additions & 11 deletions clang/test/CodeGen/64bit-swiftcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unr

typedef struct { char array[1024]; } struct_reallybig;
SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); }
// CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr noalias sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}})
// CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr dead_on_unwind noalias writable sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}})

SWIFTCALL void context_1(CONTEXT void *self) {}
// CHECK-LABEL: define {{.*}} void @context_1(ptr swiftself
Expand Down Expand Up @@ -238,7 +238,7 @@ typedef struct {
} struct_big_1;
TEST(struct_big_1)

// CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} noalias sret
// CHECK-LABEL: define {{.*}} void @return_struct_big_1(ptr dead_on_unwind noalias writable sret

// Should not be byval.
// CHECK-LABEL: define {{.*}} void @take_struct_big_1(ptr{{( %.*)?}})
Expand Down Expand Up @@ -522,7 +522,7 @@ typedef struct {
double d4;
} struct_d5;
TEST(struct_d5)
// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr noalias sret([[STRUCT5:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr dead_on_unwind noalias writable sret([[STRUCT5:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_d5(ptr

typedef struct {
Expand Down Expand Up @@ -709,7 +709,7 @@ typedef struct {
long long l4;
} struct_l5;
TEST(struct_l5)
// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr noalias sret([[STRUCT5:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr dead_on_unwind noalias writable sret([[STRUCT5:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_l5(ptr

typedef struct {
Expand Down Expand Up @@ -754,7 +754,7 @@ typedef struct {
char16 c4;
} struct_vc5;
TEST(struct_vc5)
// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vc5(ptr

typedef struct {
Expand Down Expand Up @@ -799,7 +799,7 @@ typedef struct {
short8 c4;
} struct_vs5;
TEST(struct_vs5)
// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vs5(ptr

typedef struct {
Expand Down Expand Up @@ -844,7 +844,7 @@ typedef struct {
int4 c4;
} struct_vi5;
TEST(struct_vi5)
// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vi5(ptr

typedef struct {
Expand Down Expand Up @@ -872,7 +872,7 @@ typedef struct {
long2 c4;
} struct_vl5;
TEST(struct_vl5)
// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vl5(ptr

typedef struct {
Expand Down Expand Up @@ -900,7 +900,7 @@ typedef struct {
double2 c4;
} struct_vd5;
TEST(struct_vd5)
// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vd5(ptr

typedef struct {
Expand All @@ -924,7 +924,7 @@ typedef struct {
double4 c2;
} struct_vd43;
TEST(struct_vd43)
// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vd43(ptr

typedef struct {
Expand Down Expand Up @@ -960,7 +960,7 @@ typedef struct {
float4 c4;
} struct_vf5;
TEST(struct_vf5)
// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr noalias sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]])
// CHECK: define{{.*}} swiftcc void @take_struct_vf5(ptr

typedef struct {
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/CSKY/csky-abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void f_agg_large(struct large x) {

// The address where the struct should be written to will be the first
// argument
// CHECK-LABEL: define{{.*}} void @f_agg_large_ret(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %i, i8 noundef signext %j)
// CHECK-LABEL: define{{.*}} void @f_agg_large_ret(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, i32 noundef %i, i8 noundef signext %j)
struct large f_agg_large_ret(int32_t i, int8_t j) {
return (struct large){1, 2, 3, 4};
}
Expand All @@ -144,7 +144,7 @@ int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
// the presence of large return values that consume a register due to the need
// to pass a pointer.

// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, i64 noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g)
// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, i64 noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g)
struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d,
uint8_t e, int8_t f, uint8_t g) {
return (struct large){a, e, f, g};
Expand Down
44 changes: 22 additions & 22 deletions clang/test/CodeGen/CSKY/csky-hard-abi.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ struct double_float_s {
// CHECK: define{{.*}} void @f_double_double_s_arg([4 x i32] %a.coerce)
void f_double_double_s_arg(struct double_double_s a) {}

// CHECK: define{{.*}} void @f_ret_double_double_s(ptr noalias sret(%struct.double_double_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_double_s(ptr dead_on_unwind noalias writable sret(%struct.double_double_s) align 4 %agg.result)
struct double_double_s f_ret_double_double_s(void) {
return (struct double_double_s){1.0, 2.0};
}

// CHECK: define{{.*}} void @f_double_float_s_arg([3 x i32] %a.coerce)
void f_double_float_s_arg(struct double_float_s a) {}

// CHECK: define{{.*}} void @f_ret_double_float_s(ptr noalias sret(%struct.double_float_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_float_s(ptr dead_on_unwind noalias writable sret(%struct.double_float_s) align 4 %agg.result)
struct double_float_s f_ret_double_float_s(void) {
return (struct double_float_s){1.0, 2.0};
}
Expand Down Expand Up @@ -118,47 +118,47 @@ struct double_int8_zbf_s {
// CHECK: define{{.*}} @f_double_int8_s_arg([3 x i32] %a.coerce)
void f_double_int8_s_arg(struct double_int8_s a) {}

// CHECK: define{{.*}} void @f_ret_double_int8_s(ptr noalias sret(%struct.double_int8_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_int8_s(ptr dead_on_unwind noalias writable sret(%struct.double_int8_s) align 4 %agg.result)
struct double_int8_s f_ret_double_int8_s(void) {
return (struct double_int8_s){1.0, 2};
}

// CHECK: define{{.*}} void @f_double_uint8_s_arg([3 x i32] %a.coerce)
void f_double_uint8_s_arg(struct double_uint8_s a) {}

// CHECK: define{{.*}} void @f_ret_double_uint8_s(ptr noalias sret(%struct.double_uint8_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_uint8_s(ptr dead_on_unwind noalias writable sret(%struct.double_uint8_s) align 4 %agg.result)
struct double_uint8_s f_ret_double_uint8_s(void) {
return (struct double_uint8_s){1.0, 2};
}

// CHECK: define{{.*}} void @f_double_int32_s_arg([3 x i32] %a.coerce)
void f_double_int32_s_arg(struct double_int32_s a) {}

// CHECK: define{{.*}} void @f_ret_double_int32_s(ptr noalias sret(%struct.double_int32_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_int32_s(ptr dead_on_unwind noalias writable sret(%struct.double_int32_s) align 4 %agg.result)
struct double_int32_s f_ret_double_int32_s(void) {
return (struct double_int32_s){1.0, 2};
}

// CHECK: define{{.*}} void @f_double_int64_s_arg([4 x i32] %a.coerce)
void f_double_int64_s_arg(struct double_int64_s a) {}

// CHECK: define{{.*}} void @f_ret_double_int64_s(ptr noalias sret(%struct.double_int64_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_int64_s(ptr dead_on_unwind noalias writable sret(%struct.double_int64_s) align 4 %agg.result)
struct double_int64_s f_ret_double_int64_s(void) {
return (struct double_int64_s){1.0, 2};
}

// CHECK: define{{.*}} void @f_double_int64bf_s_arg([3 x i32] %a.coerce)
void f_double_int64bf_s_arg(struct double_int64bf_s a) {}

// CHECK: define{{.*}} void @f_ret_double_int64bf_s(ptr noalias sret(%struct.double_int64bf_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_int64bf_s(ptr dead_on_unwind noalias writable sret(%struct.double_int64bf_s) align 4 %agg.result)
struct double_int64bf_s f_ret_double_int64bf_s(void) {
return (struct double_int64bf_s){1.0, 2};
}

// CHECK: define{{.*}} void @f_double_int8_zbf_s([3 x i32] %a.coerce)
void f_double_int8_zbf_s(struct double_int8_zbf_s a) {}

// CHECK: define{{.*}} void @f_ret_double_int8_zbf_s(ptr noalias sret(%struct.double_int8_zbf_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_double_int8_zbf_s(ptr dead_on_unwind noalias writable sret(%struct.double_int8_zbf_s) align 4 %agg.result)
struct double_int8_zbf_s f_ret_double_int8_zbf_s(void) {
return (struct double_int8_zbf_s){1.0, 2};
}
Expand All @@ -179,7 +179,7 @@ void f_struct_double_int8_insufficient_fprs(float a, double b, double c, double
// CHECK: define{{.*}} void @f_doublecomplex(double noundef %a.coerce0, double noundef %a.coerce1)
void f_doublecomplex(double __complex__ a) {}

// CHECK: define{{.*}} void @f_ret_doublecomplex(ptr noalias sret({ double, double }) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublecomplex(ptr dead_on_unwind noalias writable sret({ double, double }) align 4 %agg.result)
double __complex__ f_ret_doublecomplex(void) {
return 1.0;
}
Expand All @@ -191,7 +191,7 @@ struct doublecomplex_s {
// CHECK: define{{.*}} void @f_doublecomplex_s_arg([4 x i32] %a.coerce)
void f_doublecomplex_s_arg(struct doublecomplex_s a) {}

// CHECK: define{{.*}} void @f_ret_doublecomplex_s(ptr noalias sret(%struct.doublecomplex_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublecomplex_s(ptr dead_on_unwind noalias writable sret(%struct.doublecomplex_s) align 4 %agg.result)
struct doublecomplex_s f_ret_doublecomplex_s(void) {
return (struct doublecomplex_s){1.0};
}
Expand All @@ -218,7 +218,7 @@ struct doublearr2_s {
// CHECK: define{{.*}} void @f_doublearr2_s_arg([4 x i32] %a.coerce)
void f_doublearr2_s_arg(struct doublearr2_s a) {}

// CHECK: define{{.*}} void @f_ret_doublearr2_s(ptr noalias sret(%struct.doublearr2_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublearr2_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_s) align 4 %agg.result)
struct doublearr2_s f_ret_doublearr2_s(void) {
return (struct doublearr2_s){{1.0, 2.0}};
}
Expand All @@ -232,7 +232,7 @@ struct doublearr2_tricky1_s {
// CHECK: define{{.*}} void @f_doublearr2_tricky1_s_arg([4 x i32] %a.coerce)
void f_doublearr2_tricky1_s_arg(struct doublearr2_tricky1_s a) {}

// CHECK: define{{.*}} void @f_ret_doublearr2_tricky1_s(ptr noalias sret(%struct.doublearr2_tricky1_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublearr2_tricky1_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky1_s) align 4 %agg.result)
struct doublearr2_tricky1_s f_ret_doublearr2_tricky1_s(void) {
return (struct doublearr2_tricky1_s){{{{1.0}}, {{2.0}}}};
}
Expand All @@ -247,7 +247,7 @@ struct doublearr2_tricky2_s {
// CHECK: define{{.*}} void @f_doublearr2_tricky2_s_arg([4 x i32] %a.coerce)
void f_doublearr2_tricky2_s_arg(struct doublearr2_tricky2_s a) {}

// CHECK: define{{.*}} void @f_ret_doublearr2_tricky2_s(ptr noalias sret(%struct.doublearr2_tricky2_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublearr2_tricky2_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky2_s) align 4 %agg.result)
struct doublearr2_tricky2_s f_ret_doublearr2_tricky2_s(void) {
return (struct doublearr2_tricky2_s){{}, {{{1.0}}, {{2.0}}}};
}
Expand All @@ -262,7 +262,7 @@ struct doublearr2_tricky3_s {
// CHECK: define{{.*}} void @f_doublearr2_tricky3_s_arg([4 x i32] %a.coerce)
void f_doublearr2_tricky3_s_arg(struct doublearr2_tricky3_s a) {}

// CHECK: define{{.*}} void @f_ret_doublearr2_tricky3_s(ptr noalias sret(%struct.doublearr2_tricky3_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublearr2_tricky3_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky3_s) align 4 %agg.result)
struct doublearr2_tricky3_s f_ret_doublearr2_tricky3_s(void) {
return (struct doublearr2_tricky3_s){{}, {{{1.0}}, {{2.0}}}};
}
Expand All @@ -278,7 +278,7 @@ struct doublearr2_tricky4_s {
// CHECK: define{{.*}} void @f_doublearr2_tricky4_s_arg([4 x i32] %a.coerce)
void f_doublearr2_tricky4_s_arg(struct doublearr2_tricky4_s a) {}

// CHECK: define{{.*}} void @f_ret_doublearr2_tricky4_s(ptr noalias sret(%struct.doublearr2_tricky4_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_doublearr2_tricky4_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky4_s) align 4 %agg.result)
struct doublearr2_tricky4_s f_ret_doublearr2_tricky4_s(void) {
return (struct doublearr2_tricky4_s){{}, {{{}, {1.0}}, {{}, {2.0}}}};
}
Expand All @@ -292,7 +292,7 @@ struct int_double_int_s {
// CHECK: define{{.*}} void @f_int_double_int_s_arg([4 x i32] %a.coerce)
void f_int_double_int_s_arg(struct int_double_int_s a) {}

// CHECK: define{{.*}} void @f_ret_int_double_int_s(ptr noalias sret(%struct.int_double_int_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_int_double_int_s(ptr dead_on_unwind noalias writable sret(%struct.int_double_int_s) align 4 %agg.result)
struct int_double_int_s f_ret_int_double_int_s(void) {
return (struct int_double_int_s){1, 2.0, 3};
}
Expand All @@ -305,7 +305,7 @@ struct int64_double_s {
// CHECK: define{{.*}} void @f_int64_double_s_arg([4 x i32] %a.coerce)
void f_int64_double_s_arg(struct int64_double_s a) {}

// CHECK: define{{.*}} void @f_ret_int64_double_s(ptr noalias sret(%struct.int64_double_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_int64_double_s(ptr dead_on_unwind noalias writable sret(%struct.int64_double_s) align 4 %agg.result)
struct int64_double_s f_ret_int64_double_s(void) {
return (struct int64_double_s){1, 2.0};
}
Expand All @@ -319,7 +319,7 @@ struct char_char_double_s {
// CHECK-LABEL: define{{.*}} void @f_char_char_double_s_arg([3 x i32] %a.coerce)
void f_char_char_double_s_arg(struct char_char_double_s a) {}

// CHECK: define{{.*}} void @f_ret_char_char_double_s(ptr noalias sret(%struct.char_char_double_s) align 4 %agg.result)
// CHECK: define{{.*}} void @f_ret_char_char_double_s(ptr dead_on_unwind noalias writable sret(%struct.char_char_double_s) align 4 %agg.result)
struct char_char_double_s f_ret_char_char_double_s(void) {
return (struct char_char_double_s){1, 2, 3.0};
}
Expand All @@ -338,19 +338,19 @@ union double_u f_ret_double_u(void) {
return (union double_u){1.0};
}

// CHECK: define{{.*}} void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(ptr noalias sret(%struct.double_int32_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce)
// CHECK: define{{.*}} void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret(%struct.double_int32_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce)
struct double_int32_s f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(
int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) {
return (struct double_int32_s){1.0, 2};
}

// CHECK: define{{.*}} void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs(ptr noalias sret(%struct.double_double_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce)
// CHECK: define{{.*}} void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret(%struct.double_double_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce)
struct double_double_s f_ret_double_double_s_double_int32_s_just_sufficient_gprs(
int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) {
return (struct double_double_s){1.0, 2.0};
}

// CHECK: define{{.*}} void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(ptr noalias sret({ double, double }) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce)
// CHECK: define{{.*}} void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret({ double, double }) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce)
double __complex__ f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(
int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) {
return 1.0;
Expand All @@ -376,7 +376,7 @@ struct large {
// the presence of large return values that consume a register due to the need
// to pass a pointer.

// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g)
// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g)
struct large f_scalar_stack_2(float a, int64_t b, double c, long double d,
uint8_t e, int8_t f, uint8_t g) {
return (struct large){a, e, f, g};
Expand Down
Loading