Skip to content

Commit

Permalink
[Clang] Set writable and dead_on_unwind attributes on sret arguments (#…
Browse files Browse the repository at this point in the history
…77116)

Set the writable and dead_on_unwind attributes for sret arguments. These
indicate that the argument points to writable memory (and it's legal to
introduce spurious writes to it on entry to the function) and that the
argument memory will not be used if the call unwinds.

This enables additional MemCpyOpt/DSE/LICM optimizations.
  • Loading branch information
nikic committed Jan 11, 2024
1 parent 66eedd1 commit 158d72d
Show file tree
Hide file tree
Showing 134 changed files with 815 additions and 837 deletions.
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
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
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
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
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
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

0 comments on commit 158d72d

Please sign in to comment.