Anastasia updated this revision to Diff 319869. Anastasia retitled this revision from "[OpenCL][PR48896] Fix address space when binding vector literals to references" to "[OpenCL][PR48896] Fix address space in binding of initializer lists to references". Anastasia edited the summary of this revision. Anastasia added reviewers: rjmccall, ebevhan. Anastasia added a subscriber: cfe-commits. Anastasia added a comment.
- Added a test case. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95608/new/ https://reviews.llvm.org/D95608 Files: clang/lib/Sema/SemaInit.cpp clang/test/CodeGenOpenCLCXX/addrspace-references.cl Index: clang/test/CodeGenOpenCLCXX/addrspace-references.cl =================================================================== --- clang/test/CodeGenOpenCLCXX/addrspace-references.cl +++ clang/test/CodeGenOpenCLCXX/addrspace-references.cl @@ -1,8 +1,16 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -triple spir -emit-llvm -o - | FileCheck %s +//RUN: %clang_cc1 %s -cl-std=clc++ -triple spir -emit-llvm -o - -O0 | FileCheck %s + +typedef short short2 __attribute__((ext_vector_type(2))); int bar(const unsigned int &i); -// CHECK-LABEL: define{{.*}} spir_func void @_Z3foov() -void foo() { + +class C { +public: +void bar(const short2&); +}; + +// CHECK-LABEL: define{{.*}} spir_func void @_Z6scalarv() +void scalar() { // The generic addr space reference parameter object will be bound // to a temporary value allocated in private addr space. We need an // addrspacecast before passing the value to the function. @@ -12,3 +20,14 @@ // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* align 4 dereferenceable(4) [[REG]]) bar(1); } + +// Test list initialization +// CHECK-LABEL: define{{.*}} spir_func void @_Z4listv() +void list() { + C c1; +// CHECK: [[REF:%.*]] = alloca <2 x i16> +// CHECK: store <2 x i16> <i16 1, i16 2>, <2 x i16>* [[REF]] +// CHECK: [[REG:%[.a-z0-9]+]] = addrspacecast <2 x i16>* [[REF]] to <2 x i16> addrspace(4)* +// CHECK: call {{.*}}void @_ZNU3AS41C3barERU3AS4KDv2_s(%class.C addrspace(4)* {{.*}}, <2 x i16> addrspace(4)*{{.*}} [[REG]]) + c1.bar({1, 2}); +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4289,17 +4289,24 @@ if (Sequence.step_begin() != Sequence.step_end()) Sequence.RewrapReferenceInitList(cv1T1, InitList); } - + // Ignore address space of reference type at this point and perform address + // space conversion after the reference binding step. + QualType cv1T1IgnoreAS = + T1Quals.hasAddressSpace() + ? S.Context.getQualifiedType(T1, T1Quals.withoutAddressSpace()) + : cv1T1; // Not reference-related. Create a temporary and bind to that. - InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1); + InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1IgnoreAS); TryListInitialization(S, TempEntity, Kind, InitList, Sequence, TreatUnavailableAsInvalid); if (Sequence) { if (DestType->isRValueReferenceType() || - (T1Quals.hasConst() && !T1Quals.hasVolatile())) - Sequence.AddReferenceBindingStep(cv1T1, /*BindingTemporary=*/true); - else + (T1Quals.hasConst() && !T1Quals.hasVolatile())) { + Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*BindingTemporary=*/true); + if (T1Quals.hasAddressSpace()) + Sequence.AddQualificationConversionStep(cv1T1, VK_XValue); + } else Sequence.SetFailed( InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary); }
Index: clang/test/CodeGenOpenCLCXX/addrspace-references.cl =================================================================== --- clang/test/CodeGenOpenCLCXX/addrspace-references.cl +++ clang/test/CodeGenOpenCLCXX/addrspace-references.cl @@ -1,8 +1,16 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -triple spir -emit-llvm -o - | FileCheck %s +//RUN: %clang_cc1 %s -cl-std=clc++ -triple spir -emit-llvm -o - -O0 | FileCheck %s + +typedef short short2 __attribute__((ext_vector_type(2))); int bar(const unsigned int &i); -// CHECK-LABEL: define{{.*}} spir_func void @_Z3foov() -void foo() { + +class C { +public: +void bar(const short2&); +}; + +// CHECK-LABEL: define{{.*}} spir_func void @_Z6scalarv() +void scalar() { // The generic addr space reference parameter object will be bound // to a temporary value allocated in private addr space. We need an // addrspacecast before passing the value to the function. @@ -12,3 +20,14 @@ // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* align 4 dereferenceable(4) [[REG]]) bar(1); } + +// Test list initialization +// CHECK-LABEL: define{{.*}} spir_func void @_Z4listv() +void list() { + C c1; +// CHECK: [[REF:%.*]] = alloca <2 x i16> +// CHECK: store <2 x i16> <i16 1, i16 2>, <2 x i16>* [[REF]] +// CHECK: [[REG:%[.a-z0-9]+]] = addrspacecast <2 x i16>* [[REF]] to <2 x i16> addrspace(4)* +// CHECK: call {{.*}}void @_ZNU3AS41C3barERU3AS4KDv2_s(%class.C addrspace(4)* {{.*}}, <2 x i16> addrspace(4)*{{.*}} [[REG]]) + c1.bar({1, 2}); +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -4289,17 +4289,24 @@ if (Sequence.step_begin() != Sequence.step_end()) Sequence.RewrapReferenceInitList(cv1T1, InitList); } - + // Ignore address space of reference type at this point and perform address + // space conversion after the reference binding step. + QualType cv1T1IgnoreAS = + T1Quals.hasAddressSpace() + ? S.Context.getQualifiedType(T1, T1Quals.withoutAddressSpace()) + : cv1T1; // Not reference-related. Create a temporary and bind to that. - InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1); + InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1IgnoreAS); TryListInitialization(S, TempEntity, Kind, InitList, Sequence, TreatUnavailableAsInvalid); if (Sequence) { if (DestType->isRValueReferenceType() || - (T1Quals.hasConst() && !T1Quals.hasVolatile())) - Sequence.AddReferenceBindingStep(cv1T1, /*BindingTemporary=*/true); - else + (T1Quals.hasConst() && !T1Quals.hasVolatile())) { + Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*BindingTemporary=*/true); + if (T1Quals.hasAddressSpace()) + Sequence.AddQualificationConversionStep(cv1T1, VK_XValue); + } else Sequence.SetFailed( InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits