Joseph Huber d5d836635c [Libomptarget] Add test config for compiling in LTO-mode
We are planning on making LTO the default compilation mode for
offloading. In order to make sure it works we should run these tests on
the test suite. AMDGPU already uses the LTO compilation path for its
linking, but in LTO mode it also links the static library late.

Performing LTO requires the static library to be built, if we make the
change this will be a hard requirement and the old bitcode library will
go away. This means users will need to use either a two-step build or a
runtimes build for libomptarget.

Reviewed By: JonChesterfield

Differential Revision: https://reviews.llvm.org/D127512
2022-06-14 10:16:03 -04:00

155 lines
4.3 KiB
C

// Check that specifying device as omp_get_initial_device():
// - Doesn't cause the runtime to fail.
// - Offloads code to the host.
// - Doesn't transfer data. In this case, just check that neither host data nor
// default device data are affected by the specified transfers.
// - Works whether it's specified directly or as the default device.
// RUN: %libomptarget-compile-run-and-check-generic
// amdgpu does not have a working printf definition
// XFAIL: amdgcn-amd-amdhsa
// XFAIL: amdgcn-amd-amdhsa-oldDriver
// XFAIL: amdgcn-amd-amdhsa-LTO
#include <stdio.h>
#include <omp.h>
static void check(char *X, int Dev) {
printf(" host X = %c\n", *X);
#pragma omp target device(Dev)
printf("device X = %c\n", *X);
}
#define CHECK_DATA() check(&X, DevDefault)
int main(void) {
int DevDefault = omp_get_default_device();
int DevInit = omp_get_initial_device();
//--------------------------------------------------
// Initialize data on the host and default device.
//--------------------------------------------------
// CHECK: host X = h
// CHECK-NEXT: device X = d
char X = 'd';
#pragma omp target enter data map(to:X)
X = 'h';
CHECK_DATA();
//--------------------------------------------------
// Check behavior when specifying host directly.
//--------------------------------------------------
// CHECK-NEXT: omp_is_initial_device() = 1
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target device(DevInit) map(always,tofrom:X)
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
CHECK_DATA();
// CHECK-NEXT: omp_is_initial_device() = 1
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target teams device(DevInit) num_teams(1) map(always,tofrom:X)
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
CHECK_DATA();
// Check that __kmpc_push_target_tripcount_mapper doesn't fail. I'm not sure
// how to check that it actually pushes to the initial device.
#pragma omp target teams device(DevInit) num_teams(1)
#pragma omp distribute
for (int i = 0; i < 2; ++i)
;
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target data device(DevInit) map(always,tofrom:X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target enter data device(DevInit) map(always,to:X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target exit data device(DevInit) map(always,from:X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target update device(DevInit) to(X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target update device(DevInit) from(X)
;
CHECK_DATA();
//--------------------------------------------------
// Check behavior when device defaults to host.
//--------------------------------------------------
omp_set_default_device(DevInit);
// CHECK-NEXT: omp_is_initial_device() = 1
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target map(always,tofrom:X)
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
CHECK_DATA();
// CHECK-NEXT: omp_is_initial_device() = 1
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target teams num_teams(1) map(always,tofrom:X)
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
CHECK_DATA();
// Check that __kmpc_push_target_tripcount_mapper doesn't fail. I'm not sure
// how to check that it actually pushes to the initial device.
#pragma omp target teams num_teams(1)
#pragma omp distribute
for (int i = 0; i < 2; ++i)
;
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target data map(always,tofrom:X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target enter data map(always,to:X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target exit data map(always,from:X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target update to(X)
;
CHECK_DATA();
// CHECK-NEXT: host X = h
// CHECK-NEXT: device X = d
#pragma omp target update from(X)
;
CHECK_DATA();
return 0;
}