[flang-commits] [flang] Revert "[Flang]Add support for inlining hlfir.assign operation where both LHS and RHS are slices of the same array" (PR #206103)

via flang-commits flang-commits at lists.llvm.org
Fri Jun 26 08:23:55 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Eugene Epshteyn (eugeneepshteyn)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->204532 due to regressions in numerous Fujitsu tests and several important apps

---

Patch is 45.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/206103.diff


8 Files Affected:

- (modified) flang/include/flang/Optimizer/Analysis/ArraySectionAnalyzer.h (+1-1) 
- (modified) flang/include/flang/Optimizer/Builder/FIRBuilder.h (-10) 
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (-137) 
- (modified) flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp (+12-48) 
- (removed) flang/test/HLFIR/inline-hlfir-assign-pointer-overlap.fir (-132) 
- (removed) flang/test/HLFIR/inline-hlfir-assign-scalar-index.fir (-98) 
- (removed) flang/test/HLFIR/inline-hlfir-assign-self-copy-runtime-stride.fir (-141) 
- (removed) flang/test/HLFIR/inline-hlfir-assign-self-copy.fir (-178) 


``````````diff
diff --git a/flang/include/flang/Optimizer/Analysis/ArraySectionAnalyzer.h b/flang/include/flang/Optimizer/Analysis/ArraySectionAnalyzer.h
index aae9cbde2d7be..e87e37c3c5590 100644
--- a/flang/include/flang/Optimizer/Analysis/ArraySectionAnalyzer.h
+++ b/flang/include/flang/Optimizer/Analysis/ArraySectionAnalyzer.h
@@ -65,6 +65,7 @@ class ArraySectionAnalyzer {
   static bool isDesignatingArrayInOrder(hlfir::DesignateOp designate,
                                         hlfir::ElementalOpInterface elemental);
 
+private:
   struct SectionDesc {
     // An array section is described by <lb, ub, stride> tuple.
     // If the designator's subscript is not a triple, then
@@ -102,7 +103,6 @@ class ArraySectionAnalyzer {
   static std::pair<mlir::Value, mlir::Value>
   getOrderedBounds(const SectionDesc &desc);
 
-private:
   // Given two array sections <lb1, ub1, stride1> and
   // <lb2, ub2, stride2>, return true only if the sections
   // are known to be disjoint.
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 6592c384541d4..a41be5efacb56 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -988,16 +988,6 @@ mlir::Value getDescriptorWithNewBaseAddress(fir::FirOpBuilder &builder,
                                             mlir::Location loc, mlir::Value box,
                                             mlir::Value newAddr);
 
-/// Generate a index-based disjointness check.
-std::optional<mlir::Value>
-genIndexBasedDisjointnessCheck(mlir::Location loc, fir::FirOpBuilder &builder,
-                               mlir::Value lhsRef, mlir::Value rhsRef);
-
-/// Generate a address-based disjointness check.
-std::optional<mlir::Value>
-genAddressBasedDisjointnessCheck(mlir::Location loc, fir::FirOpBuilder &builder,
-                                 mlir::Value lhsRef, mlir::Value rhsRef);
-
 } // namespace fir::factory
 
 #endif // FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index 5cbc9fcedc9b5..c7df3abda156c 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -8,7 +8,6 @@
 
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Analysis/AliasAnalysis.h"
-#include "flang/Optimizer/Analysis/ArraySectionAnalyzer.h"
 #include "flang/Optimizer/Builder/BoxValue.h"
 #include "flang/Optimizer/Builder/Character.h"
 #include "flang/Optimizer/Builder/Complex.h"
@@ -22,12 +21,10 @@
 #include "flang/Optimizer/Dialect/FIRDialect.h"
 #include "flang/Optimizer/Dialect/FIROpsSupport.h"
 #include "flang/Optimizer/Dialect/FIRType.h"
-#include "flang/Optimizer/HLFIR/HLFIROps.h"
 #include "flang/Optimizer/Support/DataLayout.h"
 #include "flang/Optimizer/Support/FatalError.h"
 #include "flang/Optimizer/Support/InternalNames.h"
 #include "flang/Optimizer/Support/Utils.h"
-#include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/Dialect/OpenACC/OpenACC.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
@@ -2009,137 +2006,3 @@ mlir::Value fir::factory::getDescriptorWithNewBaseAddress(
   return builder.createBox(loc, boxType, newAddr, shape, /*slice=*/{},
                            fir::getTypeParams(openedInput), typeMold);
 }
-
-std::optional<mlir::Value> fir::factory::genIndexBasedDisjointnessCheck(
-    mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value lhsRef,
-    mlir::Value rhsRef) {
-  auto des1 = lhsRef.getDefiningOp<hlfir::DesignateOp>();
-  auto des2 = rhsRef.getDefiningOp<hlfir::DesignateOp>();
-  if (!des1 || !des2)
-    return std::nullopt;
-
-  if (des1.getMemref() != des2.getMemref())
-    return std::nullopt;
-
-  if (des1.getComponent() != des2.getComponent() ||
-      des1.getComponentShape() != des2.getComponentShape() ||
-      des1.getSubstring() != des2.getSubstring() ||
-      des1.getComplexPart() != des2.getComplexPart() ||
-      des1.getTypeparams() != des2.getTypeparams())
-    return std::nullopt;
-
-  if (des1.getIsTriplet().empty() ||
-      !llvm::equal(des1.getIsTriplet(), des2.getIsTriplet()))
-    return std::nullopt;
-
-  using Analyzer = fir::ArraySectionAnalyzer;
-  mlir::Type idxTy = builder.getIndexType();
-  auto toIdx = [&](mlir::Value v) -> mlir::Value {
-    return fir::ConvertOp::create(builder, loc, idxTy, v);
-  };
-
-  mlir::Value disjoint;
-  auto des1It = des1.getIndices().begin();
-  auto des2It = des2.getIndices().begin();
-  for (bool isTriplet : des1.getIsTriplet()) {
-    Analyzer::SectionDesc desc1 = Analyzer::readSectionDesc(des1It, isTriplet);
-    Analyzer::SectionDesc desc2 = Analyzer::readSectionDesc(des2It, isTriplet);
-    auto [lb1, ub1] = Analyzer::getOrderedBounds(desc1);
-    auto [lb2, ub2] = Analyzer::getOrderedBounds(desc2);
-    if (!lb1 || !lb2)
-      continue;
-
-    mlir::Value c1 = mlir::arith::CmpIOp::create(
-        builder, loc, mlir::arith::CmpIPredicate::slt, toIdx(ub1), toIdx(lb2));
-    mlir::Value c2 = mlir::arith::CmpIOp::create(
-        builder, loc, mlir::arith::CmpIPredicate::slt, toIdx(ub2), toIdx(lb1));
-    mlir::Value c1Orc2 = mlir::arith::OrIOp::create(builder, loc, c1, c2);
-    disjoint = disjoint
-                   ? mlir::arith::OrIOp::create(builder, loc, disjoint, c1Orc2)
-                   : c1Orc2;
-  }
-  if (!disjoint)
-    return std::nullopt;
-  return disjoint;
-}
-
-std::optional<mlir::Value> fir::factory::genAddressBasedDisjointnessCheck(
-    mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value lhsRef,
-    mlir::Value rhsRef) {
-  if (!mlir::isa<fir::BaseBoxType>(lhsRef.getType()) ||
-      !mlir::isa<fir::BaseBoxType>(rhsRef.getType()))
-    return std::nullopt;
-
-  mlir::Type idxTy = builder.getIndexType();
-  mlir::Type intPtrTy = builder.getIntPtrType();
-
-  //   Disjoint if: xEnd < yStart || yEnd < xStart.
-  auto computeRange =
-      [&](mlir::Value box) -> std::pair<mlir::Value, mlir::Value> {
-    mlir::Value baseAddr = fir::BoxAddrOp::create(builder, loc, box);
-    mlir::Value baseInt =
-        fir::ConvertOp::create(builder, loc, intPtrTy, baseAddr);
-
-    mlir::Value eleSize = fir::BoxEleSizeOp::create(builder, loc, idxTy, box);
-    mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
-    mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
-
-    mlir::Value least = zero;
-    mlir::Value most = zero;
-
-    auto boxTy = mlir::cast<fir::BaseBoxType>(box.getType());
-    unsigned rank = 0;
-    if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(
-            fir::unwrapRefType(boxTy.getEleTy())))
-      rank = seqTy.getShape().size();
-
-    if (rank == 0)
-      return {nullptr, nullptr};
-
-    for (unsigned dim = 0; dim < rank; ++dim) {
-      mlir::Value dimVal = builder.createIntegerConstant(loc, idxTy, dim);
-      auto dims = fir::BoxDimsOp::create(builder, loc, idxTy, idxTy, idxTy, box,
-                                         dimVal);
-      mlir::Value extent = dims.getExtent();
-      mlir::Value stride = dims.getByteStride();
-
-      mlir::Value extentM1 =
-          mlir::arith::SubIOp::create(builder, loc, extent, one);
-      mlir::Value dimOffset =
-          mlir::arith::MulIOp::create(builder, loc, extentM1, stride);
-
-      mlir::Value isStrideNeg = mlir::arith::CmpIOp::create(
-          builder, loc, mlir::arith::CmpIPredicate::slt, stride, zero);
-      mlir::Value addToLeast = mlir::arith::SelectOp::create(
-          builder, loc, isStrideNeg, dimOffset, zero);
-      mlir::Value addToMost = mlir::arith::SelectOp::create(
-          builder, loc, isStrideNeg, zero, dimOffset);
-      least = mlir::arith::AddIOp::create(builder, loc, least, addToLeast);
-      most = mlir::arith::AddIOp::create(builder, loc, most, addToMost);
-    }
-
-    mlir::Value eleSizeM1 =
-        mlir::arith::SubIOp::create(builder, loc, eleSize, one);
-    most = mlir::arith::AddIOp::create(builder, loc, most, eleSizeM1);
-
-    mlir::Value leastInt =
-        fir::ConvertOp::create(builder, loc, intPtrTy, least);
-    mlir::Value mostInt = fir::ConvertOp::create(builder, loc, intPtrTy, most);
-    mlir::Value rangeStart =
-        mlir::arith::AddIOp::create(builder, loc, baseInt, leastInt);
-    mlir::Value rangeEnd =
-        mlir::arith::AddIOp::create(builder, loc, baseInt, mostInt);
-    return {rangeStart, rangeEnd};
-  };
-
-  auto [lhsStart, lhsEnd] = computeRange(lhsRef);
-  auto [rhsStart, rhsEnd] = computeRange(rhsRef);
-  if (!lhsStart || !rhsStart)
-    return std::nullopt;
-
-  mlir::Value cond1 = mlir::arith::CmpIOp::create(
-      builder, loc, mlir::arith::CmpIPredicate::ult, lhsEnd, rhsStart);
-  mlir::Value cond2 = mlir::arith::CmpIOp::create(
-      builder, loc, mlir::arith::CmpIPredicate::ult, rhsEnd, lhsStart);
-  return mlir::arith::OrIOp::create(builder, loc, cond1, cond2);
-}
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp b/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
index e6dac7e7cabf8..b795d0b46da85 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
@@ -103,9 +103,11 @@ class InlineHLFIRAssignConversion
       return rewriter.notifyMatchFailure(assign,
                                          "RHS/LHS element types mismatch");
 
-    bool rhsNeedsTemporary = false;
-
     if (rhs.isArray() && !mlir::isa<hlfir::ExprType>(rhs.getType())) {
+      // If RHS is not an hlfir.expr, then we should prove that
+      // LHS and RHS do not alias.
+      // TODO: if they may alias, we can insert hlfir.as_expr for RHS,
+      // and proceed with the inlining.
       fir::AliasAnalysis aliasAnalysis;
       mlir::AliasResult aliasRes = aliasAnalysis.alias(lhs, rhs);
       if (!aliasRes.isNo()) {
@@ -119,14 +121,7 @@ class InlineHLFIRAssignConversion
                                   << "\tLHS: " << lhs << "\n"
                                   << "\tRHS: " << rhs << "\n"
                                   << "\tALIAS: " << aliasRes << "\n");
-          // Overlap is Unknown: unsafe to read RHS while writing LHS
-          // without a temp. Call genIndexBasedDisjointnessCheck(..) or
-          // genAddressBasedDisjointnessCheck(..) to check if the slices are
-          // disjoint.
-          // 1. If disjoint -> direct element-wise copy (no temp).
-          // 2. If not disjoint -> allocate a temporary and copy RHS into it,
-          // then copy the temporary to LHS..
-          rhsNeedsTemporary = true;
+          return rewriter.notifyMatchFailure(assign, "RHS/LHS may alias");
         }
       }
     }
