https://github.com/abhinavgaba updated https://github.com/llvm/llvm-project/pull/173930
>From 9824170fed25e52ee9a32b90e9d36a5385733b38 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 24 Nov 2025 13:43:20 -0800 Subject: [PATCH 01/16] [OpenMP] Preserve the original address by default on use_device_ptr/addr lookup failure. As per OpenMP 5.1, we need to assume that when the lookup for use_device_ptr/addr fails, the incoming pointer was already device accessible. Prior to 5.1, a lookup-failure meant a user-error, so we could do anything in that scenario. --- offload/libomptarget/omptarget.cpp | 34 +++++++++++++++++-- ...get_data_use_device_addr_arrsec_fallback.c | 2 -- ...target_data_use_device_addr_var_fallback.c | 2 -- .../target_data_use_device_ptr_var_fallback.c | 11 ------ 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp index 69725e77bae00..3dcc0144f6cf2 100644 --- a/offload/libomptarget/omptarget.cpp +++ b/offload/libomptarget/omptarget.cpp @@ -675,9 +675,37 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum, DataSize, DPxPTR(TgtPtrBegin), (TPR.Flags.IsNewEntry ? "" : " not")); if (ArgTypes[I] & OMP_TGT_MAPTYPE_RETURN_PARAM) { - uintptr_t Delta = (uintptr_t)HstPtrBegin - (uintptr_t)HstPtrBase; - void *TgtPtrBase = (void *)((uintptr_t)TgtPtrBegin - Delta); - DP("Returning device pointer " DPxMOD "\n", DPxPTR(TgtPtrBase)); + intptr_t Delta = reinterpret_cast<intptr_t>(HstPtrBegin) - + reinterpret_cast<intptr_t>(HstPtrBase); + void *TgtPtrBase; + if (TgtPtrBegin) { + // Lookup succeeded, return device pointer adjusted by delta + TgtPtrBase = reinterpret_cast<void *>( + reinterpret_cast<intptr_t>(TgtPtrBegin) - Delta); + DP("Returning device pointer " DPxMOD "\n", DPxPTR(TgtPtrBase)); + } else { + // Lookup failed. So we have to decide what to do based on the + // requested fallback behavior. + // + // Treat "preserve" as the default fallback behavior, since as per + // OpenMP 5.1, for use_device_ptr/addr, when there's no corresponding + // device pointer to translate into, it's the user's responsibility to + // ensure that the host address is device-accessible. + // + // OpenMP 5.1, sec 2.14.2, target data construct, p 188, l26-31: + // If a list item that appears in a use_device_ptr clause ... does not + // point to a mapped object, it must contain a valid device address for + // the target device, and the list item references are instead converted + // to references to a local device pointer that refers to this device + // address. + // + // TODO: Support OpenMP 6.1's "fb_nullify" and set the result to + // `null - Delta`. + TgtPtrBase = reinterpret_cast<void *>( + reinterpret_cast<intptr_t>(HstPtrBegin) - Delta); + DP("Returning host pointer " DPxMOD " as fallback (lookup failed).\n", + DPxPTR(TgtPtrBase)); + } ArgsBase[I] = TgtPtrBase; } diff --git a/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_fallback.c b/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_fallback.c index 4b67a3bc2aa7f..118b664fb6e53 100644 --- a/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_fallback.c +++ b/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_fallback.c @@ -7,8 +7,6 @@ // list-item is device-accessible, even if it was not // previously mapped. -// XFAIL: * - #include <stdio.h> int h[10]; int *ph = &h[0]; diff --git a/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_fallback.c b/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_fallback.c index 4495a46b6d204..4b0819ef6a9fe 100644 --- a/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_fallback.c +++ b/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_fallback.c @@ -7,8 +7,6 @@ // list-item is device-accessible, even if it was not // previously mapped. -// XFAIL: * - #include <stdio.h> int x; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c index e8fa3b69e9296..33a363495e24a 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c @@ -7,17 +7,6 @@ // This is necessary because we must assume that the // pointee is device-accessible, even if it was not // previously mapped. -// -// OpenMP 5.1, sec 2.14.2, target data construct, p 188, l26-31: -// If a list item that appears in a use_device_ptr clause ... does not point to -// a mapped object, it must contain a valid device address for the target -// device, and the list item references are instead converted to references to a -// local device pointer that refers to this device address. -// -// Note: OpenMP 6.1 will have a way to change the -// fallback behavior: preserve or nullify. - -// XFAIL: * #include <stdio.h> int x; >From 8e007d1380a31124a46a67f96599bf89d7f00c3e Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 24 Nov 2025 15:49:31 -0800 Subject: [PATCH 02/16] Update some tests that were relying on the previous behavior. --- ...ta_use_device_addr_arrsec_not_existing.cpp | 20 ++++--------- ...se_device_addr_arrsec_ref_not_existing.cpp | 28 +++++-------------- ..._data_use_device_addr_var_not_existing.cpp | 21 ++++---------- ...a_use_device_addr_var_ref_not_existing.cpp | 21 ++++---------- .../target_wrong_use_device_addr.c | 5 ++-- ...arget_data_use_device_ptr_not_existing.cpp | 19 ++++--------- ...t_data_use_device_ptr_ref_not_existing.cpp | 27 ++++++------------ 7 files changed, 41 insertions(+), 100 deletions(-) diff --git a/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_not_existing.cpp b/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_not_existing.cpp index b9ebde431e7bf..78e6bf7c070a0 100644 --- a/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_not_existing.cpp +++ b/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_not_existing.cpp @@ -8,15 +8,6 @@ // Test for various cases of use_device_addr on an array-section. // The corresponding data is not previously mapped. -// Note that this tests for the current behavior wherein if a lookup fails, -// the runtime returns nullptr, instead of the original host-address. -// That was compatible with OpenMP 5.0, where it was a user error if -// corresponding storage didn't exist, but with 5.1+, the runtime needs to -// return the host address, as it needs to assume that the host-address is -// device-accessible, as the user has guaranteed it. -// Once the runtime returns the original host-address when the lookup fails, the -// test will need to be updated. - int g, h[10]; int *ph = &h[0]; @@ -36,7 +27,7 @@ struct S { int *mapped_ptr_ph3 = (int *)omp_get_mapped_ptr(original_ph3, omp_get_default_device()); printf("A: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_ph3, &ph[3] == (int *)nullptr + 3); + mapped_ptr_ph3 != original_ph3, &ph[3] == original_ph3); } // (B) use_device_addr/map: different operands, same base-pointer. @@ -58,7 +49,7 @@ struct S { int *mapped_ptr_ph3 = (int *)omp_get_mapped_ptr(original_ph3, omp_get_default_device()); printf("C: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_ph3, &ph[3] == (int *)nullptr + 3); + mapped_ptr_ph3 != original_ph3, &ph[3] == original_ph3); } // (D) use_device_addr/map: one of two maps with matching base-pointer. @@ -80,8 +71,7 @@ struct S { int **mapped_ptr_paa02 = (int **)omp_get_mapped_ptr(original_paa02, omp_get_default_device()); printf("E: %d %d %d\n", mapped_ptr_paa02 == nullptr, - mapped_ptr_paa02 != original_paa02, - &paa[0][2] == (int **)nullptr + 2); + mapped_ptr_paa02 != original_paa02, &paa[0][2] == original_paa02); } // (F) use_device_addr/map: different operands, same base-array. @@ -110,7 +100,7 @@ struct S { } int *original_paa020 = &paa[0][2][0]; - int **original_paa0 = (int **)&paa[0]; + void *original_paa0 = &paa[0]; // (H) use_device_addr/map: different base-pointers. // No corresponding storage for use_device_addr opnd, lookup should fail. @@ -122,7 +112,7 @@ struct S { int **mapped_ptr_paa0 = (int **)omp_get_mapped_ptr(original_paa0, omp_get_default_device()); printf("H: %d %d %d\n", mapped_ptr_paa020 != nullptr, - mapped_ptr_paa0 == nullptr, &paa[0] == nullptr); + mapped_ptr_paa0 == nullptr, &paa[0] == original_paa0); } // (I) use_device_addr/map: one map with different, one with same base-ptr. diff --git a/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_ref_not_existing.cpp b/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_ref_not_existing.cpp index 0090cdb095366..d981da925acc2 100644 --- a/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_ref_not_existing.cpp +++ b/offload/test/mapping/use_device_addr/target_data_use_device_addr_arrsec_ref_not_existing.cpp @@ -8,15 +8,6 @@ // Test for various cases of use_device_addr on an array-section on a reference. // The corresponding data is not previously mapped. -// Note that this tests for the current behavior wherein if a lookup fails, -// the runtime returns nullptr, instead of the original host-address. -// That was compatible with OpenMP 5.0, where it was a user error if -// corresponding storage didn't exist, but with 5.1+, the runtime needs to -// return the host address, as it needs to assume that the host-address is -// device-accessible, as the user has guaranteed it. -// Once the runtime returns the original host-address when the lookup fails, the -// test will need to be updated. - int g_ptee; int &g = g_ptee; @@ -37,15 +28,13 @@ struct S { int **original_paa02 = &paa[0][2]; // (A) No corresponding map, lookup should fail. -// EXPECTED: A: 1 1 1 -// CHECK: A: 1 1 0 -// FIXME: ph is not being privatized in the region. +// CHECK: A: 1 1 1 #pragma omp target data use_device_addr(ph[3 : 4]) { int *mapped_ptr_ph3 = (int *)omp_get_mapped_ptr(original_ph3, omp_get_default_device()); printf("A: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_ph3, &ph[3] == (int *)nullptr + 3); + mapped_ptr_ph3 != original_ph3, &ph[3] == original_ph3); } // (B) use_device_addr/map: different operands, same base-pointer. @@ -63,15 +52,13 @@ struct S { // (C) use_device_addr/map: different base-pointers. // No corresponding storage, lookup should fail. -// EXPECTED: C: 1 1 1 -// CHECK: C: 1 1 0 -// FIXME: ph is not being privatized in the region. +// CHECK: C: 1 1 1 #pragma omp target data map(ph) use_device_addr(ph[3 : 4]) { int *mapped_ptr_ph3 = (int *)omp_get_mapped_ptr(original_ph3, omp_get_default_device()); printf("C: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_ph3, &ph[3] == (int *)nullptr + 3); + mapped_ptr_ph3 != original_ph3, &ph[3] == original_ph3); } // (D) use_device_addr/map: one of two maps with matching base-pointer. @@ -95,8 +82,7 @@ struct S { int **mapped_ptr_paa02 = (int **)omp_get_mapped_ptr(original_paa02, omp_get_default_device()); printf("E: %d %d %d\n", mapped_ptr_paa02 == nullptr, - mapped_ptr_paa02 != original_paa02, - &paa[0][2] == (int **)nullptr + 2); + mapped_ptr_paa02 != original_paa02, &paa[0][2] == original_paa02); } // (F) use_device_addr/map: different operands, same base-array. @@ -125,7 +111,7 @@ struct S { } int *original_paa020 = &paa[0][2][0]; - int **original_paa0 = (int **)&paa[0]; + void *original_paa0 = &paa[0]; // (H) use_device_addr/map: different base-pointers. // No corresponding storage for use_device_addr opnd, lookup should fail. @@ -137,7 +123,7 @@ struct S { int **mapped_ptr_paa0 = (int **)omp_get_mapped_ptr(original_paa0, omp_get_default_device()); printf("H: %d %d %d\n", mapped_ptr_paa020 != nullptr, - mapped_ptr_paa0 == nullptr, &paa[0] == nullptr); + mapped_ptr_paa0 == nullptr, &paa[0] == original_paa0); } // (I) use_device_addr/map: one map with different, one with same base-ptr. diff --git a/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_not_existing.cpp b/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_not_existing.cpp index 79c6f69edba8e..e855b0dd82744 100644 --- a/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_not_existing.cpp +++ b/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_not_existing.cpp @@ -8,15 +8,6 @@ // Test for various cases of use_device_addr on a variable (not a section). // The corresponding data is not previously mapped. -// Note that this tests for the current behavior wherein if a lookup fails, -// the runtime returns nullptr, instead of the original host-address. -// That was compatible with OpenMP 5.0, where it was a user error if -// corresponding storage didn't exist, but with 5.1+, the runtime needs to -// return the host address, as it needs to assume that the host-address is -// device-accessible, as the user has guaranteed it. -// Once the runtime returns the original host-address when the lookup fails, the -// test will need to be updated. - int g, h[10]; int *ph = &h[0]; @@ -38,7 +29,7 @@ struct S { void *mapped_ptr_g = omp_get_mapped_ptr(original_addr_g, omp_get_default_device()); printf("A: %d %d %d\n", mapped_ptr_g == nullptr, - mapped_ptr_g != original_addr_g, (void *)&g == nullptr); + mapped_ptr_g != original_addr_g, &g == original_addr_g); } // (B) Lookup should succeed. @@ -58,7 +49,7 @@ struct S { void *mapped_ptr_h = omp_get_mapped_ptr(original_addr_h, omp_get_default_device()); printf("C: %d %d %d\n", mapped_ptr_h == nullptr, - mapped_ptr_h != original_addr_h, (void *)&h == nullptr); + mapped_ptr_h != original_addr_h, &h == original_addr_h); } // (D) Lookup should succeed. @@ -78,7 +69,7 @@ struct S { void *mapped_ptr_ph = omp_get_mapped_ptr(original_addr_ph, omp_get_default_device()); printf("E: %d %d %d\n", mapped_ptr_ph == nullptr, - mapped_ptr_ph != original_addr_ph, (void *)&ph == nullptr); + mapped_ptr_ph != original_addr_ph, &ph == original_addr_ph); } // (F) Lookup should succeed. @@ -99,7 +90,7 @@ struct S { void *mapped_ptr_ph = omp_get_mapped_ptr(original_addr_ph, omp_get_default_device()); printf("G: %d %d %d\n", mapped_ptr_ph == nullptr, - mapped_ptr_ph != original_addr_ph, (void *)&ph == nullptr); + mapped_ptr_ph != original_addr_ph, &ph == original_addr_ph); } // (H) Maps both pointee and pointer. Lookup for pointer should succeed. @@ -119,7 +110,7 @@ struct S { void *mapped_ptr_paa = omp_get_mapped_ptr(original_addr_paa, omp_get_default_device()); printf("I: %d %d %d\n", mapped_ptr_paa == nullptr, - mapped_ptr_paa != original_addr_paa, (void *)&paa == nullptr); + mapped_ptr_paa != original_addr_paa, &paa == original_addr_paa); } // (J) Maps pointee only, but use_device_addr operand is pointer. @@ -130,7 +121,7 @@ struct S { void *mapped_ptr_paa = omp_get_mapped_ptr(original_addr_paa, omp_get_default_device()); printf("J: %d %d %d\n", mapped_ptr_paa == nullptr, - mapped_ptr_paa != original_addr_paa, (void *)&paa == nullptr); + mapped_ptr_paa != original_addr_paa, &paa == original_addr_paa); } // (K) Lookup should succeed. diff --git a/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_ref_not_existing.cpp b/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_ref_not_existing.cpp index 9360db4195041..1a3ed148f288b 100644 --- a/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_ref_not_existing.cpp +++ b/offload/test/mapping/use_device_addr/target_data_use_device_addr_var_ref_not_existing.cpp @@ -8,15 +8,6 @@ // Test for various cases of use_device_addr on a reference variable. // The corresponding data is not previously mapped. -// Note that this tests for the current behavior wherein if a lookup fails, -// the runtime returns nullptr, instead of the original host-address. -// That was compatible with OpenMP 5.0, where it was a user error if -// corresponding storage didn't exist, but with 5.1+, the runtime needs to -// return the host address, as it needs to assume that the host-address is -// device-accessible, as the user has guaranteed it. -// Once the runtime returns the original host-address when the lookup fails, the -// test will need to be updated. - int g_ptee; int &g = g_ptee; @@ -45,7 +36,7 @@ struct S { void *mapped_ptr_g = omp_get_mapped_ptr(original_addr_g, omp_get_default_device()); printf("A: %d %d %d\n", mapped_ptr_g == nullptr, - mapped_ptr_g != original_addr_g, (void *)&g == nullptr); + mapped_ptr_g != original_addr_g, &g == original_addr_g); } // (B) Lookup should succeed. @@ -65,7 +56,7 @@ struct S { void *mapped_ptr_h = omp_get_mapped_ptr(original_addr_h, omp_get_default_device()); printf("C: %d %d %d\n", mapped_ptr_h == nullptr, - mapped_ptr_h != original_addr_h, (void *)&h == nullptr); + mapped_ptr_h != original_addr_h, &h == original_addr_h); } // (D) Lookup should succeed. @@ -85,7 +76,7 @@ struct S { void *mapped_ptr_ph = omp_get_mapped_ptr(original_addr_ph, omp_get_default_device()); printf("E: %d %d %d\n", mapped_ptr_ph == nullptr, - mapped_ptr_ph != original_addr_ph, (void *)&ph == nullptr); + mapped_ptr_ph != original_addr_ph, &ph == original_addr_ph); } // (F) Lookup should succeed. @@ -106,7 +97,7 @@ struct S { void *mapped_ptr_ph = omp_get_mapped_ptr(original_addr_ph, omp_get_default_device()); printf("G: %d %d %d\n", mapped_ptr_ph == nullptr, - mapped_ptr_ph != original_addr_ph, (void *)&ph == nullptr); + mapped_ptr_ph != original_addr_ph, &ph == original_addr_ph); } // (H) Maps both pointee and pointer. Lookup for pointer should succeed. @@ -126,7 +117,7 @@ struct S { void *mapped_ptr_paa = omp_get_mapped_ptr(original_addr_paa, omp_get_default_device()); printf("I: %d %d %d\n", mapped_ptr_paa == nullptr, - mapped_ptr_paa != original_addr_paa, (void *)&paa == nullptr); + mapped_ptr_paa != original_addr_paa, &paa == original_addr_paa); } // (J) Maps pointee only, but use_device_addr operand is pointer. @@ -137,7 +128,7 @@ struct S { void *mapped_ptr_paa = omp_get_mapped_ptr(original_addr_paa, omp_get_default_device()); printf("J: %d %d %d\n", mapped_ptr_paa == nullptr, - mapped_ptr_paa != original_addr_paa, (void *)&paa == nullptr); + mapped_ptr_paa != original_addr_paa, &paa == original_addr_paa); } // (K) Lookup should succeed. diff --git a/offload/test/mapping/use_device_addr/target_wrong_use_device_addr.c b/offload/test/mapping/use_device_addr/target_wrong_use_device_addr.c index 28ec6857fa1a8..f8c9d7c1fe7df 100644 --- a/offload/test/mapping/use_device_addr/target_wrong_use_device_addr.c +++ b/offload/test/mapping/use_device_addr/target_wrong_use_device_addr.c @@ -1,5 +1,5 @@ // RUN: %libomptarget-compile-generic -fopenmp-version=51 -g -// RUN: env LIBOMPTARGET_INFO=64 %libomptarget-run-fail-generic 2>&1 \ +// RUN: env LIBOMPTARGET_INFO=64 %libomptarget-run-generic 2>&1 \ // RUN: | %fcheck-generic // FIXME: Fails due to optimized debugging in 'ptxas' @@ -20,7 +20,8 @@ int main() { // counterpart #pragma omp target data use_device_addr(x) { - // CHECK-NOT: device addr=0x[[#%x,HOST_ADDR:]] + // Even when the lookup fails, x should retain its host address. + // CHECK: device addr=0x[[#HOST_ADDR]] fprintf(stderr, "device addr=%p\n", x); } } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_not_existing.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_not_existing.cpp index fe3cdb56e4baa..7632cefb1ea96 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_not_existing.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_not_existing.cpp @@ -8,15 +8,6 @@ // Test for various cases of use_device_ptr on a variable. // The corresponding data is not previously mapped. -// Note that this tests for the current behavior wherein if a lookup fails, -// the runtime returns nullptr, instead of the original host-address. -// That was compatible with OpenMP 5.0, where it was a user error if -// corresponding storage didn't exist, but with 5.1+, the runtime needs to -// return the host address, as it needs to assume that the host-address is -// device-accessible, as the user has guaranteed it. -// Once the runtime returns the original host-address when the lookup fails, the -// test will need to be updated. - int aa[10][10]; int h[10]; int *ph = &h[0]; @@ -26,7 +17,9 @@ struct S { void f1(int i) { paa--; + void *original_ph = ph; void *original_addr_ph3 = &ph[3]; + void *original_paa = paa; void *original_addr_paa102 = &paa[1][0][2]; // (A) No corresponding item, lookup should fail. @@ -36,7 +29,7 @@ struct S { void *mapped_ptr_ph3 = omp_get_mapped_ptr(original_addr_ph3, omp_get_default_device()); printf("A: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_addr_ph3, ph == nullptr); + mapped_ptr_ph3 != original_addr_ph3, ph == original_ph); } // (B) use_device_ptr/map on pointer, and pointee does not exist. @@ -47,7 +40,7 @@ struct S { void *mapped_ptr_ph3 = omp_get_mapped_ptr(original_addr_ph3, omp_get_default_device()); printf("B: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_addr_ph3, ph == nullptr); + mapped_ptr_ph3 != original_addr_ph3, ph == original_ph); } // (C) map on pointee: base-pointer of map matches use_device_ptr operand. @@ -80,7 +73,7 @@ struct S { void *mapped_ptr_paa102 = omp_get_mapped_ptr(original_addr_paa102, omp_get_default_device()); printf("E: %d %d %d\n", mapped_ptr_paa102 == nullptr, - mapped_ptr_paa102 != original_addr_paa102, paa == nullptr); + mapped_ptr_paa102 != original_addr_paa102, paa == original_paa); } // (F) use_device_ptr/map on pointer, and pointee does not exist. @@ -91,7 +84,7 @@ struct S { void *mapped_ptr_paa102 = omp_get_mapped_ptr(original_addr_paa102, omp_get_default_device()); printf("F: %d %d %d\n", mapped_ptr_paa102 == nullptr, - mapped_ptr_paa102 != original_addr_paa102, paa == nullptr); + mapped_ptr_paa102 != original_addr_paa102, paa == original_paa); } // (G) map on pointee: base-pointer of map matches use_device_ptr operand. diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_ref_not_existing.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_ref_not_existing.cpp index 419ab3eb33d4d..7c4e18b6bbafd 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_ref_not_existing.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_ref_not_existing.cpp @@ -8,15 +8,6 @@ // Test for various cases of use_device_ptr on a reference variable. // The corresponding data is not previously mapped. -// Note that this tests for the current behavior wherein if a lookup fails, -// the runtime returns nullptr, instead of the original host-address. -// That was compatible with OpenMP 5.0, where it was a user error if -// corresponding storage didn't exist, but with 5.1+, the runtime needs to -// return the host address, as it needs to assume that the host-address is -// device-accessible, as the user has guaranteed it. -// Once the runtime returns the original host-address when the lookup fails, the -// test will need to be updated. - int aa[10][10]; int (*paa_ptee)[10][10] = &aa; @@ -29,32 +20,30 @@ struct S { void f1(int i) { paa--; + void *original_ph = ph; void *original_addr_ph3 = &ph[3]; + void *original_paa = paa; void *original_addr_paa102 = &paa[1][0][2]; // (A) No corresponding item, lookup should fail. -// EXPECTED: A: 1 1 1 -// CHECK: A: 1 1 0 -// FIXME: ph is not being privatized in the region. +// CHECK: A: 1 1 1 #pragma omp target data use_device_ptr(ph) { void *mapped_ptr_ph3 = omp_get_mapped_ptr(original_addr_ph3, omp_get_default_device()); printf("A: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_addr_ph3, ph == nullptr); + mapped_ptr_ph3 != original_addr_ph3, ph == original_ph); } // (B) use_device_ptr/map on pointer, and pointee does not exist. // Lookup should fail. -// EXPECTED: B: 1 1 1 -// CHECK: B: 1 1 0 -// FIXME: ph is not being privatized in the region. +// CHECK: B: 1 1 1 #pragma omp target data map(ph) use_device_ptr(ph) { void *mapped_ptr_ph3 = omp_get_mapped_ptr(original_addr_ph3, omp_get_default_device()); printf("B: %d %d %d\n", mapped_ptr_ph3 == nullptr, - mapped_ptr_ph3 != original_addr_ph3, ph == nullptr); + mapped_ptr_ph3 != original_addr_ph3, ph == original_ph); } // (C) map on pointee: base-pointer of map matches use_device_ptr operand. @@ -91,7 +80,7 @@ struct S { void *mapped_ptr_paa102 = omp_get_mapped_ptr(original_addr_paa102, omp_get_default_device()); printf("E: %d %d %d\n", mapped_ptr_paa102 == nullptr, - mapped_ptr_paa102 != original_addr_paa102, paa == nullptr); + mapped_ptr_paa102 != original_addr_paa102, paa == original_paa); } // (F) use_device_ptr/map on pointer, and pointee does not exist. @@ -102,7 +91,7 @@ struct S { void *mapped_ptr_paa102 = omp_get_mapped_ptr(original_addr_paa102, omp_get_default_device()); printf("F: %d %d %d\n", mapped_ptr_paa102 == nullptr, - mapped_ptr_paa102 != original_addr_paa102, paa == nullptr); + mapped_ptr_paa102 != original_addr_paa102, paa == original_paa); } // (G) map on pointee: base-pointer of map matches use_device_ptr operand. >From ef610f43db5f25e2dc1ed8a0471e838f9e006f18 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 24 Nov 2025 16:46:12 -0800 Subject: [PATCH 03/16] Keep using uint64_t. --- offload/libomptarget/omptarget.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp index 3dcc0144f6cf2..287564f53101a 100644 --- a/offload/libomptarget/omptarget.cpp +++ b/offload/libomptarget/omptarget.cpp @@ -675,13 +675,13 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum, DataSize, DPxPTR(TgtPtrBegin), (TPR.Flags.IsNewEntry ? "" : " not")); if (ArgTypes[I] & OMP_TGT_MAPTYPE_RETURN_PARAM) { - intptr_t Delta = reinterpret_cast<intptr_t>(HstPtrBegin) - - reinterpret_cast<intptr_t>(HstPtrBase); + uintptr_t Delta = reinterpret_cast<uintptr_t>(HstPtrBegin) - + reinterpret_cast<uintptr_t>(HstPtrBase); void *TgtPtrBase; if (TgtPtrBegin) { // Lookup succeeded, return device pointer adjusted by delta TgtPtrBase = reinterpret_cast<void *>( - reinterpret_cast<intptr_t>(TgtPtrBegin) - Delta); + reinterpret_cast<uintptr_t>(TgtPtrBegin) - Delta); DP("Returning device pointer " DPxMOD "\n", DPxPTR(TgtPtrBase)); } else { // Lookup failed. So we have to decide what to do based on the @@ -699,10 +699,12 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum, // to references to a local device pointer that refers to this device // address. // - // TODO: Support OpenMP 6.1's "fb_nullify" and set the result to - // `null - Delta`. + // TODO: Add a new map-type bit to support OpenMP 6.1's `fb_nullify` + // and set the result to `nullptr - Delta`. Note that `fb_nullify` is + // already the default for `need_device_ptr`, but clang/flang do not + // support its codegen yet. TgtPtrBase = reinterpret_cast<void *>( - reinterpret_cast<intptr_t>(HstPtrBegin) - Delta); + reinterpret_cast<uintptr_t>(HstPtrBegin) - Delta); DP("Returning host pointer " DPxMOD " as fallback (lookup failed).\n", DPxPTR(TgtPtrBase)); } >From 1d76e35bf0115a698ab51b2be195610881e1db56 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 24 Nov 2025 17:14:49 -0800 Subject: [PATCH 04/16] Update OpenMPSupport.rst, ReleaseNotes.rst. --- clang/docs/OpenMPSupport.rst | 2 ++ clang/docs/ReleaseNotes.rst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index f7e6061044c6d..7cebf96cfe026 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -266,6 +266,8 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device | has_device_addr clause on target construct | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| device | use_device_ptr/addr preserve host address when lookup fails | :good:`done` | https://github.com/llvm/llvm-project/pull/169438 | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device | iterators in map clause or motion clauses | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device | indirect clause on declare target directive | :part:`In Progress` | | diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 51f07256c5d9f..ed22cdb39068f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -759,6 +759,8 @@ OpenMP Support - Updated parsing and semantic analysis support for ``nowait`` clause to accept optional argument in OpenMP >= 60. - Added support for ``default`` clause on ``target`` directive. +- ``use_device_ptr`` and ``use_device_addr`` now preserve the original host + address when lookup fails. Improvements ^^^^^^^^^^^^ >From 3fd3927df233e887d8a2e9133c0c22ab07c66487 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Tue, 25 Nov 2025 15:31:22 -0800 Subject: [PATCH 05/16] [OpenMP][Offload] Add `FB_NULLIFY` map-type for `use_device_ptr(fb_nullify)`. This PR adds a new map-type bit to control the fallback behavior when when a pointer lookup fails. For now, this is only meaningful with `RETURN_PARAM`, and can be used for `need_device_ptr` (for which the default is to use `nullptr` as the result when lookup fails), and OpenMP 6.1's `use_device_ptr(fb_nullify)`. Eventually, this can be extended to work with assumed-size maps on `target` constructs, to control what the argument should be set to when lookup fails (the OpenMP spec does not have a way to control that yet). --- .../llvm/Frontend/OpenMP/OMPConstants.h | 4 ++++ offload/include/omptarget.h | 4 ++++ offload/libomptarget/omptarget.cpp | 22 ++++++++++++------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index 58fd8a490c04a..d2a1b5209ecba 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -252,6 +252,10 @@ enum class OpenMPOffloadMappingFlags : uint64_t { // Attach pointer and pointee, after processing all other maps. // Applicable to map-entering directives. Does not change ref-count. OMP_MAP_ATTACH = 0x4000, + // When a lookup fails, fall back to using null as the translated pointer, + // instead of preserving the original pointer's value. Currently only + // useful in conjunction with RETURN_PARAM. + OMP_MAP_FB_NULLIFY = 0x8000, /// Signal that the runtime library should use args as an array of /// descriptor_dim pointers and use args_size as dims. Used when we have /// non-contiguous list items in target update directive diff --git a/offload/include/omptarget.h b/offload/include/omptarget.h index fbb4a06accf84..44e19a5290c48 100644 --- a/offload/include/omptarget.h +++ b/offload/include/omptarget.h @@ -80,6 +80,10 @@ enum tgt_map_type { // Attach pointer and pointee, after processing all other maps. // Applicable to map-entering directives. Does not change ref-count. OMP_TGT_MAPTYPE_ATTACH = 0x4000, + // When a lookup fails, fall back to using null as the translated pointer, + // instead of preserving the original pointer's value. Currently only + // useful in conjunction with RETURN_PARAM. + OMP_TGT_MAPTYPE_FB_NULLIFY = 0x8000, // descriptor for non-contiguous target-update OMP_TGT_MAPTYPE_NON_CONTIG = 0x100000000000, // member of struct, member given by [16 MSBs] - 1 diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp index 287564f53101a..d2376a527c1da 100644 --- a/offload/libomptarget/omptarget.cpp +++ b/offload/libomptarget/omptarget.cpp @@ -699,14 +699,20 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum, // to references to a local device pointer that refers to this device // address. // - // TODO: Add a new map-type bit to support OpenMP 6.1's `fb_nullify` - // and set the result to `nullptr - Delta`. Note that `fb_nullify` is - // already the default for `need_device_ptr`, but clang/flang do not - // support its codegen yet. - TgtPtrBase = reinterpret_cast<void *>( - reinterpret_cast<uintptr_t>(HstPtrBegin) - Delta); - DP("Returning host pointer " DPxMOD " as fallback (lookup failed).\n", - DPxPTR(TgtPtrBase)); + // OpenMP 6.1's `fb_nullify` fallback behavior: when the FB_NULLIFY bit + // is set by the compiler, e.g. for `use/need_device_ptr(fb_nullify)`), + // return `nullptr - Delta` when lookup fails. + if (ArgTypes[I] & OMP_TGT_MAPTYPE_FB_NULLIFY) { + TgtPtrBase = reinterpret_cast<void *>( + reinterpret_cast<uintptr_t>(nullptr) - Delta); + DP("Returning offsetted null pointer " DPxMOD " as fallback (lookup failed)\n", + DPxPTR(TgtPtrBase)); + } else { + TgtPtrBase = reinterpret_cast<void *>( + reinterpret_cast<uintptr_t>(HstPtrBegin) - Delta); + DP("Returning host pointer " DPxMOD " as fallback (lookup failed)\n", + DPxPTR(TgtPtrBase)); + } } ArgsBase[I] = TgtPtrBase; } >From aa6a1b74f2000a16bafdec6db481babdd3e752bf Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 1 Dec 2025 13:22:40 -0800 Subject: [PATCH 06/16] Clang-format --- offload/libomptarget/omptarget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp index d2376a527c1da..669f8d0b1a85c 100644 --- a/offload/libomptarget/omptarget.cpp +++ b/offload/libomptarget/omptarget.cpp @@ -705,7 +705,8 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum, if (ArgTypes[I] & OMP_TGT_MAPTYPE_FB_NULLIFY) { TgtPtrBase = reinterpret_cast<void *>( reinterpret_cast<uintptr_t>(nullptr) - Delta); - DP("Returning offsetted null pointer " DPxMOD " as fallback (lookup failed)\n", + DP("Returning offsetted null pointer " DPxMOD + " as fallback (lookup failed)\n", DPxPTR(TgtPtrBase)); } else { TgtPtrBase = reinterpret_cast<void *>( >From e716fa8120309d5b8780cd2ea77a84231e351c88 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Tue, 23 Dec 2025 15:38:48 -0800 Subject: [PATCH 07/16] Fix minor typo. --- offload/libomptarget/omptarget.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp index b6b03e692ad26..960c5bc17df96 100644 --- a/offload/libomptarget/omptarget.cpp +++ b/offload/libomptarget/omptarget.cpp @@ -713,9 +713,8 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum, if (ArgTypes[I] & OMP_TGT_MAPTYPE_FB_NULLIFY) { TgtPtrBase = reinterpret_cast<void *>( reinterpret_cast<uintptr_t>(nullptr) - Delta); - ODBG(ODT_MAPPING) << "Returning offsetted null pointer " - - << TgtPtrBase << " as fallback (lookup failed)"; + ODBG(ODT_Mapping) << "Returning offsetted null pointer " << TgtPtrBase + << " as fallback (lookup failed)"; } else { TgtPtrBase = reinterpret_cast<void *>( reinterpret_cast<uintptr_t>(HstPtrBegin) - Delta); >From 7ae746ff1cfd0230f080c43aa36c3996398f00cc Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Tue, 6 Jan 2026 13:59:31 -0800 Subject: [PATCH 08/16] Update PR number in OpenMPSupport RST. --- clang/docs/OpenMPSupport.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index 273e7ea601c8c..7941c2e439ed6 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -266,7 +266,7 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device | has_device_addr clause on target construct | :none:`unclaimed` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| device | use_device_ptr/addr preserve host address when lookup fails | :good:`done` | https://github.com/llvm/llvm-project/pull/169438 | +| device | use_device_ptr/addr preserve host address when lookup fails | :good:`done` | https://github.com/llvm/llvm-project/pull/174659 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | device | iterators in map clause or motion clauses | :none:`done` | https://github.com/llvm/llvm-project/pull/159112 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ >From 009a8ae6c1939f86c7ac3b6ddcb011a403b84e45 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 1 Dec 2025 14:20:15 -0800 Subject: [PATCH 09/16] [OpenMP][Clang] Parsing/Sema support for `use_device_ptr(fb_preserve/fb_nullify)`. Depends on #169603. This is the `use_device_ptr` counterpart of #168905. With OpenMP 6.1, a `fallback` modifier can be specified on the `use_device_ptr` clause to control the behavior when a pointer lookup fails, i.e. there is no device pointer to translate into. The default is `fb_preserve` (i.e. retain the original pointer), while `fb_nullify` means: use `nullptr` as the translated pointer. --- clang/include/clang/AST/OpenMPClause.h | 39 ++++++++++++++++++++--- clang/include/clang/Basic/OpenMPKinds.def | 8 +++++ clang/include/clang/Basic/OpenMPKinds.h | 8 +++++ clang/include/clang/Sema/SemaOpenMP.h | 8 +++-- clang/lib/AST/OpenMPClause.cpp | 17 ++++++++-- clang/lib/Basic/OpenMPKinds.cpp | 22 +++++++++++-- clang/lib/Parse/ParseOpenMP.cpp | 18 +++++++++++ clang/lib/Sema/SemaOpenMP.cpp | 14 +++++--- clang/lib/Sema/TreeTransform.h | 12 ++++--- clang/lib/Serialization/ASTReader.cpp | 2 ++ clang/lib/Serialization/ASTWriter.cpp | 2 ++ 11 files changed, 130 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 6525e64ff102f..0847839221ea0 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -7989,6 +7989,13 @@ class OMPUseDevicePtrClause final friend OMPVarListClause; friend TrailingObjects; + /// Fallback modifier for the clause. + OpenMPUseDevicePtrFallbackModifier FallbackModifier = + OMPC_USE_DEVICE_PTR_FALLBACK_unknown; + + /// Location of the fallback modifier. + SourceLocation FallbackModifierLoc; + /// Build clause with number of variables \a NumVars. /// /// \param Locs Locations needed to build a mappable clause. It includes 1) @@ -7999,10 +8006,14 @@ class OMPUseDevicePtrClause final /// NumUniqueDeclarations: number of unique base declarations in this clause; /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. + /// \param FallbackModifier The fallback modifier for the clause. + /// \param FallbackModifierLoc Location of the fallback modifier. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, - const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { - } + const OMPMappableExprListSizeTy &Sizes, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc) + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes), + FallbackModifier(FallbackModifier), FallbackModifierLoc(FallbackModifierLoc) {} /// Build an empty clause. /// @@ -8055,6 +8066,14 @@ class OMPUseDevicePtrClause final return {getPrivateCopies().end(), varlist_size()}; } + /// Set the fallback modifier for the clause. + void setFallbackModifier(OpenMPUseDevicePtrFallbackModifier M) { + FallbackModifier = M; + } + + /// Set the location of the fallback modifier. + void setFallbackModifierLoc(SourceLocation Loc) { FallbackModifierLoc = Loc; } + public: /// Creates clause with a list of variables \a Vars. /// @@ -8067,11 +8086,15 @@ class OMPUseDevicePtrClause final /// \param Inits Expressions referring to private copy initializers. /// \param Declarations Declarations used in the clause. /// \param ComponentLists Component lists used in the clause. + /// \param FallbackModifier The fallback modifier for the clause. + /// \param FallbackModifierLoc Location of the fallback modifier. static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists); + MappableExprComponentListsRef ComponentLists, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc); /// Creates an empty clause with the place for \a NumVars variables. /// @@ -8084,6 +8107,14 @@ class OMPUseDevicePtrClause final static OMPUseDevicePtrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); + /// Get the fallback modifier for the clause. + OpenMPUseDevicePtrFallbackModifier getFallbackModifier() const { + return FallbackModifier; + } + + /// Get the location of the fallback modifier. + SourceLocation getFallbackModifierLoc() const { return FallbackModifierLoc; } + using private_copies_iterator = MutableArrayRef<Expr *>::iterator; using private_copies_const_iterator = ArrayRef<const Expr *>::iterator; using private_copies_range = llvm::iterator_range<private_copies_iterator>; diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index ceac89d3aba6d..e61ee0ddc08da 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -110,6 +110,9 @@ #ifndef OPENMP_NEED_DEVICE_PTR_KIND #define OPENMP_NEED_DEVICE_PTR_KIND(Name) #endif +#ifndef OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER +#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) +#endif // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) @@ -282,6 +285,10 @@ OPENMP_THREADSET_KIND(omp_team) OPENMP_NEED_DEVICE_PTR_KIND(fb_nullify) OPENMP_NEED_DEVICE_PTR_KIND(fb_preserve) +// OpenMP 6.1 modifiers for 'use_device_ptr' clause. +OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(fb_nullify) +OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(fb_preserve) + #undef OPENMP_NUMTASKS_MODIFIER #undef OPENMP_NUMTHREADS_MODIFIER #undef OPENMP_DYN_GROUPPRIVATE_MODIFIER @@ -315,3 +322,4 @@ OPENMP_NEED_DEVICE_PTR_KIND(fb_preserve) #undef OPENMP_ALLOCATE_MODIFIER #undef OPENMP_THREADSET_KIND #undef OPENMP_NEED_DEVICE_PTR_KIND +#undef OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 3b088b3efd998..4e83bfcd0128b 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -218,6 +218,14 @@ enum OpenMPNeedDevicePtrModifier { OMPC_NEED_DEVICE_PTR_unknown, }; +/// OpenMP 6.1 use_device_ptr fallback modifier +enum OpenMPUseDevicePtrFallbackModifier { +#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) \ + OMPC_USE_DEVICE_PTR_FALLBACK_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_USE_DEVICE_PTR_FALLBACK_unknown, +}; + /// OpenMP bindings for the 'bind' clause. enum OpenMPBindClauseKind { #define OPENMP_BIND_KIND(Name) OMPC_BIND_##Name, diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 2d05b4423140b..e4eb3345534a4 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1176,6 +1176,9 @@ class SemaOpenMP : public SemaBase { int OriginalSharingModifier = 0; // Default is shared int NeedDevicePtrModifier = 0; SourceLocation NeedDevicePtrModifierLoc; + int UseDevicePtrFallbackModifier = + OMPC_USE_DEVICE_PTR_FALLBACK_unknown; ///< Fallback modifier for use_device_ptr clause. + SourceLocation UseDevicePtrFallbackModifierLoc; SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> MapTypeModifiers; SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> @@ -1364,8 +1367,9 @@ class SemaOpenMP : public SemaBase { ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers = {}); /// Called on well-formed 'use_device_ptr' clause. - OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, - const OMPVarListLocTy &Locs); + OMPClause *ActOnOpenMPUseDevicePtrClause( + ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, SourceLocation FallbackModifierLoc); /// Called on well-formed 'use_device_addr' clause. OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs); diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 2183d77de8fa7..5a6a958595671 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1441,7 +1441,9 @@ OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create( const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations, - MappableExprComponentListsRef ComponentLists) { + MappableExprComponentListsRef ComponentLists, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc) { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Vars.size(); Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations); @@ -1465,7 +1467,8 @@ OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create( Sizes.NumUniqueDeclarations + Sizes.NumComponentLists, Sizes.NumComponents)); - OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes); + OMPUseDevicePtrClause *Clause = new (Mem) + OMPUseDevicePtrClause(Locs, Sizes, FallbackModifier, FallbackModifierLoc); Clause->setVarRefs(Vars); Clause->setPrivateCopies(PrivateVars); @@ -2753,7 +2756,15 @@ void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) { void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) { if (!Node->varlist_empty()) { OS << "use_device_ptr"; - VisitOMPClauseList(Node, '('); + if (Node->getFallbackModifier() != OMPC_USE_DEVICE_PTR_FALLBACK_unknown) { + OS << "(" + << getOpenMPSimpleClauseTypeName(OMPC_use_device_ptr, + Node->getFallbackModifier()) + << ":"; + VisitOMPClauseList(Node, ' '); + } else { + VisitOMPClauseList(Node, '('); + } OS << ")"; } } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 03485b7e81abc..7ba2c89638c05 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -238,6 +238,16 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, return OMPC_NUMTHREADS_unknown; return Type; } + case OMPC_use_device_ptr: { + unsigned Type = llvm::StringSwitch<unsigned>(Str) +#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) \ + .Case(#Name, OMPC_USE_DEVICE_PTR_FALLBACK_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_USE_DEVICE_PTR_FALLBACK_unknown); + if (LangOpts.OpenMP < 61) + return OMPC_USE_DEVICE_PTR_FALLBACK_unknown; + return Type; + } case OMPC_unknown: case OMPC_threadprivate: case OMPC_groupprivate: @@ -280,7 +290,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str, case OMPC_nogroup: case OMPC_hint: case OMPC_uniform: - case OMPC_use_device_ptr: case OMPC_use_device_addr: case OMPC_is_device_ptr: case OMPC_has_device_addr: @@ -608,6 +617,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'threadset' clause modifier"); + case OMPC_use_device_ptr: + switch (Type) { + case OMPC_USE_DEVICE_PTR_FALLBACK_unknown: + return "unknown"; +#define OPENMP_USE_DEVICE_PTR_FALLBACK_MODIFIER(Name) \ + case OMPC_USE_DEVICE_PTR_FALLBACK_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'use_device_ptr' clause modifier"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_groupprivate: @@ -650,7 +669,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_nogroup: case OMPC_hint: case OMPC_uniform: - case OMPC_use_device_ptr: case OMPC_use_device_addr: case OMPC_is_device_ptr: case OMPC_has_device_addr: diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 01fd05961f876..3619cd03ec0fd 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -5055,6 +5055,24 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon, "adjust-op"); } + } else if (Kind == OMPC_use_device_ptr && getLangOpts().OpenMP >= 61) { + // Handle optional fallback modifier for use_device_ptr clause. + // use_device_ptr([fb_preserve | fb_nullify :] list) + // Default is fb_preserve. + if (Tok.is(tok::identifier)) { + auto FallbackModifier = static_cast<OpenMPUseDevicePtrFallbackModifier>( + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts())); + if (FallbackModifier != OMPC_USE_DEVICE_PTR_FALLBACK_unknown) { + Data.UseDevicePtrFallbackModifier = FallbackModifier; + Data.UseDevicePtrFallbackModifierLoc = Tok.getLocation(); + ConsumeToken(); + if (Tok.is(tok::colon)) { + Data.ColonLoc = ConsumeToken(); + } else { + Diag(Tok, diag::err_modifier_expected_colon) << "fallback"; + } + } + } } bool IsComma = diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2a1337be13b99..29c809888a168 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18757,7 +18757,11 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, VarList, Locs); break; case OMPC_use_device_ptr: - Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); + Res = ActOnOpenMPUseDevicePtrClause( + VarList, Locs, + static_cast<OpenMPUseDevicePtrFallbackModifier>( + Data.UseDevicePtrFallbackModifier), + Data.UseDevicePtrFallbackModifierLoc); break; case OMPC_use_device_addr: Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); @@ -24574,9 +24578,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPFromClause( MapperId); } -OMPClause * -SemaOpenMP::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, - const OMPVarListLocTy &Locs) { +OMPClause *SemaOpenMP::ActOnOpenMPUseDevicePtrClause( + ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, SourceLocation FallbackModifierLoc) { MappableVarListInfo MVLI(VarList); SmallVector<Expr *, 8> PrivateCopies; SmallVector<Expr *, 8> Inits; @@ -24657,7 +24661,7 @@ SemaOpenMP::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, return OMPUseDevicePtrClause::Create( getASTContext(), Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, - MVLI.VarBaseDeclarations, MVLI.VarComponents); + MVLI.VarBaseDeclarations, MVLI.VarComponents, FallbackModifier, FallbackModifierLoc); } OMPClause * diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index bc923c80b7132..25ed92fd3f44b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2258,9 +2258,12 @@ class TreeTransform { /// /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList, - const OMPVarListLocTy &Locs) { - return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs); + OMPClause *RebuildOMPUseDevicePtrClause( + ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc) { + return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause( + VarList, Locs, FallbackModifier, FallbackModifierLoc); } /// Build a new OpenMP 'use_device_addr' clause. @@ -11624,7 +11627,8 @@ OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause( Vars.push_back(EVar.get()); } OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); - return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs); + return getDerived().RebuildOMPUseDevicePtrClause( + Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc()); } template <typename Derived> diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 66cf484bb5cb6..b6b1a4d280b16 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12542,6 +12542,8 @@ void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) { void OMPClauseReader::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setFallbackModifier(Record.readEnum<OpenMPUseDevicePtrFallbackModifier>()); + C->setFallbackModifierLoc(Record.readSourceLocation()); auto NumVars = C->varlist_size(); auto UniqueDecls = C->getUniqueDeclarationsNum(); auto TotalLists = C->getTotalComponentListNum(); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 39104da10d0b7..d66dc7b2adffd 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -8535,6 +8535,8 @@ void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); + Record.writeEnum(C->getFallbackModifier()); + Record.AddSourceLocation(C->getFallbackModifierLoc()); for (auto *E : C->varlist()) Record.AddStmt(E); for (auto *VE : C->private_copies()) >From 0e260ad20c41ed834f7615d9509f6e46add1cb4e Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Wed, 3 Dec 2025 16:06:54 -0800 Subject: [PATCH 10/16] Add tests. --- ...data_use_device_ptr_fallback_ast_print.cpp | 36 +++++++++++++++++++ ..._data_use_device_ptr_fallback_messages.cpp | 28 +++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp create mode 100644 clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp diff --git a/clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp b/clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp new file mode 100644 index 0000000000000..060f64f6e86a8 --- /dev/null +++ b/clang/test/OpenMP/target_data_use_device_ptr_fallback_ast_print.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=61 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=61 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=61 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s + +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +// CHECK-LABEL:void f1(int *p, int *q) +void f1(int *p, int *q) { + +// CHECK: #pragma omp target data use_device_ptr(fb_preserve: p) +#pragma omp target data use_device_ptr(fb_preserve: p) + {} + +// CHECK: #pragma omp target data use_device_ptr(fb_nullify: p) +#pragma omp target data use_device_ptr(fb_nullify: p) + {} + +// Without any fallback modifier +// CHECK: #pragma omp target data use_device_ptr(p) +#pragma omp target data use_device_ptr(p) + {} + +// Multiple variables with fb_preserve +// CHECK: #pragma omp target data use_device_ptr(fb_preserve: p,q) +#pragma omp target data use_device_ptr(fb_preserve: p, q) + {} + +// Multiple variables with fb_nullify +// CHECK: #pragma omp target data use_device_ptr(fb_nullify: p,q) +#pragma omp target data use_device_ptr(fb_nullify: p, q) + {} +} +#endif diff --git a/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp b/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp new file mode 100644 index 0000000000000..7a22e95e7fee6 --- /dev/null +++ b/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=60 -verify=omp60,expected -ferror-limit 200 %s +// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=61 -verify=omp61,expected -ferror-limit 200 %s + +void f1(int x, int *p, int *q) { + + // Test that fallback modifier is only recognized in OpenMP 6.1+ +#pragma omp target data map(x) use_device_ptr(fb_preserve: p) // omp60-error {{use of undeclared identifier 'fb_preserve'}} + {} + +#pragma omp target data map(x) use_device_ptr(fb_nullify: p) // omp60-error {{use of undeclared identifier 'fb_nullify'}} + {} + + // Without modifier (should work in both versions) +#pragma omp target data map(x) use_device_ptr(p) + {} + + // Unknown modifier: should fail in both versions +#pragma omp target data map(x) use_device_ptr(fb_abc: p) // expected-error {{use of undeclared identifier 'fb_abc'}} + {} + + // Multiple modifiers: should fail in both versions +#pragma omp target data map(x) use_device_ptr(fb_nullify, fb_preserve: p, q) // omp61-error {{missing ':' after fallback modifier}} omp61-error {{expected expression}} omp61-error {{use of undeclared identifier 'fb_preserve'}} omp60-error {{use of undeclared identifier 'fb_nullify'}} omp60-error {{use of undeclared identifier 'fb_preserve'}} + {} + + // Test missing colon after modifier in OpenMP 6.1 - should error +#pragma omp target data map(x) use_device_ptr(fb_preserve p) // omp61-error {{missing ':' after fallback modifier}} omp60-error {{use of undeclared identifier 'fb_preserve'}} + {} +} \ No newline at end of file >From 1986d1fd37eba52fb726875bc44373ca70f5b316 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Wed, 3 Dec 2025 16:32:12 -0800 Subject: [PATCH 11/16] Minor formatting changes. --- clang/include/clang/AST/OpenMPClause.h | 11 ++++++----- clang/include/clang/Sema/SemaOpenMP.h | 6 ++++-- clang/lib/Parse/ParseOpenMP.cpp | 5 ++--- clang/lib/Sema/SemaOpenMP.cpp | 6 ++++-- .../target_data_use_device_ptr_fallback_messages.cpp | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 0847839221ea0..21a4cfb519f5a 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -8008,12 +8008,13 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. /// \param FallbackModifier The fallback modifier for the clause. /// \param FallbackModifierLoc Location of the fallback modifier. - explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, - const OMPMappableExprListSizeTy &Sizes, - OpenMPUseDevicePtrFallbackModifier FallbackModifier, - SourceLocation FallbackModifierLoc) + explicit OMPUseDevicePtrClause( + const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes, + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc) : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes), - FallbackModifier(FallbackModifier), FallbackModifierLoc(FallbackModifierLoc) {} + FallbackModifier(FallbackModifier), + FallbackModifierLoc(FallbackModifierLoc) {} /// Build an empty clause. /// diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index e4eb3345534a4..1d4ea0f1cf3b0 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1177,7 +1177,8 @@ class SemaOpenMP : public SemaBase { int NeedDevicePtrModifier = 0; SourceLocation NeedDevicePtrModifierLoc; int UseDevicePtrFallbackModifier = - OMPC_USE_DEVICE_PTR_FALLBACK_unknown; ///< Fallback modifier for use_device_ptr clause. + OMPC_USE_DEVICE_PTR_FALLBACK_unknown; ///< Fallback modifier for + ///< use_device_ptr clause. SourceLocation UseDevicePtrFallbackModifierLoc; SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> MapTypeModifiers; @@ -1369,7 +1370,8 @@ class SemaOpenMP : public SemaBase { /// Called on well-formed 'use_device_ptr' clause. OMPClause *ActOnOpenMPUseDevicePtrClause( ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, - OpenMPUseDevicePtrFallbackModifier FallbackModifier, SourceLocation FallbackModifierLoc); + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc); /// Called on well-formed 'use_device_addr' clause. OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 3619cd03ec0fd..9e181bd5bfb1d 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -5066,11 +5066,10 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.UseDevicePtrFallbackModifier = FallbackModifier; Data.UseDevicePtrFallbackModifierLoc = Tok.getLocation(); ConsumeToken(); - if (Tok.is(tok::colon)) { + if (Tok.is(tok::colon)) Data.ColonLoc = ConsumeToken(); - } else { + else Diag(Tok, diag::err_modifier_expected_colon) << "fallback"; - } } } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 29c809888a168..f6c6b493d819b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -24580,7 +24580,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPFromClause( OMPClause *SemaOpenMP::ActOnOpenMPUseDevicePtrClause( ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs, - OpenMPUseDevicePtrFallbackModifier FallbackModifier, SourceLocation FallbackModifierLoc) { + OpenMPUseDevicePtrFallbackModifier FallbackModifier, + SourceLocation FallbackModifierLoc) { MappableVarListInfo MVLI(VarList); SmallVector<Expr *, 8> PrivateCopies; SmallVector<Expr *, 8> Inits; @@ -24661,7 +24662,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPUseDevicePtrClause( return OMPUseDevicePtrClause::Create( getASTContext(), Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, - MVLI.VarBaseDeclarations, MVLI.VarComponents, FallbackModifier, FallbackModifierLoc); + MVLI.VarBaseDeclarations, MVLI.VarComponents, FallbackModifier, + FallbackModifierLoc); } OMPClause * diff --git a/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp b/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp index 7a22e95e7fee6..fff2dcf15e29e 100644 --- a/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp +++ b/clang/test/OpenMP/target_data_use_device_ptr_fallback_messages.cpp @@ -25,4 +25,4 @@ void f1(int x, int *p, int *q) { // Test missing colon after modifier in OpenMP 6.1 - should error #pragma omp target data map(x) use_device_ptr(fb_preserve p) // omp61-error {{missing ':' after fallback modifier}} omp60-error {{use of undeclared identifier 'fb_preserve'}} {} -} \ No newline at end of file +} >From 7dbda3107a06748a12ce044746d093cdfcc41e30 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Fri, 5 Dec 2025 15:10:27 -0800 Subject: [PATCH 12/16] [NFC][OpenMP][Offload] Add tests for `use_device_ptr(fb_preserve/nullify)`. The fallback modifiers are currently part of OpenMP 6.1. The tests mostly fail for now. The associated libomptarget and clang parsing/sema changes are in #169438, #169603 and #170578, with clang codegen to follow. --- ...a_use_device_ptr_class_member_fallback.cpp | 34 ++++++++++++++++++ ...vice_ptr_class_member_fallback_nullify.cpp | 30 ++++++++++++++++ ...ice_ptr_class_member_fallback_preserve.cpp | 30 ++++++++++++++++ ...e_device_ptr_class_member_ref_fallback.cpp | 35 +++++++++++++++++++ ..._ptr_class_member_ref_fallback_nullify.cpp | 31 ++++++++++++++++ ...ptr_class_member_ref_fallback_preserve.cpp | 31 ++++++++++++++++ ...rget_data_use_device_ptr_var_fallback.cpp} | 6 +++- ...ta_use_device_ptr_var_fallback_nullify.cpp | 23 ++++++++++++ ...a_use_device_ptr_var_fallback_preserve.cpp | 23 ++++++++++++ ...t_data_use_device_ptr_var_ref_fallback.cpp | 26 ++++++++++++++ ...se_device_ptr_var_ref_fallback_nullify.cpp | 25 +++++++++++++ ...e_device_ptr_var_ref_fallback_preserve.cpp | 24 +++++++++++++ 12 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp rename offload/test/mapping/use_device_ptr/{target_data_use_device_ptr_var_fallback.c => target_data_use_device_ptr_var_fallback.cpp} (69%) create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp create mode 100644 offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp new file mode 100644 index 0000000000000..2dd33732a7d2f --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp @@ -0,0 +1,34 @@ +// RUN: %libomptarget-compilexx-generic +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value by +// default. +// +// This is necessary because we must assume that the +// pointee is device-accessible, even if it was not +// previously mapped. + +// XFAIL: * + +#include <stdio.h> + +int x = 0; + +struct ST { + int *a = &x; + + void f1() { + printf("%p\n", a); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(a) + printf("%p\n", a); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] + } +}; + +int main() { + ST s; + s.f1(); +} diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp new file mode 100644 index 0000000000000..61f3367f537ee --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp @@ -0,0 +1,30 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,OFFLOAD +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,NOOFFLOAD + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer is set to null because of fb_nullify. + +// XFAIL: * + +#include <stdio.h> + +int x = 0; + +struct ST { + int *a = &x; + + void f1() { + printf("%p\n", a); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_nullify : a) + printf("%p\n", a); // OFFLOAD-NEXT: (nil) + // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] + } +}; + +int main() { + ST s; + s.f1(); +} diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp new file mode 100644 index 0000000000000..b7af1f39cc3bf --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp @@ -0,0 +1,30 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value +// because of fb_preserve. + +// XFAIL: * + +#include <stdio.h> + +int x = 0; + +struct ST { + int *a = &x; + + void f1() { + printf("%p\n", a); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_preserve : a) + printf("%p\n", a); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] + } +}; + +int main() { + ST s; + s.f1(); +} diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp new file mode 100644 index 0000000000000..45f89d0ee92cc --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp @@ -0,0 +1,35 @@ +// RUN: %libomptarget-compilexx-generic +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value by +// default. +// +// This is necessary because we must assume that the +// pointee is device-accessible, even if it was not +// previously mapped. + +// XFAIL: * + +#include <stdio.h> + +int x = 0; +int *y = &x; + +struct ST { + int *&b = y; + + void f2() { + printf("%p\n", b); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(b) + printf("%p\n", b); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] + } +}; + +int main() { + ST s; + s.f2(); +} diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp new file mode 100644 index 0000000000000..39f39a974577c --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp @@ -0,0 +1,31 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,OFFLOAD +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,NOOFFLOAD + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer is set to null because of fb_nullify. + +// XFAIL: * + +#include <stdio.h> + +int x = 0; +int *y = &x; + +struct ST { + int *&b = y; + + void f2() { + printf("%p\n", b); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_nullify : b) + printf("%p\n", b); // OFFLOAD-NEXT: (nil) + // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] + } +}; + +int main() { + ST s; + s.f2(); +} diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp new file mode 100644 index 0000000000000..ad861ab12001e --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp @@ -0,0 +1,31 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value +// because of fb_preserve. + +// XFAIL: * + +#include <stdio.h> + +int x = 0; +int *y = &x; + +struct ST { + int *&b = y; + + void f2() { + printf("%p\n", b); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_preserve : b) + printf("%p\n", b); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] + } +}; + +int main() { + ST s; + s.f2(); +} diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.cpp similarity index 69% rename from offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c rename to offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.cpp index 33a363495e24a..5be209a8c5b0d 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.c +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback.cpp @@ -1,4 +1,8 @@ -// RUN: %libomptarget-compilexx-run-and-check-generic +// RUN: %libomptarget-compilexx-generic +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic // Test that when a use_device_ptr lookup fails, the // privatized pointer retains its original value by diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp new file mode 100644 index 0000000000000..cb11f52645dd8 --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp @@ -0,0 +1,23 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,OFFLOAD +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,NOOFFLOAD + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer is set to null because of fb_nullify. + +// XFAIL: * + +#include <stdio.h> +int x; +int *xp = &x; + +void f1() { + printf("%p\n", xp); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_nullify : xp) + printf("%p\n", xp); // OFFLOAD-NEXT: (nil) + // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] +} + +int main() { f1(); } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp new file mode 100644 index 0000000000000..31ce803fc1ed0 --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp @@ -0,0 +1,23 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value +// because of fb_preserve. + +// XFAIL: * + +#include <stdio.h> +int x; +int *xp = &x; + +void f1() { + printf("%p\n", xp); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_preserve : xp) + printf("%p\n", xp); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] +} + +int main() { f1(); } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback.cpp new file mode 100644 index 0000000000000..1060ed9cdbc70 --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback.cpp @@ -0,0 +1,26 @@ +// RUN: %libomptarget-compilexx-generic +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value by +// default. +// +// This is necessary because we must assume that the +// pointee is device-accessible, even if it was not +// previously mapped. + +#include <stdio.h> +int x; +int *xp = &x; +int *&xpr = xp; + +void f2() { + printf("%p\n", xpr); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(xpr) + printf("%p\n", xpr); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] +} + +int main() { f2(); } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp new file mode 100644 index 0000000000000..230ffda4fad9a --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp @@ -0,0 +1,25 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,OFFLOAD +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic -check-prefixes=CHECK,NOOFFLOAD + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer is set to null because of fb_nullify. + +// XFAIL: * + +#include <stdio.h> +int x; +int *xp = &x; +int *&xpr = xp; + +void f2() { + printf("%p\n", xpr); // CHECK: 0x[[#%x,ADDR:]] + // FIXME: We won't get "nil" until we start privatizing xpr. +#pragma omp target data use_device_ptr(fb_nullify : xpr) + printf("%p\n", xpr); // OFFLOAD-NEXT: (nil) + // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] +} + +int main() { f2(); } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp new file mode 100644 index 0000000000000..443739814ed0d --- /dev/null +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp @@ -0,0 +1,24 @@ +// RUN: %libomptarget-compilexx-generic -fopenmp-version=61 +// RUN: %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic +// RUN: env OMP_TARGET_OFFLOAD=disabled %libomptarget-run-generic 2>&1 \ +// RUN: | %fcheck-generic + +// Test that when a use_device_ptr lookup fails, the +// privatized pointer retains its original value +// because of fb_preserve. + +// XFAIL: * + +#include <stdio.h> +int x; +int *xp = &x; +int *&xpr = xp; + +void f2() { + printf("%p\n", xpr); // CHECK: 0x[[#%x,ADDR:]] +#pragma omp target data use_device_ptr(fb_preserve : xpr) + printf("%p\n", xpr); // CHECK-NEXT: 0x{{0*}}[[#ADDR]] +} + +int main() { f2(); } >From 75d82a2d78cf959b9ab4d5833d5ee043e33e1bfb Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 29 Dec 2025 15:03:49 -0800 Subject: [PATCH 13/16] Update test checks to incorporate Parsing/Sema changes. --- .../target_data_use_device_ptr_class_member_fallback.cpp | 2 -- ...et_data_use_device_ptr_class_member_fallback_nullify.cpp | 6 +++--- ...t_data_use_device_ptr_class_member_fallback_preserve.cpp | 2 -- ...target_data_use_device_ptr_class_member_ref_fallback.cpp | 2 -- ...ata_use_device_ptr_class_member_ref_fallback_nullify.cpp | 6 +++--- ...ta_use_device_ptr_class_member_ref_fallback_preserve.cpp | 2 -- .../target_data_use_device_ptr_var_fallback_nullify.cpp | 6 +++--- .../target_data_use_device_ptr_var_fallback_preserve.cpp | 2 -- .../target_data_use_device_ptr_var_ref_fallback_nullify.cpp | 5 ++--- ...target_data_use_device_ptr_var_ref_fallback_preserve.cpp | 2 -- 10 files changed, 11 insertions(+), 24 deletions(-) diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp index 2dd33732a7d2f..5c232d5db02e0 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback.cpp @@ -12,8 +12,6 @@ // pointee is device-accessible, even if it was not // previously mapped. -// XFAIL: * - #include <stdio.h> int x = 0; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp index 61f3367f537ee..e85f51736f4f7 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp @@ -7,8 +7,6 @@ // Test that when a use_device_ptr lookup fails, the // privatized pointer is set to null because of fb_nullify. -// XFAIL: * - #include <stdio.h> int x = 0; @@ -18,8 +16,10 @@ struct ST { void f1() { printf("%p\n", a); // CHECK: 0x[[#%x,ADDR:]] + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : a) - printf("%p\n", a); // OFFLOAD-NEXT: (nil) + printf("%p\n", a); // EXPECTED-OFFLOAD-NEXT: (nil) + // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] } }; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp index b7af1f39cc3bf..51944c561dc2d 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_preserve.cpp @@ -8,8 +8,6 @@ // privatized pointer retains its original value // because of fb_preserve. -// XFAIL: * - #include <stdio.h> int x = 0; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp index 45f89d0ee92cc..59a8facdf2f5c 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback.cpp @@ -12,8 +12,6 @@ // pointee is device-accessible, even if it was not // previously mapped. -// XFAIL: * - #include <stdio.h> int x = 0; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp index 39f39a974577c..00e6372a0f588 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp @@ -7,8 +7,6 @@ // Test that when a use_device_ptr lookup fails, the // privatized pointer is set to null because of fb_nullify. -// XFAIL: * - #include <stdio.h> int x = 0; @@ -19,8 +17,10 @@ struct ST { void f2() { printf("%p\n", b); // CHECK: 0x[[#%x,ADDR:]] + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : b) - printf("%p\n", b); // OFFLOAD-NEXT: (nil) + printf("%p\n", b); // EXPECTED-OFFLOAD-NEXT: (nil) + // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] } }; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp index ad861ab12001e..beeb7526e1625 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_preserve.cpp @@ -8,8 +8,6 @@ // privatized pointer retains its original value // because of fb_preserve. -// XFAIL: * - #include <stdio.h> int x = 0; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp index cb11f52645dd8..2d4cd11463801 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_nullify.cpp @@ -7,16 +7,16 @@ // Test that when a use_device_ptr lookup fails, the // privatized pointer is set to null because of fb_nullify. -// XFAIL: * - #include <stdio.h> int x; int *xp = &x; void f1() { printf("%p\n", xp); // CHECK: 0x[[#%x,ADDR:]] + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : xp) - printf("%p\n", xp); // OFFLOAD-NEXT: (nil) + printf("%p\n", xp); // EXPECTED-OFFLOAD-NEXT: (nil) + // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp index 31ce803fc1ed0..197704f14f86a 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_fallback_preserve.cpp @@ -8,8 +8,6 @@ // privatized pointer retains its original value // because of fb_preserve. -// XFAIL: * - #include <stdio.h> int x; int *xp = &x; diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp index 230ffda4fad9a..7fa76dd69e7c0 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_nullify.cpp @@ -7,8 +7,6 @@ // Test that when a use_device_ptr lookup fails, the // privatized pointer is set to null because of fb_nullify. -// XFAIL: * - #include <stdio.h> int x; int *xp = &x; @@ -18,7 +16,8 @@ void f2() { printf("%p\n", xpr); // CHECK: 0x[[#%x,ADDR:]] // FIXME: We won't get "nil" until we start privatizing xpr. #pragma omp target data use_device_ptr(fb_nullify : xpr) - printf("%p\n", xpr); // OFFLOAD-NEXT: (nil) + printf("%p\n", xpr); // EXPECTED-OFFLOAD-NEXT: (nil) + // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] // NOOFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] } diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp index 443739814ed0d..e7f8bd48ec4fe 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_var_ref_fallback_preserve.cpp @@ -8,8 +8,6 @@ // privatized pointer retains its original value // because of fb_preserve. -// XFAIL: * - #include <stdio.h> int x; int *xp = &x; >From 660e4edf398a3840e823f9eb93abe4ff1b35954d Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Mon, 29 Dec 2025 15:21:04 -0800 Subject: [PATCH 14/16] Clang-format fixes. --- ...target_data_use_device_ptr_class_member_fallback_nullify.cpp | 2 +- ...et_data_use_device_ptr_class_member_ref_fallback_nullify.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp index e85f51736f4f7..9745276294078 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp @@ -16,7 +16,7 @@ struct ST { void f1() { printf("%p\n", a); // CHECK: 0x[[#%x,ADDR:]] - // FIXME: Update this with codegen changes for fb_nullify + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : a) printf("%p\n", a); // EXPECTED-OFFLOAD-NEXT: (nil) // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp index 00e6372a0f588..76610a95af512 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp @@ -17,7 +17,7 @@ struct ST { void f2() { printf("%p\n", b); // CHECK: 0x[[#%x,ADDR:]] - // FIXME: Update this with codegen changes for fb_nullify + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : b) printf("%p\n", b); // EXPECTED-OFFLOAD-NEXT: (nil) // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] >From 80310d75873a37273438529a97d68893f26c8d67 Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Tue, 30 Dec 2025 13:37:37 -0800 Subject: [PATCH 15/16] Clang-format changed its mind. --- ...target_data_use_device_ptr_class_member_fallback_nullify.cpp | 2 +- ...et_data_use_device_ptr_class_member_ref_fallback_nullify.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp index 9745276294078..3094446f8b44d 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_fallback_nullify.cpp @@ -16,7 +16,7 @@ struct ST { void f1() { printf("%p\n", a); // CHECK: 0x[[#%x,ADDR:]] - // FIXME: Update this with codegen changes for fb_nullify + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : a) printf("%p\n", a); // EXPECTED-OFFLOAD-NEXT: (nil) // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] diff --git a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp index 76610a95af512..39a987b08a505 100644 --- a/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp +++ b/offload/test/mapping/use_device_ptr/target_data_use_device_ptr_class_member_ref_fallback_nullify.cpp @@ -17,7 +17,7 @@ struct ST { void f2() { printf("%p\n", b); // CHECK: 0x[[#%x,ADDR:]] - // FIXME: Update this with codegen changes for fb_nullify + // FIXME: Update this with codegen changes for fb_nullify #pragma omp target data use_device_ptr(fb_nullify : b) printf("%p\n", b); // EXPECTED-OFFLOAD-NEXT: (nil) // OFFLOAD-NEXT: 0x{{0*}}[[#ADDR]] >From 1994152bb17665bb245f9b336cab0d1e25b9635a Mon Sep 17 00:00:00 2001 From: Abhinav Gaba <[email protected]> Date: Fri, 16 Jan 2026 11:10:14 -0800 Subject: [PATCH 16/16] Remove unrelated code. --- clang/include/clang/Sema/SemaOpenMP.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 58b9e4d952689..7853f29f98c25 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -1181,10 +1181,6 @@ class SemaOpenMP : public SemaBase { int OriginalSharingModifier = 0; // Default is shared int NeedDevicePtrModifier = 0; SourceLocation NeedDevicePtrModifierLoc; - int UseDevicePtrFallbackModifier = - OMPC_USE_DEVICE_PTR_FALLBACK_unknown; ///< Fallback modifier for - ///< use_device_ptr clause. - SourceLocation UseDevicePtrFallbackModifierLoc; SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> MapTypeModifiers; SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
