================
@@ -1,93 +1,169 @@
-! Test lowering of OpenMP metadirective with user={condition()} selectors.
+! Test lowering of OpenMP metadirective with dynamic user={condition()}
+! selectors.
 
-! RUN: %flang_fc1 -fopenmp -emit-hlfir -fopenmp-version=50 %s -o - | FileCheck 
%s
 ! RUN: %flang_fc1 -fopenmp -emit-hlfir -fopenmp-version=51 %s -o - | FileCheck 
%s
 ! RUN: %flang_fc1 -fopenmp -emit-hlfir -fopenmp-version=52 -cpp -DOMP_52 %s -o 
- | FileCheck %s
 
 !===----------------------------------------------------------------------===!
-! Static (constant-folded) user conditions
+! Unknown ARCH retains its weight even when only the runtime condition matches.
+! CHECK-LABEL: func.func @_QPtest_unknown_arch_weight(
+! CHECK: fir.if
+! CHECK-NEXT: omp.barrier
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.taskyield
+! CHECK: return
+subroutine test_unknown_arch_weight(flag)
+  logical :: flag
+  !$omp metadirective &
+  !$omp& when(device={arch(bogus_arch)}, &
+  !$omp& implementation={extension(match_any)}, &
+  !$omp& user={condition(flag)}: barrier) &
+  !$omp& when(user={condition(score(1): .true.)}: taskyield)
+end subroutine
+
+! Selectors with unknown properties retain their separate scores,
+! regardless of selector order.
+! CHECK-LABEL: func.func @_QPtest_unknown_selector_scores(
+! CHECK: fir.if
+! CHECK-NEXT: omp.barrier
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.taskyield
+! CHECK: return
+subroutine test_unknown_selector_scores(flag)
+  logical :: flag
+  !$omp metadirective &
+  !$omp& when(implementation={vendor(score(10): bogus_vendor), &
+  !$omp& extension(score(1): match_any, bogus_extension)}, &
+  !$omp& user={condition(score(5): flag)}: barrier) &
+  !$omp& when(implementation={vendor(score(10): llvm)}: taskyield)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_unknown_selector_scores_reversed(
+! CHECK: fir.if
+! CHECK-NEXT: omp.barrier
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.taskyield
+! CHECK: return
+subroutine test_unknown_selector_scores_reversed(flag)
+  logical :: flag
+  !$omp metadirective &
+  !$omp& when(implementation={extension(score(1): match_any, bogus_extension), 
&
+  !$omp& vendor(score(10): bogus_vendor)}, &
+  !$omp& user={condition(score(5): flag)}: barrier) &
+  !$omp& when(implementation={vendor(score(10): llvm)}: taskyield)
+end subroutine
+
+! An unknown vendor does not veto a runtime MATCH_ANY condition or its score.
+! CHECK-LABEL: func.func @_QPtest_dynamic_unknown_vendor(
+! CHECK: fir.if
+! CHECK-NEXT: omp.barrier
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.taskyield
+! CHECK: return
+subroutine test_dynamic_unknown_vendor(flag)
+  logical :: flag
+  !$omp metadirective &
+  !$omp& when(implementation={vendor(bogus_vendor), extension(match_any)}, &
+  !$omp& user={condition(score(5): flag)}: barrier) &
+  !$omp& when(user={condition(.true.)}: taskyield)
+end subroutine
+
+! The same rule applies to unknown device traits and implicit NOTHING.
+! CHECK-LABEL: func.func @_QPtest_dynamic_unknown_arch_implicit(
+! CHECK: fir.if
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.barrier
+! CHECK: return
+subroutine test_dynamic_unknown_arch_implicit(flag)
+  logical :: flag
+  !$omp metadirective &
+  !$omp& when(device={arch(bogus_arch)}, &
+  !$omp& implementation={extension(match_any)}, &
+  !$omp& user={condition(score(10): flag)}:) &
+  !$omp& when(user={condition(score(5): .true.)}: barrier)
+end subroutine
+
+! Scored implicit NOTHING competes with explicit replacements by score.
 !===----------------------------------------------------------------------===!
 
-! CHECK-LABEL: func.func @_QPtest_condition_true()
-! CHECK:         omp.taskyield
-! CHECK-NOT:     fir.if
-! CHECK:         return
-subroutine test_condition_true()
+! CHECK-LABEL: func.func @_QPtest_implicit_nothing_score(
+! CHECK: fir.if
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.barrier
+! CHECK: return
+subroutine test_implicit_nothing_score(flag)
+  logical :: flag
   !$omp metadirective &
-  !$omp & when(user={condition(.true.)}: taskyield) &
-#ifdef OMP_52
-  !$omp & otherwise(nothing)
-#else
-  !$omp & default(nothing)
-#endif
+  !$omp& when(user={condition(score(10): flag)}:) &
+  !$omp& when(user={condition(score(5): .true.)}: barrier)
 end subroutine
 
-! CHECK-LABEL: func.func @_QPtest_condition_false()
-! CHECK-NOT:     omp.taskwait
-! CHECK-NOT:     fir.if
-! CHECK:         return
-subroutine test_condition_false()
+! Explicit NOTHING with the same score must produce the same selection.
+! CHECK-LABEL: func.func @_QPtest_explicit_nothing_score(
+! CHECK: fir.if
+! CHECK-NEXT: } else {
+! CHECK-NEXT: omp.barrier
+! CHECK: return
+subroutine test_explicit_nothing_score(flag)
+  logical :: flag
   !$omp metadirective &
-  !$omp & when(user={condition(.false.)}: taskwait) &
-#ifdef OMP_52
-  !$omp & otherwise(nothing)
-#else
-  !$omp & default(nothing)
-#endif
+  !$omp& when(user={condition(score(10): flag)}: nothing) &
+  !$omp& when(user={condition(score(5): .true.)}: barrier)
 end subroutine
 
-! CHECK-LABEL: func.func @_QPtest_condition_score()
-! CHECK-NOT:     omp.taskyield
-! CHECK:         omp.taskwait
-! CHECK:         return
-subroutine test_condition_score()
+! Equal scores favor the explicit replacement without a runtime branch.
+! CHECK-LABEL: func.func @_QPtest_implicit_nothing_equal_score(
+! CHECK-NOT: fir.if
+! CHECK: omp.barrier
+! CHECK-NEXT: return
+subroutine test_implicit_nothing_equal_score(flag)
+  logical :: flag
   !$omp metadirective &
-  !$omp & when(user={condition(.true.)}: taskyield) &
-  !$omp & when(user={condition(score(2): .true.)}: taskwait) &
-#ifdef OMP_52
-  !$omp & otherwise(nothing)
-#else
-  !$omp & default(nothing)
-#endif
+  !$omp& when(user={condition(score(5): flag)}:) &
+  !$omp& when(user={condition(score(5): .true.)}: barrier)
 end subroutine
 
-! CHECK-LABEL: func.func @_QPtest_begin_condition_true()
-! CHECK:         omp.parallel
-! CHECK:           omp.terminator
-! CHECK-NOT:     fir.if
-! CHECK:         return
-subroutine test_begin_condition_true()
-  integer :: x
-  x = 0
-#ifdef OMP_52
-  !$omp begin metadirective &
-  !$omp & when(user={condition(.true.)}: parallel) &
-  !$omp & otherwise(nothing)
-#else
-  !$omp begin metadirective &
-  !$omp & when(user={condition(.true.)}: parallel)
-#endif
-  x = 1
-  !$omp end metadirective
+! MATCH_ANY still needs a scored runtime candidate when a static trait matches.
----------------
MattPD wrote:

Is the false-path result here the intended contract for `match_any`? When 
`vendor(llvm)` already satisfies `match_any`, the unguarded candidate is built 
from the static traits and the condition's `score(10)` is dropped. With `flag` 
false at run time, that candidate scores 1 against 6, and `barrier` wins. With 
the constant `.false.` in place of `flag`, the same candidate keeps its score, 
11 against 6, and `barrier` is not emitted. A condition known false at compile 
time and one false at run time therefore select different replacements. Unknown 
properties also keep their selector scores under `match_any` in this PR, which 
matches the compile-time case rather than the runtime one. I can see the 
argument that a false condition should contribute nothing. If the runtime 
result is the intended one, the static case should probably match it.

https://github.com/llvm/llvm-project/pull/224431
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to