================
@@ -1481,17 +1481,36 @@ void collectEnclosingConstructTraits(
   // be able to match construct={target, parallel}. The final reverse yields
   // outermost-to-innermost order as required by OMPContext.
   for (; op; op = op->getParentOp()) {
-    if (mlir::isa<mlir::omp::WsloopOp>(op))
+    if (mlir::isa<mlir::omp::SimdOp>(op))
+      constructTraits.push_back(llvm::omp::TraitProperty::construct_simd_simd);
+    else if (mlir::isa<mlir::omp::WsloopOp>(op))
       constructTraits.push_back(llvm::omp::TraitProperty::construct_for_for);
-    if (mlir::isa<mlir::omp::ParallelOp>(op))
+    else if (mlir::isa<mlir::omp::ParallelOp>(op))
       constructTraits.push_back(
           llvm::omp::TraitProperty::construct_parallel_parallel);
-    if (mlir::isa<mlir::omp::TeamsOp>(op))
+    else if (mlir::isa<mlir::omp::TeamsOp>(op))
       constructTraits.push_back(
           llvm::omp::TraitProperty::construct_teams_teams);
-    if (mlir::isa<mlir::omp::TargetOp>(op))
+    else if (mlir::isa<mlir::omp::TargetOp>(op)) {
       constructTraits.push_back(
           llvm::omp::TraitProperty::construct_target_target);
+      // The construct context starts at the innermost TARGET, as in
+      // semantic analysis.
+      break;
+    } else if (mlir::isa<mlir::omp::CriticalOp, mlir::omp::DistributeOp,
----------------
MattPD wrote:

For a composite `distribute parallel do`, lowering nests `omp.parallel` above 
`omp.distribute`, so this walk records `teams, parallel, distribute, do`. 
OpenMP 5.2 section 7.1 orders the construct set by the original construct, 
`teams, distribute, parallel, do`, so `construct={parallel}` scores 2^1 + 1 = 3 
instead of 2^2 + 1 = 5.

You can reproduce this by saving the following to `composite.f90` and running 
`flang -fc1 -fopenmp -fopenmp-version=52 -emit-hlfir -o - composite.f90`:

```fortran
module m
contains
  subroutine parallel_variant()
  end subroutine
  subroutine scored_variant()
  end subroutine
  subroutine base()
    !$omp declare variant(parallel_variant) match(construct={parallel})
    !$omp declare variant(scored_variant) 
match(implementation={vendor(score(3): llvm)})
  end subroutine
  subroutine combined(n)
    integer :: n, i
    !$omp teams distribute parallel do
    do i = 1, n
      call base()
    end do
    !$omp end teams distribute parallel do
  end subroutine
end module
```

With this PR `combined` calls `scored_variant`. The same nest written as 
separate `teams`, `distribute`, and `parallel do` directives calls 
`parallel_variant`, and Clang calls the parallel variant for `teams distribute 
parallel for`. The merge base also scored PARALLEL at position 1 for this 
composite because it did not count `distribute`, so the gap predates this PR. 
PR https://github.com/llvm/llvm-project/pull/219014 derives the positions in 
semantics from the source order, so on that PR semantics and lowering disagree 
for this composite.

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