[flang-commits] [flang] [flang][OpenMP] Improve reduction of Scalar ArrayElement types (PR #163940)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Mon Nov 3 06:13:08 PST 2025


================
@@ -492,10 +573,497 @@ void RewriteMutator::Post(parser::WriteStmt &x) {
   FixMisparsedUntaggedNamelistName(x);
 }
 
+void ReplacementTemp::createTempSymbol(
+    SourceName &source, Scope &scope, SemanticsContext &context) {
+  replacementTempSymbol_ =
+      const_cast<Scope &>(originalName_.symbol->owner()).FindSymbol(source);
+  replacementTempSymbol_->set_scope(
+      &const_cast<Scope &>(originalName_.symbol->owner()));
+  DeclTypeSpec *tempType = originalName_.symbol->GetUltimate().GetType();
+  replacementTempSymbol_->get<ObjectEntityDetails>().set_type(*tempType);
+  replacementTempSymbol_->flags().set(Symbol::Flag::CompilerCreated);
+}
+
+void ReplacementTemp::setOriginalSubscriptInt(
+    std::list<parser::SectionSubscript> &sectionSubscript) {
+  bool setSubscript{false};
+
+  auto visitDataRef = [&](parser::DataRef &dataRef) {
+    std::visit(
+        llvm::makeVisitor(
+            [&](parser::Name &name) { setOriginalSubscriptInt(name.source); },
+            [&](auto &) {}),
+        dataRef.u);
+  };
+  auto visitDesignator = [&](parser::Designator &designator) {
+    std::visit(llvm::makeVisitor(
+                   [&](parser::DataRef &dataRef) { visitDataRef(dataRef); },
+                   [&](auto &) {}),
+        designator.u);
+  };
+  auto visitLiteralConstant = [&](parser::LiteralConstant &literalConstant) {
+    std::visit(llvm::makeVisitor(
+                   [&](parser::IntLiteralConstant &intLiteralConstant) {
+                     originalSubscriptCharBlock_ =
+                         std::get<parser::CharBlock>(intLiteralConstant.t);
+                     setSubscript = true;
+                   },
+                   [&](auto &) {}),
+        literalConstant.u);
+  };
+  auto visitIntExpr = [&](parser::IntExpr &intExpr) {
+    parser::Expr &expr = intExpr.thing.value();
+    std::visit(
+        llvm::makeVisitor(
+            [&](parser::LiteralConstant &literalConstant) -> void {
+              visitLiteralConstant(literalConstant);
+            },
+            [&](common::Indirection<parser::Designator> &designator) -> void {
+              visitDesignator(designator.value());
+            },
+            [&](auto &) {}),
+        expr.u);
+  };
+  for (parser::SectionSubscript &subscript : sectionSubscript) {
----------------
kparzysz wrote:

The temp needs to store all subscripts.  Consider this:
```
subroutine f00(x, y, j)
  integer :: x(:), y(:,:)
  integer :: i, j
  if (j /= 2) then
    !$omp parallel do reduction(+: y(j, 2), y(2, 2))
    do i = 1, 200
      y(j, 2) = i - y(j, 2)
      y(2, 2) = y(2, 2) + 1
    end do
    !$omp end parallel do
  end if
end
```
We have two distinct array elements in the reduction, but the transformation only updates one of them:
```
SUBROUTINE f00 (x, y, j)
 INTEGER x(:), y(:,:)
 INTEGER i, j
 IF (j/=2_4) THEN
   reduction_temp_y(2)=y(int(j,kind=8),2_8)
   reduction_temp_y(2)=y(2_8,2_8)
!$OMP PARALLEL DO REDUCTION(+: reduction_temp_y(2),reduction_temp_y(2))
  DO i=1_4,200_4
    reduction_temp_y(2)=i-reduction_temp_y(2)
    reduction_temp_y(2)=reduction_temp_y(2)+1_4
  END DO
!$OMP END PARALLEL DO
   y(int(j,kind=8),2_8)=reduction_temp_y(2)
   y(int(j,kind=8),2_8)=reduction_temp_y(2)
 END IF
END SUBROUTINE
```

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


More information about the flang-commits mailing list