Skip to content

Commit e90e76e

Browse files
ShashwathiNavadaShashwathi N
andauthored
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]>
1 parent 9971844 commit e90e76e

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "clang/Sema/SemaOpenMP.h"
15+
#include "clang/AST/ASTConsumer.h"
1516

1617
#include "TreeTransform.h"
1718
#include "clang/AST/ASTContext.h"
@@ -22647,8 +22648,16 @@ ExprResult SemaOpenMP::ActOnOpenMPDeclareMapperDirectiveVarDecl(
2264722648
}
2264822649

2264922650
void SemaOpenMP::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22650-
if (DSAStack->getDeclareMapperVarRef())
22651+
bool IsGlobalVar =
22652+
!VD->isLocalVarDecl() && VD->getDeclContext()->isTranslationUnit();
22653+
if (DSAStack->getDeclareMapperVarRef()) {
22654+
if (IsGlobalVar)
22655+
SemaRef.Consumer.HandleTopLevelDecl(DeclGroupRef(VD));
2265122656
DSAStack->addIteratorVarDecl(VD);
22657+
} else {
22658+
// Currently, only declare mapper handles global-scope iterator vars.
22659+
assert(!IsGlobalVar && "Only declare mapper handles TU-scope iterators.");
22660+
}
2265222661
}
2265322662

