Author: ShashwathiNavada Date: 2025-09-04T12:08:19+05:30 New Revision: e90e76e15dee4b835b9b2cfd55c0c3f047bb6d76
URL: https://github.com/llvm/llvm-project/commit/e90e76e15dee4b835b9b2cfd55c0c3f047bb6d76 DIFF: https://github.com/llvm/llvm-project/commit/e90e76e15dee4b835b9b2cfd55c0c3f047bb6d76.diff LOG: Trying to fix undefined symbol error caused by iterator variable (#141507) When a mapper is declared with an iterator variable inside the map clause, it results in unintended behavior due to the iterator being implicitly created but left uninitialized. Testcase: ``` typedef struct myvec{ size_t len; double *data; } myvec_t; #pragma omp declare mapper(id:myvec_t v) map( iterator( iterator_variable=0:v.len), tofrom: v.data[iterator_variable]) int main() { int errors = 0; myvec_t s; #pragma omp target map(mapper(id), to:s) { } return 0; } ``` The error we get while compiling this is: ``` /usr/lib64/gcc/x86_64-suse-linux/14/../../../../x86_64-suse-linux/bin/ld: /tmp/test-f70647.o: in function `.omp_mapper._ZTS5myvec.id': test.cpp:(.text+0x21a): undefined reference to `iterator_variable' /llvm-project/install/bin/clang-linker-wrapper: error: 'ld' failed clang++: error: linker command failed with exit code 1 (use -v to see invocation) ``` This patch tries to fix this by initializing the iterator variable to a null constant. --------- Co-authored-by: Shashwathi N <[email protected]> Added: Modified: clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/declare_mapper_codegen.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ebd5aa2b9bc11..a1dd5b090c59b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaOpenMP.h" +#include "clang/AST/ASTConsumer.h" #include "TreeTransform.h" #include "clang/AST/ASTContext.h" @@ -22647,8 +22648,16 @@ ExprResult SemaOpenMP::ActOnOpenMPDeclareMapperDirectiveVarDecl( } void SemaOpenMP::ActOnOpenMPIteratorVarDecl(VarDecl *VD) { - if (DSAStack->getDeclareMapperVarRef()) + bool IsGlobalVar = + !VD->isLocalVarDecl() && VD->getDeclContext()->isTranslationUnit(); + if (DSAStack->getDeclareMapperVarRef()) { + if (IsGlobalVar) + SemaRef.Consumer.HandleTopLevelDecl(DeclGroupRef(VD)); DSAStack->addIteratorVarDecl(VD); + } else { + // Currently, only declare mapper handles global-scope iterator vars. + assert(!IsGlobalVar && "Only declare mapper handles TU-scope iterators."); + } } bool SemaOpenMP::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { diff --git a/clang/test/OpenMP/declare_mapper_codegen.cpp b/clang/test/OpenMP/declare_mapper_codegen.cpp index 81453223b2a27..7dc32d0ae12ff 100644 --- a/clang/test/OpenMP/declare_mapper_codegen.cpp +++ b/clang/test/OpenMP/declare_mapper_codegen.cpp @@ -1055,4 +1055,106 @@ void foo(int a){ #endif // CK4 +///==========================================================================/// +// RUN: %clang_cc1 -DCK5 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm -femit-all-decls -disable-llvm-passes %s -o - | FileCheck --check-prefix CK5 %s +// RUN: %clang_cc1 -DCK5 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -femit-all-decls -disable-llvm-passes -o %t %s +// RUN: %clang_cc1 -DCK5 -verify -fopenmp-version=52 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm -femit-all-decls -disable-llvm-passes %s -o - | FileCheck --check-prefix CK5 %s +// RUN: %clang_cc1 -DCK5 -fopenmp -fopenmp-version=52 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -femit-all-decls -disable-llvm-passes -o %t %s + +// RUN: %clang_cc1 -DCK5 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm -femit-all-decls -disable-llvm-passes %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK5 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -femit-all-decls -disable-llvm-passes -o %t %s +// RUN: %clang_cc1 -DCK5 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm -femit-all-decls -disable-llvm-passes %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK5 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -femit-all-decls -disable-llvm-passes -o %t %s + +#ifdef CK5 +typedef struct myvec { + int a; + double *b; +} myvec_t; + +#pragma omp declare mapper(id: myvec_t v) map(iterator(it=0:v.a), tofrom: v.b[it]) +// CK5: @[[ITER:[a-zA-Z0-9_]+]] = global i32 0, align 4 + +void foo(){ + myvec_t s; + #pragma omp target map(mapper(id), to:s) + { + } +} + +// CK5: define {{.*}}void [[MPRFUNC:@[.]omp_mapper[.].*myvec[.]id]](ptr noundef [[HANDLE:%.+]], ptr noundef [[BPTR:%.+]], ptr noundef [[BEGIN:%.+]], i64 noundef [[BYTESIZE:%.+]], i64 noundef [[TYPE:%.+]], ptr{{.*}}) +// CK5-DAG: [[SIZE:%.+]] = udiv exact i64 [[BYTESIZE]], {{.*}} +// CK5-DAG: [[PTREND:%.+]] = getelementptr %struct.myvec, ptr [[BEGIN]], i64 [[SIZE]] +// CK5-DAG: [[ISARRAY:%.+]] = icmp sgt i64 [[SIZE]], 1 +// CK5-DAG: [[PTRSNE:%.+]] = icmp ne ptr [[BPTR]], [[BEGIN]] +// CK5-DAG: [[PTRANDOBJ:%.+]] = and i64 [[TYPE]], 16 +// CK5-DAG: [[ISPTRANDOBJ:%.+]] = icmp ne i64 [[PTRANDOBJ]], 0 +// CK5-DAG: [[CMPA:%.+]] = and i1 [[PTRSNE]], [[ISPTRANDOBJ]] +// CK5-DAG: [[CMP:%.+]] = or i1 [[ISARRAY]], [[CMPA]] +// CK5-DAG: [[TYPEDEL:%.+]] = and i64 [[TYPE]], 8 +// CK5-DAG: [[ISNOTDEL:%.+]] = icmp eq i64 [[TYPEDEL]], 0 +// CK5-DAG: [[CMP1:%.+]] = and i1 [[CMP]], [[ISNOTDEL]] +// CK5: br i1 [[CMP1]], label %[[INITEVALDEL:[^,]+]], label %[[LHEAD:[^,]+]] + +// CK5: [[INITEVALDEL]] +// CK5-DAG: [[ARRSIZE:%.+]] = mul nuw i64 [[SIZE]], {{.*}} + +// Remove movement mappings and mark as implicit +// CK5-DAG: [[ITYPE:%.+]] = and i64 [[TYPE]], -4 +// CK5-DAG: [[ITYPE1:%.+]] = or i64 [[ITYPE]], 512 +// CK5: call void @__tgt_push_mapper_component(ptr [[HANDLE]], ptr [[BPTR]], ptr [[BEGIN]], i64 [[ARRSIZE]], i64 [[ITYPE1]], {{.*}}) +// CK5: br label %[[LHEAD:[^,]+]] + +// CK5: [[LHEAD]] +// CK5: [[ISEMPTY:%.+]] = icmp eq ptr [[BEGIN]], [[PTREND]] +// CK5: br i1 [[ISEMPTY]], label %[[DONE:[^,]+]], label %[[LBODY:[^,]+]] +// CK5: [[LBODY]] +// CK5: [[PTR:%.+]] = phi ptr [ [[BEGIN]], %{{.+}} ], [ [[PTRNEXT:%.+]], %[[LCORRECT:[^,]+]] ] +// CK5-DAG: [[ABEGIN:%.+]] = getelementptr inbounds nuw %struct.myvec, ptr [[PTR]], i32 0, i32 1 +// CK5-DAG: load i32, ptr @[[ITER]], align 4 +// CK5-DAG: [[PRESIZE:%.+]] = call i64 @__tgt_mapper_num_components(ptr [[HANDLE]]) +// CK5-DAG: [[SHIPRESIZE:%.+]] = shl i64 [[PRESIZE]], 48 +// CK5-DAG: [[MEMBERTYPE:%.+]] = add nuw i64 0, [[SHIPRESIZE]] +// CK5-DAG: [[TYPETF:%.+]] = and i64 [[TYPE]], 3 +// CK5-DAG: [[ISALLOC:%.+]] = icmp eq i64 [[TYPETF]], 0 +// CK5-DAG: br i1 [[ISALLOC]], label %[[ALLOC:[^,]+]], label %[[ALLOCELSE:[^,]+]] +// CK5-DAG: [[ALLOC]] +// CK5-DAG: [[ALLOCTYPE:%.+]] = and i64 [[MEMBERTYPE]], -4 +// CK5-DAG: br label %[[TYEND:[^,]+]] +// CK5-DAG: [[ALLOCELSE]] +// CK5-DAG: [[ISTO:%.+]] = icmp eq i64 [[TYPETF]], 1 +// CK5-DAG: br i1 [[ISTO]], label %[[TO:[^,]+]], label %[[TOELSE:[^,]+]] +// CK5-DAG: [[TO]] +// CK5-DAG: [[TOTYPE:%.+]] = and i64 [[MEMBERTYPE]], -3 +// CK5-DAG: br label %[[TYEND]] +// CK5-DAG: [[TOELSE]] +// CK5-DAG: [[ISFROM:%.+]] = icmp eq i64 [[TYPETF]], 2 +// CK5-DAG: br i1 [[ISFROM]], label %[[FROM:[^,]+]], label %[[TYEND]] +// CK5-DAG: [[FROM]] +// CK5-DAG: [[FROMTYPE:%.+]] = and i64 [[MEMBERTYPE]], -2 +// CK5-DAG: br label %[[TYEND]] +// CK5-DAG: [[TYEND]] +// CK5-DAG: [[TYPE1:%.+]] = phi i64 [ [[ALLOCTYPE]], %[[ALLOC]] ], [ [[TOTYPE]], %[[TO]] ], [ [[FROMTYPE]], %[[FROM]] ], [ [[MEMBERTYPE]], %[[TOELSE]] ] +// CK5: call void @__tgt_push_mapper_component(ptr [[HANDLE]], ptr [[PTR]], ptr [[ABEGIN]], i64 {{.*}}, i64 [[TYPE1]], {{.*}}) +// CK5: [[PTRNEXT]] = getelementptr %struct.myvec, ptr [[PTR]], i32 1 +// CK5: [[ISDONE:%.+]] = icmp eq ptr [[PTRNEXT]], [[PTREND]] +// CK5: br i1 [[ISDONE]], label %[[LEXIT:[^,]+]], label %[[LBODY]] + +// CK5: [[LEXIT]] +// CK5: [[ISARRAY:%.+]] = icmp sgt i64 [[SIZE]], 1 +// CK5: [[TYPEDEL:%.+]] = and i64 [[TYPE]], 8 +// CK5: [[ISNOTDEL:%.+]] = icmp ne i64 [[TYPEDEL]], {{.*}} +// CK5: [[CMP1:%.+]] = and i1 [[ISARRAY]], [[ISNOTDEL]] +// CK5-DAG: [[ARRSIZE:%.+]] = mul nuw i64 [[SIZE]], {{.*}} + +// Remove movement mappings and mark as implicit +// CK5-DAG: [[DTYPE:%.+]] = and i64 [[TYPE]], -4 +// CK5-DAG: [[DTYPE1:%.+]] = or i64 [[DTYPE]], 512 +// CK5: call void @__tgt_push_mapper_component(ptr [[HANDLE]], ptr [[BPTR]], ptr [[BEGIN]], i64 [[ARRSIZE]], i64 [[DTYPE1]], {{.*}}) +// CK5: br label %[[DONE]] +// CK5: [[DONE]] +// CK5: ret void + +#endif // CK5 + #endif // HEADER _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