@@ -135,42 +130,6 @@ class InlineHLFIRAssignConversion
     fir::FirOpBuilder builder(rewriter, assign.getOperation());
     builder.setInsertionPoint(assign);
 
-    const bool useWorkshare = flangomp::shouldUseWorkshareLowering(assign);
-    mlir::ArrayAttr accessGroups;
-    if (auto attrs = assign.getOperation()->getAttrOfType<mlir::ArrayAttr>(
-            fir::getAccessGroupsAttrName()))
-      accessGroups = attrs;
-
-    auto emitAssignFrom = [&](hlfir::Entity rhsEntity) {
-      hlfir::genNoAliasArrayAssignment(
-          loc, builder, rhsEntity, lhs, useWorkshare,
-          /*temporaryLHS=*/false, nullptr, accessGroups);
-    };
-
-    if (rhsNeedsTemporary) {
-      std::optional<mlir::Value> disjoint =
-          fir::factory::genIndexBasedDisjointnessCheck(loc, builder, lhs, rhs);
-      if (!disjoint) {
-        disjoint = fir::factory::genAddressBasedDisjointnessCheck(loc, builder,
-                                                                  lhs, rhs);
-      }
-      if (!disjoint)
-        return rewriter.notifyMatchFailure(
-            assign, "Failed to generate runtime disjointness check,"
-                    "deferring to runtime assignment implementation");
-
-      builder.genIfThenElse(loc, *disjoint)
-          .genThen([&]() { emitAssignFrom(rhs); })
-          .genElse([&]() {
-            mlir::Value tempExpr = hlfir::AsExprOp::create(builder, loc, rhs);
-            emitAssignFrom(hlfir::Entity{tempExpr});
-            hlfir::DestroyOp::create(builder, loc, tempExpr);
-          })
-          .end();
-      rewriter.eraseOp(assign);
-      return mlir::success();
-    }
-
     // Materialize scalar RHS before the assignment loop. Fortran 10.2.1.3
     // requires that the RHS expression is fully evaluated before any part
     // of the LHS variable is defined. When the scalar RHS is a reference
