diff --git a/openmp/README.rst b/openmp/README.rst --- a/openmp/README.rst +++ b/openmp/README.rst @@ -165,6 +165,12 @@ **LIBOMP_FORTRAN_MODULES** = ``OFF|ON`` Create the Fortran modules (requires Fortran compiler). + .. note:: + + If libomptarget is built in-tree with both flang and openmp in + `LLVM_ENABLE_PROJECTS`, flang will be used for Fortran offloading + tests. + macOS* Fat Libraries """""""""""""""""""" On macOS* machines, it is possible to build universal (or fat) libraries which diff --git a/openmp/libomptarget/test/CMakeLists.txt b/openmp/libomptarget/test/CMakeLists.txt --- a/openmp/libomptarget/test/CMakeLists.txt +++ b/openmp/libomptarget/test/CMakeLists.txt @@ -32,9 +32,13 @@ configure_file(lit.site.cfg.in ${CURRENT_TARGET}/lit.site.cfg @ONLY) endforeach() +if ("flang" IN_LIST LLVM_ENABLE_PROJECTS) + SET(FORTRAN_TEST_DEPS flang-new) +endif() + add_openmp_testsuite(check-libomptarget "Running libomptarget tests" ${LIBOMPTARGET_LIT_TESTSUITES} EXCLUDE_FROM_CHECK_ALL - DEPENDS omptarget omp ${LIBOMPTARGET_TESTED_PLUGINS} + DEPENDS omptarget omp ${LIBOMPTARGET_TESTED_PLUGINS} ${FORTRAN_TEST_DEPS} ARGS ${LIBOMPTARGET_LIT_ARG_LIST}) diff --git a/openmp/libomptarget/test/lit.cfg b/openmp/libomptarget/test/lit.cfg --- a/openmp/libomptarget/test/lit.cfg +++ b/openmp/libomptarget/test/lit.cfg @@ -4,6 +4,10 @@ import os import lit.formats +from lit.llvm import llvm_config +from lit.llvm.subst import ToolSubst +from lit.llvm.subst import FindTool + # Tell pylint that we know config and lit_config exist somewhere. if 'PYLINT_IMPORT' in os.environ: config = object() @@ -58,6 +62,8 @@ # test_exec_root: The root object directory where output is placed config.test_exec_root = config.libomptarget_obj_root +tools = [] + # test format config.test_format = lit.formats.ShTest() @@ -86,6 +92,10 @@ config.available_features.add(config.libomptarget_current_target) +if 'flang' in config.llvm_enabled_projects: + config.available_features.add('flang') + tools.append(ToolSubst('%flang', command=FindTool('flang-new'), unresolved='fatal')) + # Determine whether the test system supports unified memory. # For CUDA, this is the case with compute capability 70 (Volta) or higher. # For all other targets, we currently assume it is. @@ -300,3 +310,4 @@ config.substitutions.append(("%cuda_flags", "")) config.substitutions.append(("%flags", config.test_flags)) config.substitutions.append(("%not", config.libomptarget_not)) +llvm_config.add_tool_substitutions(tools, config.bin_llvm_tools_dir) diff --git a/openmp/libomptarget/test/lit.site.cfg.in b/openmp/libomptarget/test/lit.site.cfg.in --- a/openmp/libomptarget/test/lit.site.cfg.in +++ b/openmp/libomptarget/test/lit.site.cfg.in @@ -1,5 +1,6 @@ @AUTO_GEN_COMMENT@ +config.bin_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin" config.test_c_compiler = "@OPENMP_TEST_C_COMPILER@" config.test_cxx_compiler = "@OPENMP_TEST_CXX_COMPILER@" config.test_compiler_features = @OPENMP_TEST_COMPILER_FEATURES@ @@ -20,6 +21,10 @@ config.libomptarget_not = "@OPENMP_NOT_EXECUTABLE@" config.libomptarget_debug = @LIBOMPTARGET_DEBUG@ config.has_libomptarget_ompt = @LIBOMPTARGET_OMPT_SUPPORT@ +config.llvm_enabled_projects = "@LLVM_ENABLE_PROJECTS@".split(";") + +import lit.llvm +lit.llvm.initialize(lit_config, config) # Let the main config do the real work. lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") diff --git a/openmp/libomptarget/test/offloading/fortran/basic_array.c b/openmp/libomptarget/test/offloading/fortran/basic_array.c new file mode 100644 --- /dev/null +++ b/openmp/libomptarget/test/offloading/fortran/basic_array.c @@ -0,0 +1,43 @@ +// Basic offloading test for function compiled with flang +// REQUIRES: flang, amdgcn-amd-amdhsa + +// RUN: %flang -c -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa \ +// RUN: %S/basic_array.f90 -o basic_array.o +// RUN: %libomptarget-compile-generic basic_array.o +// RUN: %t | %fcheck-generic + +#include +#define TEST_ARR_LEN 10 + +#pragma omp declare target +void increment_at(int i, int *array); +#pragma omp end declare target + +void increment_array(int *b, int n) { +#pragma omp target map(tofrom : b [0:n]) + for (int i = 0; i < n; i++) { + increment_at(i, b); + } +} + +int main() { + int arr[TEST_ARR_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + increment_array(arr, TEST_ARR_LEN); + for (int i = 0; i < TEST_ARR_LEN; i++) { + printf("%d = %d\n", i, arr[i]); + } + + return 0; +} + +// CHECK: 0 = 1 +// CHECK-NEXT: 1 = 2 +// CHECK-NEXT: 2 = 3 +// CHECK-NEXT: 3 = 4 +// CHECK-NEXT: 4 = 5 +// CHECK-NEXT: 5 = 6 +// CHECK-NEXT: 6 = 7 +// CHECK-NEXT: 7 = 8 +// CHECK-NEXT: 8 = 9 +// CHECK-NEXT: 9 = 10 diff --git a/openmp/libomptarget/test/offloading/fortran/basic_array.f90 b/openmp/libomptarget/test/offloading/fortran/basic_array.f90 new file mode 100644 --- /dev/null +++ b/openmp/libomptarget/test/offloading/fortran/basic_array.f90 @@ -0,0 +1,6 @@ +subroutine increment_at(c_index, arr) bind(C, name="increment_at") + use ISO_C_BINDING + integer (C_INT), dimension(*), intent(inout) :: arr + integer (C_INT), value :: c_index + arr(c_index+1) = arr(c_index+1) + 1 +end subroutine