[flang-commits] [flang] [flang][OpenMP] Fix wrong results for FORALL in a workshare construct (PR #211371)

Tom Eccles via flang-commits flang-commits at lists.llvm.org
Mon Aug 3 03:52:10 PDT 2026


================
@@ -259,6 +259,95 @@ static bool isSafeToParallelize(Operation *op) {
   return false;
 }
 
+// Returns the underlying thread-local storage that mem refers to, or null if
+// mem is not thread-local. The alias analysis is used to look through
+// fir.declare/hlfir.declare, fir.convert, fir.rebox, etc., so that two
+// accesses of the same thread-local location yield the same value even if one
+// goes through such ops and the other does not. This is what makes it safe to
+// match the reads and writes of collect{Reads,Writes} against each other by
+// value identity: a store to an alloca and a load from a fir.declare of that
+// alloca map to the same key. Matching the raw effect value instead would
+// silently miss such accesses, dropping a required broadcast.
+static Value getOpenMPThreadLocalSource(Operation *op, Value mem) {
+  if (!isOpenMPThreadLocalMemory(op, mem))
+    return nullptr;
+  fir::AliasAnalysis aliasAnalysis;
+  return llvm::dyn_cast_if_present<mlir::Value>(
+      aliasAnalysis.getSource(mem).origin.u);
----------------
tblah wrote:

Codex pointed out that the result of the private clause and the result of a hlfir.declare of that private clause result will produce different origins from alias analysis. There is already handling for this in `isOpenMPThreadLocalMemory`.

e.g.
```
omp.parallel private(... -> %priv_arg) {
  %decl:2 = hlfir.declare %priv_arg

  omp.workshare {
    fir.store %value to %decl#0
  }

  %read = fir.load %priv_arg
}
// getOpenMPThreadLocalSource(%decl#0)  = %decl#0
// getOpenMPThreadLocalSource(%priv_arg) = %priv_arg
```

https://github.com/llvm/llvm-project/pull/211371


More information about the flang-commits mailing list