Skip to content

Commit daedd57

Browse files
Fix alignment of generated type (#8118)
Alignment can be explicitly specified on records/fields using attribute. Copy attributes from original type to compiler generated types to maintain same alignment in generated types
1 parent d2cafd5 commit daedd57

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,6 +1973,8 @@ class SyclKernelPointerHandler : public SyclKernelFieldHandler {
19731973
const_cast<DeclContext *>(RD->getDeclContext()), SourceLocation(),
19741974
SourceLocation(), getModifiedName(RD->getIdentifier()));
19751975
ModifiedRD->startDefinition();
1976+
if (RD->hasAttrs())
1977+
ModifiedRD->setAttrs(RD->getAttrs());
19761978
ModifiedRecords.push_back(ModifiedRD);
19771979
}
19781980

@@ -1987,6 +1989,8 @@ class SyclKernelPointerHandler : public SyclKernelFieldHandler {
19871989
Ctx.getTrivialTypeSourceInfo(FieldTy, SourceLocation()), /*BW=*/nullptr,
19881990
/*Mutable=*/false, ICIS_NoInit);
19891991
Field->setAccess(FD->getAccess());
1992+
if (FD->hasAttrs())
1993+
Field->setAttrs(FD->getAttrs());
19901994
// Add generated field to generated record.
19911995
ModifiedRecords.back()->addDecl(Field);
19921996
}
Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -disable-llvm-passes -no-opaque-pointers -emit-llvm %s -o - | FileCheck %s
22

33
// This test checks that compiler generates correct address spaces for pointer
4-
// kernel arguments that are wrapped by struct.
4+
// kernel arguments that are wrapped by struct. Generated class should retain
5+
// original padding and alignment.
56

67
#include "Inputs/sycl.hpp"
78

89
struct A {
910
float *F;
1011
};
1112

