[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