Skip to content

Commit de98cf9

Browse files
committed
[CodeGen] Add an alignment attribute to all sret parameters
This fixes a miscompile when the parameter is actually underaligned. rdar://58316406 Differential revision: https://reviews.llvm.org/D74183
1 parent 43a6d28 commit de98cf9

File tree

101 files changed

+570
-559
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+570
-559
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,6 +2084,7 @@ void CodeGenModule::ConstructAttributeList(
20842084
hasUsedSRet = true;
20852085
if (RetAI.getInReg())
20862086
SRETAttrs.addAttribute(llvm::Attribute::InReg);
2087+
SRETAttrs.addAlignmentAttr(RetAI.getIndirectAlign().getQuantity());
20872088
ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
20882089
llvm::AttributeSet::get(getLLVMContext(), SRETAttrs);
20892090
}

clang/test/CodeGen/2006-05-19-SingleEltReturn.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct Y bar() {
2424

2525

2626
// X86_32: define void @foo(%struct.Y* %P)
27-
// X86_32: call void @bar(%struct.Y* sret %{{[^),]*}})
27+
// X86_32: call void @bar(%struct.Y* sret align 4 %{{[^),]*}})
2828

29-
// X86_32: define void @bar(%struct.Y* noalias sret %{{[^,)]*}})
29+
// X86_32: define void @bar(%struct.Y* noalias sret align 4 %{{[^,)]*}})
3030
// X86_32: ret void

clang/test/CodeGen/aarch64-varargs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ typedef struct __attribute__((aligned(32))) {
639639
__int128 val;
640640
} overaligned_int128_struct;
641641
overaligned_int128_struct overaligned_int128_struct_test() {
642-
// CHECK-LABEL: define void @overaligned_int128_struct_test(%struct.overaligned_int128_struct* noalias sret %agg.result)
642+
// CHECK-LABEL: define void @overaligned_int128_struct_test(%struct.overaligned_int128_struct* noalias sret align 32 %agg.result)
643643
return va_arg(the_list, overaligned_int128_struct);
644644
// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
645645
// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0
@@ -853,7 +853,7 @@ typedef struct {
853853
__int128 val __attribute__((aligned(32)));
854854
} overaligned_int128_struct_member;
855855
overaligned_int128_struct_member overaligned_int128_struct_member_test() {
856-
// CHECK-LABEL: define void @overaligned_int128_struct_member_test(%struct.overaligned_int128_struct_member* noalias sret %agg.result)
856+
// CHECK-LABEL: define void @overaligned_int128_struct_member_test(%struct.overaligned_int128_struct_member* noalias sret align 32 %agg.result)
857857
return va_arg(the_list, overaligned_int128_struct_member);
858858
// CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, i32* getelementptr inbounds (%struct.__va_list, %struct.__va_list* @the_list, i32 0, i32 3)
859859
// CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0

clang/test/CodeGen/aggregate-assign-call.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,17 @@ struct S baz(int i, volatile int *j) {
6262
// O1-NEWPM: %[[TMP3:.*]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
6363
// O1-NEWPM: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* nonnull %[[P]])
6464
//
65-
// O1-LEGACY: call void @foo_int(%struct.S* sret %[[TMP1_ALLOCA]],
66-
// O1-NEWPM: call void @foo_int(%struct.S* nonnull sret %[[TMP1_ALLOCA]],
65+
// O1-LEGACY: call void @foo_int(%struct.S* sret align 4 %[[TMP1_ALLOCA]],
66+
// O1-NEWPM: call void @foo_int(%struct.S* nonnull sret align 4 %[[TMP1_ALLOCA]],
6767
// O1: call void @llvm.memcpy
6868
// O1-LEGACY: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP1_ALLOCA]] to i8*
6969
// O1-LEGACY: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])
7070
// O1-NEWPM: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* nonnull %[[P]])
7171
// O1-LEGACY: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
7272
// O1-LEGACY: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* %[[P]])
7373
// O1-NEWPM: call void @llvm.lifetime.start.p0i8({{[^,]*}}, i8* nonnull %[[TMP3]])
74-
// O1-LEGACY: call void @foo_int(%struct.S* sret %[[TMP2_ALLOCA]],
75-
// O1-NEWPM: call void @foo_int(%struct.S* nonnull sret %[[TMP2_ALLOCA]],
74+
// O1-LEGACY: call void @foo_int(%struct.S* sret align 4 %[[TMP2_ALLOCA]],
75+
// O1-NEWPM: call void @foo_int(%struct.S* nonnull sret align 4 %[[TMP2_ALLOCA]],
7676
// O1: call void @llvm.memcpy
7777
// O1-LEGACY: %[[P:[^ ]+]] = bitcast %struct.S* %[[TMP2_ALLOCA]] to i8*
7878
// O1-LEGACY: call void @llvm.lifetime.end.p0i8({{[^,]*}}, i8* %[[P]])

clang/test/CodeGen/aligned-sret.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -triple x86_64-apple-macos %s -S -emit-llvm -o- | FileCheck %s
2+
3+
typedef __attribute__((__ext_vector_type__(4),__aligned__(16))) double simd_double4;
4+
typedef struct { simd_double4 columns[4]; } simd_double4x4;
5+
typedef simd_double4x4 matrix_double4x4;
6+
7+
// CHECK: define void @ident(%struct.simd_double4x4* noalias sret align 16 %agg.result
8+
matrix_double4x4 ident(matrix_double4x4 x) {
9+
return x;
10+
}

clang/test/CodeGen/arc/arguments.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void cf1(cs1 i) {}
2222
typedef struct {
2323
int cc;
2424
} s2;
25-
// CHECK: define void @f2(%struct.s2* noalias sret %agg.result)
25+
// CHECK: define void @f2(%struct.s2* noalias sret align 4 %agg.result)
2626
s2 f2() {
2727
s2 foo;
2828
return foo;
@@ -32,7 +32,7 @@ typedef struct {
3232
int cc;
3333
int dd;
3434
} s3;
35-
// CHECK: define void @f3(%struct.s3* noalias sret %agg.result)
35+
// CHECK: define void @f3(%struct.s3* noalias sret align 4 %agg.result)
3636
s3 f3() {
3737
s3 foo;
3838
return foo;
@@ -128,8 +128,8 @@ void st3(s16 a, s16 b, s16 c) {}
128128

129129
// 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval
130130
s16 st4(int x, s8 a, s16 b, s16 c) { return b; }
131-
// CHECK: define void @st4(%struct.s16* noalias sret %agg.result, i32 inreg %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)
131+
// CHECK: define void @st4(%struct.s16* noalias sret align 4 %agg.result, i32 inreg %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)
132132

133133
// 1 sret + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce)
134134
s16 st5(s8 a, s16 b, s16 c) { return b; }
135-
// CHECK: define void @st5(%struct.s16* noalias sret %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)
135+
// CHECK: define void @st5(%struct.s16* noalias sret align 4 %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce)

clang/test/CodeGen/arm-aapcs-vfp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ void test_vfp_stack_gpr_split_1(double a, double b, double c, double d, double e
125125
// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_2(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [2 x i64] %k.coerce)
126126
void test_vfp_stack_gpr_split_2(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_long_long_int k) {}
127127

128-
// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(%struct.struct_long_long_int* noalias sret %agg.result, double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, [2 x i64] %k.coerce)
128+
// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(%struct.struct_long_long_int* noalias sret align 8 %agg.result, double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, [2 x i64] %k.coerce)
129129
struct_long_long_int test_vfp_stack_gpr_split_3(double a, double b, double c, double d, double e, double f, double g, double h, double i, struct_long_long_int k) {}
130130

131131
typedef struct { int a; int b:4; int c; } struct_int_bitfield_int;

clang/test/CodeGen/arm-homogenous.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void test_union_with_first_floats(void) {
2727
void test_return_union_with_first_floats(void) {
2828
g_u_f = returns_union_with_first_floats();
2929
}
30-
// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret)
30+
// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret align 4)
3131

3232
/* This is not a homogenous aggregate - fundamental types are different */
3333
typedef union {
@@ -47,7 +47,7 @@ void test_union_with_non_first_floats(void) {
4747
void test_return_union_with_non_first_floats(void) {
4848
g_u_nf_f = returns_union_with_non_first_floats();
4949
}
50-
// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret)
50+
// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret align 4)
5151

5252
/* This is not a homogenous aggregate - fundamental types are different */
5353
typedef struct {
@@ -67,7 +67,7 @@ void test_struct_with_union_with_first_floats(void) {
6767
void test_return_struct_with_union_with_first_floats(void) {
6868
g_s_f = returns_struct_with_union_with_first_floats();
6969
}
70-
// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret)
70+
// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret align 4)
7171

7272
/* This is not a homogenous aggregate - fundamental types are different */
7373
typedef struct {
@@ -87,7 +87,7 @@ void test_struct_with_union_with_non_first_floats(void) {
8787
void test_return_struct_with_union_with_non_first_floats(void) {
8888
g_s_nf_f = returns_struct_with_union_with_non_first_floats();
8989
}
90-
// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret)
90+
// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret align 4)
9191

9292
/* Plain array is not a homogenous aggregate */
9393
extern void takes_array_of_floats(float a[4]);

0 commit comments

Comments
 (0)