[flang-commits] [flang] [flang][OpenMP] Inline the firstprivate array copy instead of calling Assign() (PR #211543)
Spencer Bryngelson via flang-commits
flang-commits at lists.llvm.org
Thu Jul 23 08:16:13 PDT 2026
================
@@ -39,6 +40,22 @@ static llvm::cl::opt<bool> inlineAllocatableExprAssignFlag(
"hlfir.expr (e.g., from hlfir.elemental)"),
llvm::cl::init(false));
+/// Is \p assign the copy-in of an `omp.private` copy region, writing the
+/// privatized clone? The operation defines its first copy-region block
+/// argument to be the original host variable and the second to be the memory
+/// allocated for the clone, so the two cannot overlap and the copy can be
+/// inlined without an aliasing check.
+static bool isOmpPrivateCopyInAssign(hlfir::AssignOp assign) {
+ mlir::Region *region = assign->getParentRegion();
+ auto privateOp =
+ llvm::dyn_cast_or_null<mlir::omp::PrivateClauseOp>(region->getParentOp());
+ if (!privateOp || region != &privateOp.getCopyRegion())
+ return false;
+ auto blockArg = llvm::dyn_cast<mlir::BlockArgument>(assign.getLhs());
----------------
sbryngelson wrote:
Both points were right and both were reachable: the two new tests below fail against the previous revision.
I dropped the provenance walk rather than extend it. Treating every regionless op as provenance-preserving was the wrong shape of check, and `fir.call` is exactly the counterexample. The predicate now matches only the canonical copy-in that lowering emits:
```mlir
^bb0(%orig, %clone):
%0 = fir.load %orig // boxed privatizer only
hlfir.assign %0 to %clone
```
It requires the assignment to be in the entry block, the LHS to be exactly `entry.getArgument(1)`, and the RHS to be either `entry.getArgument(0)` or a single `fir.load` of it. Anything else keeps the aliasing check, so there is no longer a class of operations to reason about.
Two negative tests, both accepted by the previous revision:
- `@_QFtestEf_firstprivate`: RHS from `fir.call @get_box(%arg0)`. The call may return a descriptor for memory that overlaps the clone, so skipping the check here can be wrong.
- `@_QFtestEg_firstprivate`: LHS is argument 1 of a non-entry block reached by `cf.br`. The previous revision accepted it on the argument number alone.
Both stay as `hlfir.assign`.
check-flang: 4607 passed, 11 expected failures, 0 failures. The one-element `real(8)` case still emits no `_FortranAAssign`.
https://github.com/llvm/llvm-project/pull/211543
More information about the flang-commits
mailing list