================
@@ -0,0 +1,339 @@
+! RUN: split-file %s %t
+! RUN: cd %t && %flang_fc1 -fopenmp -fopenmp-version=52 -fsyntax-only 
settings.f90
+! RUN: cd %t && %flang_fc1 -fopenmp -fopenmp-version=52 -emit-hlfir 
variants.f90 -o - | FileCheck %s --check-prefix=LOCAL
+! RUN: cd %t && %flang_fc1 -fopenmp -fopenmp-version=52 -emit-hlfir use.f90 -o 
- | FileCheck %s --check-prefix=IMPORTED
+! RUN: cd %t && %flang_fc1 -fopenmp -fopenmp-version=52 -emit-fir use.f90 -o - 
| FileCheck %s --check-prefix=IMPORTED
+
+! RUN: cd %t && %flang_fc1 -fopenmp -fopenmp-version=52 -emit-hlfir kinds.f90 
-o - | FileCheck %s --check-prefix=DEFAULT4
+! RUN: cd %t && %flang_fc1 -fopenmp -fopenmp-version=52 -fdefault-integer-8 
-emit-hlfir kinds.f90 -o - | FileCheck %s --check-prefix=DEFAULT8
+
+! Identical conditions make the CPU selector a strict superset, zeroing the
+! high-scoring variant. Distinct expressions and declarations must retain the
+! high score even when they fold to the same value.
+! LOCAL-LABEL: func.func @_QMconditionsPlocal_calls(
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPhigh()
+! LOCAL: fir.call @_QMconditionsPhigh()
+! LOCAL: fir.call @_QMconditionsPhigh()
+! LOCAL: fir.call @_QMconditionsPhigh()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: fir.call @_QMconditionsPhigh()
+! LOCAL: fir.call @_QMconditionsPhigh()
+! LOCAL: fir.call @_QMconditionsPlow()
+! LOCAL: return
+
+! Conditions referring to USE-associated names are rebuilt in the importing
+! compilation, using the loaded symbols rather than serialized pointers.
+! IMPORTED-LABEL: func.func @_QPimported_conditions(
+! IMPORTED: omp.taskwait
+! IMPORTED: omp.taskwait
+! IMPORTED: omp.taskyield
+! IMPORTED: return
+
+! Same runtime condition: the low-scoring strict superset wins when true.
+! IMPORTED-LABEL: func.func @_QPruntime_same(
+! IMPORTED: fir.if
+! IMPORTED-NEXT: omp.taskwait
+! IMPORTED-NEXT: } else {
+! IMPORTED: return
+
+! Different variables must not be merged even when their values might agree.
+! IMPORTED-LABEL: func.func @_QPruntime_distinct(
+! IMPORTED: fir.if
+! IMPORTED: omp.taskyield
+! IMPORTED: } else {
+! IMPORTED: fir.if
+! IMPORTED: omp.taskwait
+! IMPORTED: return
+
+! False conditions retain the same identity under match_none.
+! IMPORTED-LABEL: func.func @_QPfalse_conditions(
+! IMPORTED-NOT: omp.taskyield
+! IMPORTED: omp.taskwait
+! IMPORTED-NOT: omp.taskyield
+! IMPORTED: return
+
+! Both runtime outcomes under match_any retain condition identity, even when
+! the implementation selector makes each candidate applicable independently.
+! Both outcomes select TASKWAIT, so the runtime branch can be eliminated.
+! IMPORTED-LABEL: func.func @_QPruntime_any(
+! IMPORTED-NOT: fir.if
+! IMPORTED-NOT: omp.taskyield
+! IMPORTED: omp.taskwait
+! IMPORTED-NOT: fir.if
+! IMPORTED-NOT: omp.taskyield
+! IMPORTED: return
+
+!--- settings.f90
+module settings
+  logical, parameter :: on = .true., other = .true.
+  logical :: flag, other_flag
+end module
+
+!--- variants.f90
+module conditions
+  use settings, only: on, on2 => on, other
+contains
+  integer function high()
+    high = 100
+  end function
+  integer function low()
+    low = 1
+  end function
+
+  integer function parentheses()
+    !$omp declare variant(high) match(user={condition(.true.)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(((.true.)))}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    parentheses = 0
+  end function
+
+  integer function aliases()
+    !$omp declare variant(high) match(user={condition(on)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(on2)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    aliases = 0
+  end function
+
+  integer function compound_aliases()
+    !$omp declare variant(high) match(user={condition(on .and. .true.)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition((on2.and..true.))}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    compound_aliases = 0
+  end function
+
+  integer function distinct()
+    !$omp declare variant(high) match(user={condition(on)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(other)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    distinct = 0
+  end function
+
+  integer function literal_and_name()
+    !$omp declare variant(high) match(user={condition(.true.)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(on)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    literal_and_name = 0
+  end function
+
+  integer function ordered_expression()
+    !$omp declare variant(high) match(user={condition(on .and. other)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(other .and. on)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    ordered_expression = 0
+  end function
+
+  integer function character_literals()
+    !$omp declare variant(high) match(user={condition('a b' == 'a b')}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition('ab' == 'ab')}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    character_literals = 0
+  end function
+
+  integer function spelling_eq()
+    !$omp declare variant(high) match(user={condition(1 .eq. 1)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1 == 1)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_eq = 0
+  end function
+
+  integer function spelling_ne()
+    !$omp declare variant(high) match(user={condition(1 .ne. 2)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1 /= 2)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_ne = 0
+  end function
+
+  integer function spelling_lt()
+    !$omp declare variant(high) match(user={condition(1 .lt. 2)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1 < 2)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_lt = 0
+  end function
+
+  integer function spelling_le()
+    !$omp declare variant(high) match(user={condition(1 .le. 1)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1 <= 1)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_le = 0
+  end function
+
+  integer function spelling_gt()
+    !$omp declare variant(high) match(user={condition(2 .gt. 1)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(2 > 1)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_gt = 0
+  end function
+
+  integer function spelling_ge()
+    !$omp declare variant(high) match(user={condition(1 .ge. 1)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1 >= 1)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_ge = 0
+  end function
+
+  integer function spelling_integer_kind()
+    !$omp declare variant(high) match(user={condition(1 == 1)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1_4 == 1_4)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_integer_kind = 0
+  end function
+
+  integer function spelling_distinct_kind()
+    !$omp declare variant(high) match(user={condition(1_4 == 1_4)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition(1_8 == 1_8)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_distinct_kind = 0
+  end function
+
+  integer function spelling_complex_values()
+    !$omp declare variant(high) match(user={condition((1,2) == (1,2))}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) match(user={condition((1,3) == (1,3))}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_complex_values = 0
+  end function
+
+  ! The positive magnitude is out of range, but the signed literal is valid.
+  integer function spelling_integer_min()
+    !$omp declare variant(high) &
+    !$omp& match(user={condition(-2147483648 == -2147483648)}, &
+    !$omp& implementation={vendor(score(100): llvm)})
+    !$omp declare variant(low) &
+    !$omp& match(user={condition(-2147483648_4 == -2147483648_4)}, &
+    !$omp& implementation={vendor(score(1): llvm)}, device={kind(cpu)})
+    spelling_integer_min = 0
+  end function
+
+  subroutine local_calls(a)
+    integer :: a(17)
+    a(1) = parentheses()
+    a(2) = aliases()
+    a(3) = compound_aliases()
+    a(4) = distinct()
+    a(5) = literal_and_name()
+    a(6) = ordered_expression()
+    a(7) = character_literals()
+    a(8) = spelling_eq()
+    a(9) = spelling_ne()
+    a(10) = spelling_lt()
+    a(11) = spelling_le()
+    a(12) = spelling_gt()
+    a(13) = spelling_ge()
+    a(14) = spelling_integer_kind()
+    a(15) = spelling_distinct_kind()
+    a(16) = spelling_complex_values()
+    a(17) = spelling_integer_min()
+  end subroutine
+end module
+
+!--- use.f90
+subroutine imported_conditions()
+  use settings, only: on, alias => on, other
+  !$omp metadirective &
+  !$omp& when(user={condition(on)}, &
+  !$omp& implementation={vendor(score(100): llvm)}: taskyield) &
+  !$omp& when(user={condition((alias))}, device={kind(cpu)}, &
+  !$omp& implementation={vendor(score(1): llvm)}: taskwait)
+  !$omp metadirective &
+  !$omp& when(user={condition(.true.)}, &
+  !$omp& implementation={vendor(score(100): llvm)}: taskyield) &
+  !$omp& when(user={condition((.true.))}, device={kind(cpu)}, &
+  !$omp& implementation={vendor(score(1): llvm)}: taskwait)
+  !$omp metadirective &
+  !$omp& when(user={condition(on)}, &
+  !$omp& implementation={vendor(score(100): llvm)}: taskyield) &
+  !$omp& when(user={condition(other)}, device={kind(cpu)}, &
+  !$omp& implementation={vendor(score(1): llvm)}: taskwait)
+end subroutine
+
+subroutine runtime_same()
+  use settings, only: flag, alias => flag
+  !$omp metadirective &
+  !$omp& when(user={condition(flag)}, &
+  !$omp& implementation={vendor(score(100): llvm)}: taskyield) &
+  !$omp& when(user={condition((alias))}, device={kind(cpu)}, &
+  !$omp& implementation={vendor(score(1): llvm)}: taskwait)
+end subroutine
+
+subroutine runtime_distinct()
+  use settings, only: flag, other_flag
+  !$omp metadirective &
+  !$omp& when(user={condition(flag)}, &
+  !$omp& implementation={vendor(score(100): llvm)}: taskyield) &
+  !$omp& when(user={condition(other_flag)}, device={kind(cpu)}, &
+  !$omp& implementation={vendor(score(1): llvm)}: taskwait)
+end subroutine
+
+subroutine false_conditions()
+  !$omp metadirective &
+  !$omp& when(user={condition(.false.)}, &
+  !$omp& implementation={extension(match_none), vendor(score(100): gnu)}: 
taskyield) &
+  !$omp& when(user={condition((.false.))}, device={kind(gpu)}, &
+  !$omp& implementation={extension(match_none), vendor(score(1): gnu)}: 
taskwait)
+end subroutine
+
+subroutine runtime_any()
+  use settings, only: flag, alias => flag
+  !$omp metadirective &
+  !$omp& when(user={condition(flag)}, &
+  !$omp& implementation={extension(match_any), vendor(score(100): llvm)}: 
taskyield) &
+  !$omp& when(user={condition((alias))}, device={kind(cpu)}, &
+  !$omp& implementation={extension(match_any), vendor(score(1): llvm)}: 
taskwait)
+end subroutine
+
+! Imported-symbol runtime expressions also normalize relational operators.
+! IMPORTED-LABEL: func.func @_QPruntime_operators(
+! IMPORTED-NOT: omp.taskyield
+! IMPORTED: fir.if
+! IMPORTED: omp.taskwait
----------------
MattPD wrote:

Confirmed at 3080eca: The `runtime_operators` block now also requires 
`omp.taskwait` in the first arm.

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