@@ -179,8 +138,13 @@ class InlineHLFIRAssignConversion
     if (!rhs.isArray())
       rhs = hlfir::loadTrivialScalar(loc, builder, rhs);
 
-    emitAssignFrom(rhs);
-
+    mlir::ArrayAttr accessGroups;
+    if (auto attrs = assign.getOperation()->getAttrOfType<mlir::ArrayAttr>(
+            fir::getAccessGroupsAttrName()))
+      accessGroups = attrs;
+    hlfir::genNoAliasArrayAssignment(
+        loc, builder, rhs, lhs, flangomp::shouldUseWorkshareLowering(assign),
+        /*temporaryLHS=*/false, /*combiner=*/nullptr, accessGroups);
     rewriter.eraseOp(assign);
     return mlir::success();
   }
diff --git a/flang/test/HLFIR/inline-hlfir-assign-pointer-overlap.fir b/flang/test/HLFIR/inline-hlfir-assign-pointer-overlap.fir
deleted file mode 100644
index cb3fa5334e568..0000000000000
--- a/flang/test/HLFIR/inline-hlfir-assign-pointer-overlap.fir
+++ /dev/null
@@ -1,132 +0,0 @@
-// Test inlining of hlfir.assign for pointer-based array assignment
-
-// RUN: fir-opt --inline-hlfir-assign %s | FileCheck %s
-
-// Fortran source code:
-//  subroutine assign_pointers(arr, N, lo1, hi1, lo2, hi2)
-//    integer, intent(in)    :: N, lo1, hi1, lo2, hi2
-//    integer, pointer, intent(inout) :: arr(:)
-//    integer, pointer :: p1(:), p2(:)
-//
-//    p1 => arr(lo1:hi1)
-//    p2 => arr(lo2:hi2)
-//
-//    p1 = p2
-//  end subroutine assign_pointers
-
-// CHECK-LABEL: func.func @_QPassign_pointers
-
-// Address-based runtime disjointness check:
-// CHECK: %[[LHS_ADDR:.*]] = fir.box_addr %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
-// CHECK: %[[LHS_BASE:.*]] = fir.convert %[[LHS_ADDR]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
-// CHECK: fir.box_elesize %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> index
-// CHECK: fir.box_dims %{{.*}}, %{{.*}}
-// CHECK: arith.subi %{{.*}}, %{{.*}} : index
-// CHECK: arith.muli %{{.*}}, %{{.*}} : index
-// CHECK: arith.cmpi slt, %{{.*}}, %{{.*}} : index
-// CHECK: arith.select %{{.*}}, %{{.*}}, %{{.*}} : index
-// CHECK: arith.select %{{.*}}, %{{.*}}, %{{.*}} : index
-// CHECK: arith.subi %{{.*}}, %{{.*}} : index
-// CHECK: arith.addi %{{.*}}, %{{.*}} : index
-// CHECK: fir.convert %{{.*}} : (index) -> i64
-// CHECK: fir.convert %{{.*}} : (index) -> i64
-// CHECK: %[[LHS_START:.*]] = arith.addi %[[LHS_BASE]], %{{.*}} : i64
-// CHECK: %[[LHS_END:.*]] = arith.addi %[[LHS_BASE]], %{{.*}} : i64
-// CHECK: %[[RHS_ADDR:.*]] = fir.box_addr %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
-// CHECK: %[[RHS_BASE:.*]] = fir.convert %[[RHS_ADDR]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
-// CHECK: fir.box_elesize %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> index
-// CHECK: fir.box_dims %{{.*}}, %{{.*}}
-// CHECK: arith.subi %{{.*}}, %{{.*}} : index
-// CHECK: arith.muli %{{.*}}, %{{.*}} : index
-// CHECK: arith.cmpi slt, %{{.*}}, %{{.*}} : index
-// CHECK: arith.select %{{.*}}, %{{.*}}, %{{.*}} : index
-// CHECK: arith.select %{{.*}}, %{{.*}}, %{{.*}} : index
-// CHECK: arith.subi %{{.*}}, %{{.*}} : index
-// CHECK: arith.addi %{{.*}}, %{{.*}} : index
-// CHECK: fir.convert %{{.*}} : (index) -> i64
-// CHECK: fir.convert %{{.*}} : (index) -> i64
-// CHECK: %[[RHS_START:.*]] = arith.addi %[[RHS_BASE]], %{{.*}} : i64
-// CHECK: %[[RHS_END:.*]] = arith.addi %[[RHS_BASE]], %{{.*}} : i64
-// CHECK: %[[CMP1:.*]] = arith.cmpi ult, %[[LHS_END]], %[[RHS_START]] : i64
-// CHECK: %[[CMP2:.*]] = arith.cmpi ult, %[[RHS_END]], %[[LHS_START]] : i64
-// CHECK: %[[DISJOINT:.*]] = arith.ori %[[CMP1]], %[[CMP2]] : i1
-// CHECK: fir.if %[[DISJOINT]] {
-// CHECK:   fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered {
-// CHECK:     hlfir.designate
-// CHECK:     fir.load
-// CHECK:     hlfir.designate
-// CHECK:     hlfir.assign %{{.*}} to %{{.*}} : i32, !fir.ref<i32>
-// CHECK:   }
-// CHECK: } else {
-// CHECK:   %[[EXPR:.*]] = hlfir.as_expr %{{.*}}
-// CHECK:   fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered {
-// CHECK:     hlfir.apply %[[EXPR]], %{{.*}}
-// CHECK:     hlfir.designate
-// CHECK:     hlfir.assign %{{.*}} to %{{.*}} : i32, !fir.ref<i32>
-// CHECK:   }
-// CHECK:   hlfir.destroy %[[EXPR]]
-// CHECK: }
-
-func.func @_QPassign_pointers(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "arr"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}, %arg2: !fir.ref<i32> {fir.bindc_name = "lo1"}, %arg3: !fir.ref<i32> {fir.bindc_name = "hi1"}, %arg4: !fir.ref<i32> {fir.bindc_name = "lo2"}, %arg5: !fir.ref<i32> {fir.bindc_name = "hi2"}) {
-  %0 = fir.dummy_scope : !fir.dscope
-  %1:2 = hlfir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_inout, pointer>, uniq_name = "_QFassign_pointersEarr"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
-  %2:2 = hlfir.declare %arg3 dummy_scope %0 arg 4 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFassign_pointersEhi1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-  %3:2 = hlfir.declare %arg5 dummy_scope %0 arg 6 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFassign_pointersEhi2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-  %4:2 = hlfir.declare %arg2 dummy_scope %0 arg 3 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFassign_pointersElo1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-  %5:2 = hlfir.declare %arg4 dummy_scope %0 arg 5 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFassign_pointersElo2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-  %6:2 = hlfir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFassign_pointersEn"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
-  %7 = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>> {bindc_name = "p1", uniq_name = "_QFassign_pointersEp1"}
-  %8 = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
-  %c0 = arith.constant 0 : index
-  %9 = fir.shape %c0 : (index) -> !fir.shape<1>
-  %10 = fir.embox %8(%9) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
-  fir.store %10 to %7 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  %11:2 = hlfir.declare %7 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFassign_pointersEp1"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
-  %12 = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>> {bindc_name = "p2", uniq_name = "_QFassign_pointersEp2"}
-  %13 = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
-  %c0_0 = arith.constant 0 : index
-  %14 = fir.shape %c0_0 : (index) -> !fir.shape<1>
-  %15 = fir.embox %13(%14) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
-  fir.store %15 to %12 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  %16:2 = hlfir.declare %12 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFassign_pointersEp2"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
-  %17 = fir.load %1#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  %18 = fir.load %4#0 : !fir.ref<i32>
-  %19 = fir.convert %18 : (i32) -> i64
-  %20 = fir.load %2#0 : !fir.ref<i32>
-  %21 = fir.convert %20 : (i32) -> i64
-  %22 = fir.convert %19 : (i64) -> index
-  %23 = fir.convert %21 : (i64) -> index
-  %c1 = arith.constant 1 : index
-  %c0_1 = arith.constant 0 : index
-  %24 = arith.subi %23, %22 : index
-  %25 = arith.addi %24, %c1 : index
-  %26 = arith.divsi %25, %c1 : index
-  %27 = arith.cmpi sgt, %26, %c0_1 : index
-  %28 = arith.select %27, %...
[truncated]

``````````

</details>


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


More information about the flang-commits mailing list