[libomptarget-nvptx] Align data sharing stack
NVPTX requires addresses of pointer locations to be 8-byte aligned or there will be an exception during runtime. This could happen without this patch as shown in the added test: getId() requires 4 byte of stack and putValueInParallel() uses 16 bytes to store the addresses of the captured variables. Differential Revision: https://reviews.llvm.org/D52655 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@343402 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -384,6 +384,13 @@ EXTERN void* __kmpc_data_sharing_push_stack(size_t DataSize,
|
||||
return omptarget_nvptx_SimpleThreadPrivateContext::Allocate(DataSize);
|
||||
}
|
||||
|
||||
// Add worst-case padding to DataSize so that future stack allocations are
|
||||
// correctly aligned.
|
||||
const size_t Alignment = 8;
|
||||
if (DataSize % Alignment != 0) {
|
||||
DataSize += (Alignment - DataSize % Alignment);
|
||||
}
|
||||
|
||||
// Frame pointer must be visible to all workers in the same warp.
|
||||
unsigned WID = getWarpId();
|
||||
void *&FrameP = DataSharingState.FramePtr[WID];
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// RUN: %compile-run-and-check
|
||||
|
||||
#include <omp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma omp declare target
|
||||
static void putValueInParallel(int *ptr, int value) {
|
||||
#pragma omp parallel
|
||||
{
|
||||
*ptr = value;
|
||||
}
|
||||
}
|
||||
|
||||
static int getId() {
|
||||
int id;
|
||||
putValueInParallel(&id, omp_get_thread_num());
|
||||
return id;
|
||||
}
|
||||
#pragma omp end declare target
|
||||
|
||||
const int MaxThreads = 1024;
|
||||
const int Threads = 64;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int master;
|
||||
int check[MaxThreads];
|
||||
for (int i = 0; i < MaxThreads; i++) {
|
||||
check[i] = 0;
|
||||
}
|
||||
|
||||
#pragma omp target map(master, check[:])
|
||||
{
|
||||
master = getId();
|
||||
|
||||
#pragma omp parallel num_threads(Threads)
|
||||
{
|
||||
check[omp_get_thread_num()] = getId();
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: master = 0.
|
||||
printf("master = %d.\n", master);
|
||||
// CHECK-NOT: invalid
|
||||
for (int i = 0; i < MaxThreads; i++) {
|
||||
if (i < Threads) {
|
||||
if (check[i] != i) {
|
||||
printf("invalid: check[%d] should be %d, is %d\n", i, i, check[i]);
|
||||
}
|
||||
} else if (check[i] != 0) {
|
||||
printf("invalid: check[%d] should be 0, is %d\n", i, check[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user