12-
struct B {
13+
struct alignas(16) B {
1314
int *F1;
1415
float *F2;
1516
A F3;
1617
int *F4[2];
1718
};
1819

20+
struct testFieldAlignment {
21+
int *ptr;
22+
alignas(16) float arr[4];
23+
int data;
24+
};
25+
1926
int main() {
20-
B Obj;
27+
B Obj1;
28+
testFieldAlignment Obj2;
2129
sycl::kernel_single_task<class structs>(
2230
[=]() {
23-
(void)Obj;
31+
(void)Obj1;
32+
(void)Obj2;
2433
});
2534
float A = 1;
2635
float *Ptr = &A;
@@ -33,9 +42,15 @@ int main() {
3342
return 0;
3443
}
3544

36-
// CHECK: %[[GENERATED_B:[a-zA-Z0-9_.]+]] = type { i32 addrspace(1)*, float addrspace(1)*, %[[GENERATED_A:[a-zA-Z0-9_.]+]], [2 x i32 addrspace(1)*] }
45+
// Padding in generated class class should match the 'original' padding
46+
// CHECK: %[[GENERATED_B:[a-zA-Z0-9_.]+]] = type { i32 addrspace(1)*, float addrspace(1)*, %[[GENERATED_A:[a-zA-Z0-9_.]+]], [2 x i32 addrspace(1)*], [8 x i8] }
3747
// CHECK: %[[GENERATED_A]] = type { float addrspace(1)* }
48+
// CHECK: %[[GENERATED_TESTFIELDALIGNMENT:[a-zA-Z0-9_.]+]] = type { i32 addrspace(1)*, [8 x i8], [4 x float], i32, [12 x i8] }
49+
// CHECK: %struct.B = type { i32 addrspace(4)*, float addrspace(4)*, %struct.A, [2 x i32 addrspace(4)*], [8 x i8] }
50+
// CHECK: %struct.A = type { float addrspace(4)* }
51+
// %struct.testFieldAlignment = type { i32 addrspace(4)*, [8 x i8], [4 x float], i32, [12 x i8] }
3852
// CHECK: %[[WRAPPER_LAMBDA_PTR:[a-zA-Z0-9_.]+]] = type { float addrspace(1)* }
3953
// CHECK: define {{.*}}spir_kernel void @{{.*}}structs
40-
// CHECK-SAME: %[[GENERATED_B]]* noundef byval(%[[GENERATED_B]]) align 8 %_arg_Obj
54+
// CHECK-SAME: %[[GENERATED_B]]* noundef byval(%[[GENERATED_B]]) align 16 %_arg_Obj1
55+
// CHECK-SAME: %[[GENERATED_TESTFIELDALIGNMENT]]* noundef byval(%[[GENERATED_TESTFIELDALIGNMENT]]) align 16 %_arg_Obj2
4156
// CHECK: define {{.*}}spir_kernel void @{{.*}}lambdas{{.*}}(%[[WRAPPER_LAMBDA_PTR]]* noundef byval(%[[WRAPPER_LAMBDA_PTR]]) align 8 %_arg_Lambda)
Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -disable-llvm-passes -opaque-pointers -emit-llvm %s -o - | FileCheck %s
22

33
// This test checks that compiler generates correct address spaces for pointer
4-
// kernel arguments that are wrapped by struct.
4+
// kernel arguments that are wrapped by struct. Generated class should retain
5+
// original padding and alignment.
56

67
#include "Inputs/sycl.hpp"
78

89
struct A {
910
float *F;
1011
};
1112

12-
struct B {
13+
struct alignas(16) B {
1314
int *F1;
1415
float *F2;
1516
A F3;
1617
int *F4[2];
1718
};
1819

20+
struct testFieldAlignment {
21+
int *ptr;
22+
alignas(16) float arr[4];
23+
int data;
24+
};
25+
1926
int main() {
20-
B Obj;
27+
B Obj1;
28+
testFieldAlignment Obj2;
2129
sycl::kernel_single_task<class structs>(
2230
[=]() {
23-
(void)Obj;
31+
(void)Obj1;
32+
(void)Obj2;
2433
});
2534
float A = 1;
2635
float *Ptr = &A;
@@ -33,10 +42,16 @@ int main() {
3342
return 0;
3443
}
3544

36-
// CHECK: %[[GENERATED_B:[a-zA-Z0-9_.]+]] = type { ptr addrspace(1), ptr addrspace(1), %[[GENERATED_A:[a-zA-Z0-9_.]+]], [2 x ptr addrspace(1)] }
37-
// CHECK: [[GENERATED_A]] = type { ptr addrspace(1) }
45+
// Padding in generated class class should match the 'original' padding
46+
// CHECK: %[[GENERATED_B:[a-zA-Z0-9_.]+]] = type { ptr addrspace(1), ptr addrspace(1), %[[GENERATED_A:[a-zA-Z0-9_.]+]], [2 x ptr addrspace(1)], [8 x i8] }
47+
// CHECK: %[[GENERATED_A]] = type { ptr addrspace(1) }
48+
// CHECK: %[[GENERATED_TESTFIELDALIGNMENT:[a-zA-Z0-9_.]+]] = type { ptr addrspace(1), [8 x i8], [4 x float], i32, [12 x i8] }
49+
// CHECK: %struct.B = type { ptr addrspace(4), ptr addrspace(4), %struct.A, [2 x ptr addrspace(4)], [8 x i8] }
50+
// CHECK: %struct.testFieldAlignment = type { ptr addrspace(4), [8 x i8], [4 x float], i32, [12 x i8] }
51+
// %struct.A = type { ptr addrspace(4) }
3852
// CHECK: %[[WRAPPER_LAMBDA_PTR:[a-zA-Z0-9_.]+]] = type { ptr addrspace(1) }
3953

4054
// CHECK: define {{.*}}spir_kernel void @{{.*}}structs
41-
// CHECK-SAME: ptr noundef byval(%[[GENERATED_B]]) align 8 %_arg_Obj
55+
// CHECK-SAME: ptr noundef byval(%[[GENERATED_B]]) align 16 %_arg_Obj1
56+
// CHECK-SAME: ptr noundef byval(%[[GENERATED_TESTFIELDALIGNMENT]]) align 16 %_arg_Obj2
4257
// CHECK: define {{.*}}spir_kernel void @{{.*}}lambdas{{.*}}(ptr noundef byval(%[[WRAPPER_LAMBDA_PTR]]) align 8 %_arg_Lambda)

0 commit comments

Comments
 (0)