2265422663
bool SemaOpenMP::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {

clang/test/OpenMP/declare_mapper_codegen.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,4 +1055,106 @@ void foo(int a){
10551055

10561056
#endif // CK4
10571057

1058+
///==========================================================================///
1059+
// 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
1060+
// 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
1061+
// 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
1062+
// 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
1063+
1064+
// 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
1065+
// 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
1066+
// 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
1067+
// 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
1068+
1069+
#ifdef CK5
1070+
typedef struct myvec {
1071+
int a;
1072+
double *b;
1073+
} myvec_t;
1074+
1075+
#pragma omp declare mapper(id: myvec_t v) map(iterator(it=0:v.a), tofrom: v.b[it])
1076+
// CK5: @[[ITER:[a-zA-Z0-9_]+]] = global i32 0, align 4
1077+
1078+
void foo(){
1079+
myvec_t s;
1080+
#pragma omp target map(mapper(id), to:s)
1081+
{
1082+
}
1083+
}
1084+
1085+
// CK5: define {{.*}}void [[MPRFUNC:@[.]omp_mapper[.].*myvec[.]id]](ptr noundef [[HANDLE:%.+]], ptr noundef [[BPTR:%.+]], ptr noundef [[BEGIN:%.+]], i64 noundef [[BYTESIZE:%.+]], i64 noundef [[TYPE:%.+]], ptr{{.*}})
1086+
// CK5-DAG: [[SIZE:%.+]] = udiv exact i64 [[BYTESIZE]], {{.*}}
1087+
// CK5-DAG: [[PTREND:%.+]] = getelementptr %struct.myvec, ptr [[BEGIN]], i64 [[SIZE]]
1088+
// CK5-DAG: [[ISARRAY:%.+]] = icmp sgt i64 [[SIZE]], 1
1089+
// CK5-DAG: [[PTRSNE:%.+]] = icmp ne ptr [[BPTR]], [[BEGIN]]
1090+
// CK5-DAG: [[PTRANDOBJ:%.+]] = and i64 [[TYPE]], 16
1091+
// CK5-DAG: [[ISPTRANDOBJ:%.+]] = icmp ne i64 [[PTRANDOBJ]], 0
1092+
// CK5-DAG: [[CMPA:%.+]] = and i1 [[PTRSNE]], [[ISPTRANDOBJ]]
1093+
// CK5-DAG: [[CMP:%.+]] = or i1 [[ISARRAY]], [[CMPA]]
1094+
// CK5-DAG: [[TYPEDEL:%.+]] = and i64 [[TYPE]], 8
1095+
// CK5-DAG: [[ISNOTDEL:%.+]] = icmp eq i64 [[TYPEDEL]], 0
1096+
// CK5-DAG: [[CMP1:%.+]] = and i1 [[CMP]], [[ISNOTDEL]]
1097+
// CK5: br i1 [[CMP1]], label %[[INITEVALDEL:[^,]+]], label %[[LHEAD:[^,]+]]
1098+
1099+
// CK5: [[INITEVALDEL]]
1100+
// CK5-DAG: [[ARRSIZE:%.+]] = mul nuw i64 [[SIZE]], {{.*}}
1101+
1102+
// Remove movement mappings and mark as implicit
1103+
// CK5-DAG: [[ITYPE:%.+]] = and i64 [[TYPE]], -4
1104+
// CK5-DAG: [[ITYPE1:%.+]] = or i64 [[ITYPE]], 512
1105+
// CK5: call void @__tgt_push_mapper_component(ptr [[HANDLE]], ptr [[BPTR]], ptr [[BEGIN]], i64 [[ARRSIZE]], i64 [[ITYPE1]], {{.*}})
1106+
// CK5: br label %[[LHEAD:[^,]+]]
1107+
1108+
// CK5: [[LHEAD]]
1109+
// CK5: [[ISEMPTY:%.+]] = icmp eq ptr [[BEGIN]], [[PTREND]]
1110+
// CK5: br i1 [[ISEMPTY]], label %[[DONE:[^,]+]], label %[[LBODY:[^,]+]]
1111+
// CK5: [[LBODY]]
1112+
// CK5: [[PTR:%.+]] = phi ptr [ [[BEGIN]], %{{.+}} ], [ [[PTRNEXT:%.+]], %[[LCORRECT:[^,]+]] ]
1113+
// CK5-DAG: [[ABEGIN:%.+]] = getelementptr inbounds nuw %struct.myvec, ptr [[PTR]], i32 0, i32 1
1114+
// CK5-DAG: load i32, ptr @[[ITER]], align 4
1115+
// CK5-DAG: [[PRESIZE:%.+]] = call i64 @__tgt_mapper_num_components(ptr [[HANDLE]])
1116+
// CK5-DAG: [[SHIPRESIZE:%.+]] = shl i64 [[PRESIZE]], 48
1117+
// CK5-DAG: [[MEMBERTYPE:%.+]] = add nuw i64 0, [[SHIPRESIZE]]
1118+
// CK5-DAG: [[TYPETF:%.+]] = and i64 [[TYPE]], 3
1119+
// CK5-DAG: [[ISALLOC:%.+]] = icmp eq i64 [[TYPETF]], 0
1120+
// CK5-DAG: br i1 [[ISALLOC]], label %[[ALLOC:[^,]+]], label %[[ALLOCELSE:[^,]+]]
1121+
// CK5-DAG: [[ALLOC]]
1122+
// CK5-DAG: [[ALLOCTYPE:%.+]] = and i64 [[MEMBERTYPE]], -4
1123+
// CK5-DAG: br label %[[TYEND:[^,]+]]
1124+
// CK5-DAG: [[ALLOCELSE]]
1125+
// CK5-DAG: [[ISTO:%.+]] = icmp eq i64 [[TYPETF]], 1
1126+
// CK5-DAG: br i1 [[ISTO]], label %[[TO:[^,]+]], label %[[TOELSE:[^,]+]]
1127+
// CK5-DAG: [[TO]]
1128+
// CK5-DAG: [[TOTYPE:%.+]] = and i64 [[MEMBERTYPE]], -3
1129+
// CK5-DAG: br label %[[TYEND]]
1130+
// CK5-DAG: [[TOELSE]]
1131+
// CK5-DAG: [[ISFROM:%.+]] = icmp eq i64 [[TYPETF]], 2
1132+
// CK5-DAG: br i1 [[ISFROM]], label %[[FROM:[^,]+]], label %[[TYEND]]
1133+
// CK5-DAG: [[FROM]]
1134+
// CK5-DAG: [[FROMTYPE:%.+]] = and i64 [[MEMBERTYPE]], -2
1135+
// CK5-DAG: br label %[[TYEND]]
1136+
// CK5-DAG: [[TYEND]]
1137+
// CK5-DAG: [[TYPE1:%.+]] = phi i64 [ [[ALLOCTYPE]], %[[ALLOC]] ], [ [[TOTYPE]], %[[TO]] ], [ [[FROMTYPE]], %[[FROM]] ], [ [[MEMBERTYPE]], %[[TOELSE]] ]
1138+
// CK5: call void @__tgt_push_mapper_component(ptr [[HANDLE]], ptr [[PTR]], ptr [[ABEGIN]], i64 {{.*}}, i64 [[TYPE1]], {{.*}})
1139+
// CK5: [[PTRNEXT]] = getelementptr %struct.myvec, ptr [[PTR]], i32 1
1140+
// CK5: [[ISDONE:%.+]] = icmp eq ptr [[PTRNEXT]], [[PTREND]]
1141+
// CK5: br i1 [[ISDONE]], label %[[LEXIT:[^,]+]], label %[[LBODY]]
1142+
1143+
// CK5: [[LEXIT]]
1144+
// CK5: [[ISARRAY:%.+]] = icmp sgt i64 [[SIZE]], 1
1145+
// CK5: [[TYPEDEL:%.+]] = and i64 [[TYPE]], 8
1146+
// CK5: [[ISNOTDEL:%.+]] = icmp ne i64 [[TYPEDEL]], {{.*}}
1147+
// CK5: [[CMP1:%.+]] = and i1 [[ISARRAY]], [[ISNOTDEL]]
1148+
// CK5-DAG: [[ARRSIZE:%.+]] = mul nuw i64 [[SIZE]], {{.*}}
1149+
1150+
// Remove movement mappings and mark as implicit
1151+
// CK5-DAG: [[DTYPE:%.+]] = and i64 [[TYPE]], -4
1152+
// CK5-DAG: [[DTYPE1:%.+]] = or i64 [[DTYPE]], 512
1153+
// CK5: call void @__tgt_push_mapper_component(ptr [[HANDLE]], ptr [[BPTR]], ptr [[BEGIN]], i64 [[ARRSIZE]], i64 [[DTYPE1]], {{.*}})
1154+
// CK5: br label %[[DONE]]
1155+
// CK5: [[DONE]]
1156+
// CK5: ret void
1157+
1158+
#endif // CK5
1159+
10581160
#endif // HEADER

0 commit comments

Comments
 (0)