Author: Eugene Epshteyn Date: 2026-06-26T11:07:43-04:00 New Revision: 5c577a1af3a1bbb19464f2c6b5155ff82d225117
URL: https://github.com/llvm/llvm-project/commit/5c577a1af3a1bbb19464f2c6b5155ff82d225117 DIFF: https://github.com/llvm/llvm-project/commit/5c577a1af3a1bbb19464f2c6b5155ff82d225117.diff LOG: Revert "[Flang]Add support for inlining hlfir.assign operation where both LHS…" This reverts commit 8eae99152a23bd70c6f8bbf8f59a4518902eb73f. Added: Modified: flang/include/flang/Optimizer/Analysis/ArraySectionAnalyzer.h flang/include/flang/Optimizer/Builder/FIRBuilder.h flang/lib/Optimizer/Builder/FIRBuilder.cpp flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp Removed: flang/test/HLFIR/inline-hlfir-assign-pointer-overlap.fir flang/test/HLFIR/inline-hlfir-assign-scalar-index.fir flang/test/HLFIR/inline-hlfir-assign-self-copy-runtime-stride.fir flang/test/HLFIR/inline-hlfir-assign-self-copy.fir ################################################################################ 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, %26, %c0_1 : index - %29 = fir.shape %28 : (index) -> !fir.shape<1> - %30 = hlfir.designate %17 (%22:%23:%c1) shape %29 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>> - %31 = fir.rebox %30 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> - fir.store %31 to %11#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> - %32 = fir.load %1#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> - %33 = fir.load %5#0 : !fir.ref<i32> - %34 = fir.convert %33 : (i32) -> i64 - %35 = fir.load %3#0 : !fir.ref<i32> - %36 = fir.convert %35 : (i32) -> i64 - %37 = fir.convert %34 : (i64) -> index - %38 = fir.convert %36 : (i64) -> index - %c1_2 = arith.constant 1 : index - %c0_3 = arith.constant 0 : index - %39 = arith.subi %38, %37 : index - %40 = arith.addi %39, %c1_2 : index - %41 = arith.divsi %40, %c1_2 : index - %42 = arith.cmpi sgt, %41, %c0_3 : index - %43 = arith.select %42, %41, %c0_3 : index - %44 = fir.shape %43 : (index) -> !fir.shape<1> - %45 = hlfir.designate %32 (%37:%38:%c1_2) shape %44 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>> - %46 = fir.rebox %45 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> - fir.store %46 to %16#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> - %47 = fir.load %16#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> - %48 = fir.load %11#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> - hlfir.assign %47 to %48 : !fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.box<!fir.ptr<!fir.array<?xi32>>> - return -} diff --git a/flang/test/HLFIR/inline-hlfir-assign-scalar-index.fir b/flang/test/HLFIR/inline-hlfir-assign-scalar-index.fir deleted file mode 100644 index f15cf75c761bf..0000000000000 --- a/flang/test/HLFIR/inline-hlfir-assign-scalar-index.fir +++ /dev/null @@ -1,98 +0,0 @@ -// Test inlining of hlfir.assign for self-copy with scalar index and triplet dimensions. -// RUN: fir-opt --inline-hlfir-assign %s | FileCheck %s - -// Fortran source code: -// subroutine copy_row(a, n, i, j, lo1, hi1, lo2, hi2) -// integer, intent(in) :: n, i, j, lo1, hi1, lo2, hi2 -// real, intent(inout) :: a(n, n) -// a(i, lo1:hi1) = a(j, lo2:hi2) -// end subroutine copy_row - -// CHECK-LABEL: func.func @_QPcopy_row - -// Index-based disjointness check for scalar index (dim1) and triplet (dim2): -// Dim1 (scalar): compares i vs j : disjoint if i != j (i.e., i < j || j < i) -// CHECK: %[[CMP1:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[CMP2:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[DISJ_DIM1:.*]] = arith.ori %[[CMP1]], %[[CMP2]] : i1 - -// Dim2 (triplet): compares lo1:hi1 vs lo2:hi2 — disjoint if hi1 < lo2 || hi2 < lo1 -// CHECK: %[[CMP3:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[CMP4:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[DISJ_DIM2:.*]] = arith.ori %[[CMP3]], %[[CMP4]] : i1 -// Overall: disjoint if ANY dimension is disjoint -// CHECK: %[[DISJOINT:.*]] = arith.ori %[[DISJ_DIM1]], %[[DISJ_DIM2]] : 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 %{{.*}} : f32, !fir.ref<f32> -// 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 %{{.*}} : f32, !fir.ref<f32> -// CHECK: } -// CHECK: hlfir.destroy %[[EXPR]] -// CHECK: } - -func.func @_QPcopy_row(%arg0: !fir.ref<!fir.array<?x?xf32>> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}, %arg2: !fir.ref<i32> {fir.bindc_name = "i"}, %arg3: !fir.ref<i32> {fir.bindc_name = "j"}, %arg4: !fir.ref<i32> {fir.bindc_name = "lo1"}, %arg5: !fir.ref<i32> {fir.bindc_name = "hi1"}, %arg6: !fir.ref<i32> {fir.bindc_name = "lo2"}, %arg7: !fir.ref<i32> {fir.bindc_name = "hi2"}) { - %c1 = arith.constant 1 : index - %c0 = arith.constant 0 : index - %0 = fir.dummy_scope : !fir.dscope - %1:2 = hlfir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowEn"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %2:2 = hlfir.declare %arg2 dummy_scope %0 arg 3 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowEi"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %3:2 = hlfir.declare %arg3 dummy_scope %0 arg 4 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowEj"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %4:2 = hlfir.declare %arg4 dummy_scope %0 arg 5 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowElo1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %5:2 = hlfir.declare %arg5 dummy_scope %0 arg 6 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowEhi1"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %6:2 = hlfir.declare %arg6 dummy_scope %0 arg 7 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowElo2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %7:2 = hlfir.declare %arg7 dummy_scope %0 arg 8 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFcopy_rowEhi2"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - - %8 = fir.load %1#0 : !fir.ref<i32> - %9 = fir.convert %8 : (i32) -> i64 - %10 = fir.convert %9 : (i64) -> index - %11 = arith.cmpi sgt, %10, %c0 : index - %12 = arith.select %11, %10, %c0 : index - %13 = fir.shape %12, %12 : (index, index) -> !fir.shape<2> - %14:2 = hlfir.declare %arg0(%13) dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QFcopy_rowEa"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>) - - // RHS: a(j, lo2:hi2) - %15 = fir.load %3#0 : !fir.ref<i32> - %16 = fir.convert %15 : (i32) -> i64 - %17 = fir.convert %16 : (i64) -> index - %18 = fir.load %6#0 : !fir.ref<i32> - %19 = fir.convert %18 : (i32) -> i64 - %20 = fir.convert %19 : (i64) -> index - %21 = fir.load %7#0 : !fir.ref<i32> - %22 = fir.convert %21 : (i32) -> i64 - %23 = fir.convert %22 : (i64) -> index - %24 = arith.subi %23, %20 : index - %25 = arith.addi %24, %c1 : index - %26 = arith.cmpi sgt, %25, %c0 : index - %27 = arith.select %26, %25, %c0 : index - %28 = fir.shape %27 : (index) -> !fir.shape<1> - %29 = hlfir.designate %14#0 (%17, %20:%23:%c1) shape %28 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>> - - // LHS: a(i, lo1:hi1) - %30 = fir.load %2#0 : !fir.ref<i32> - %31 = fir.convert %30 : (i32) -> i64 - %32 = fir.convert %31 : (i64) -> index - %33 = fir.load %4#0 : !fir.ref<i32> - %34 = fir.convert %33 : (i32) -> i64 - %35 = fir.convert %34 : (i64) -> index - %36 = fir.load %5#0 : !fir.ref<i32> - %37 = fir.convert %36 : (i32) -> i64 - %38 = fir.convert %37 : (i64) -> index - %39 = arith.subi %38, %35 : index - %40 = arith.addi %39, %c1 : index - %41 = arith.cmpi sgt, %40, %c0 : index - %42 = arith.select %41, %40, %c0 : index - %43 = fir.shape %42 : (index) -> !fir.shape<1> - %44 = hlfir.designate %14#0 (%32, %35:%38:%c1) shape %43 : (!fir.box<!fir.array<?x?xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>> - - hlfir.assign %29 to %44 : !fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>> - return -} diff --git a/flang/test/HLFIR/inline-hlfir-assign-self-copy-runtime-stride.fir b/flang/test/HLFIR/inline-hlfir-assign-self-copy-runtime-stride.fir deleted file mode 100644 index ee53844b010a8..0000000000000 --- a/flang/test/HLFIR/inline-hlfir-assign-self-copy-runtime-stride.fir +++ /dev/null @@ -1,141 +0,0 @@ -// Test inlining of hlfir.assign for array sections with the same runtime stride on LHS and RHS -// RUN: fir-opt --inline-hlfir-assign %s | FileCheck %s - -// Fortran source: -// subroutine testcase(a, n, step) -// implicit none -// integer, intent(in) :: n, step -// real, intent(inout) :: a(n) -// integer :: lo1, hi1, lo2, hi2 -// lo1 = 1 -// hi1 = max(n / 2, 1) -// lo2 = 2 -// hi2 = n -// a(lo1:hi1:step) = a(lo2:hi2:step) -// end subroutine testcase -// - -// CHECK-LABEL: func.func @_QPtestcase -// CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.array<?xf32>> - -// CHECK: %{{.*}} = hlfir.designate -// CHECK: %{{.*}} = hlfir.designate -// CHECK: %[[LHS_ADDR:.*]] = fir.box_addr %{{.*}} -// CHECK: %[[LHS_BASE:.*]] = fir.convert %[[LHS_ADDR]] : (!fir.ref<!fir.array<?xf32>>) -> i64 -// CHECK: %[[LHS_ELESZ:.*]] = fir.box_elesize %{{.*}} -// CHECK: %[[LHS_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %{{.*}} -// CHECK: %{{.*}} = arith.subi %[[LHS_DIMS]]#1, %{{.*}} : index -// CHECK: %{{.*}} = arith.muli %{{.*}}, %[[LHS_DIMS]]#2 : index -// CHECK: %{{.*}} = arith.cmpi slt, %[[LHS_DIMS]]#2, %{{.*}} : index -// CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index -// CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index -// CHECK: %{{.*}} = arith.subi %[[LHS_ELESZ]], %{{.*}} : 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 %{{.*}} -// CHECK: %[[RHS_BASE:.*]] = fir.convert %[[RHS_ADDR]] : (!fir.ref<!fir.array<?xf32>>) -> i64 -// CHECK: %[[RHS_ELESZ:.*]] = fir.box_elesize %{{.*}} -// CHECK: %[[RHS_DIMS:.*]]:3 = fir.box_dims %{{.*}}, %{{.*}} -// CHECK: %{{.*}} = arith.subi %[[RHS_DIMS]]#1, %{{.*}} : index -// CHECK: %{{.*}} = arith.muli %{{.*}}, %[[RHS_DIMS]]#2 : index -// CHECK: %{{.*}} = arith.cmpi slt, %[[RHS_DIMS]]#2, %{{.*}} : index -// CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index -// CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : index -// CHECK: %{{.*}} = arith.subi %[[RHS_ELESZ]], %{{.*}} : 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 %{{.*}} -// 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 %{{.*}} -// CHECK: } -// CHECK: hlfir.destroy %[[EXPR]] -// CHECK: } - -func.func @_QPtestcase(%arg0: !fir.ref<!fir.array<?xf32>> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}, %arg2: !fir.ref<i32> {fir.bindc_name = "step"}) { - %0 = fir.dummy_scope : !fir.dscope - %1:2 = hlfir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtestcaseEn"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %2 = fir.alloca i32 {bindc_name = "hi1", uniq_name = "_QFtestcaseEhi1"} - %3:2 = hlfir.declare %2 {uniq_name = "_QFtestcaseEhi1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %4 = fir.alloca i32 {bindc_name = "hi2", uniq_name = "_QFtestcaseEhi2"} - %5:2 = hlfir.declare %4 {uniq_name = "_QFtestcaseEhi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %6 = fir.alloca i32 {bindc_name = "lo1", uniq_name = "_QFtestcaseElo1"} - %7:2 = hlfir.declare %6 {uniq_name = "_QFtestcaseElo1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %8 = fir.alloca i32 {bindc_name = "lo2", uniq_name = "_QFtestcaseElo2"} - %9:2 = hlfir.declare %8 {uniq_name = "_QFtestcaseElo2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %10:2 = hlfir.declare %arg2 dummy_scope %0 arg 3 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtestcaseEstep"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %11 = fir.load %1#0 : !fir.ref<i32> - %12 = fir.convert %11 : (i32) -> i64 - %13 = fir.convert %12 : (i64) -> index - %c0 = arith.constant 0 : index - %14 = arith.cmpi sgt, %13, %c0 : index - %15 = arith.select %14, %13, %c0 : index - %16 = fir.shape %15 : (index) -> !fir.shape<1> - %17:2 = hlfir.declare %arg0(%16) dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QFtestcaseEa"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>) - %c1_i32 = arith.constant 1 : i32 - hlfir.assign %c1_i32 to %7#0 : i32, !fir.ref<i32> - %18 = fir.load %1#0 : !fir.ref<i32> - %c2_i32 = arith.constant 2 : i32 - %19 = arith.divsi %18, %c2_i32 : i32 - %c1_i32_0 = arith.constant 1 : i32 - %20 = arith.maxsi %19, %c1_i32_0 : i32 - hlfir.assign %20 to %3#0 : i32, !fir.ref<i32> - %c2_i32_1 = arith.constant 2 : i32 - hlfir.assign %c2_i32_1 to %9#0 : i32, !fir.ref<i32> - %21 = fir.load %1#0 : !fir.ref<i32> - hlfir.assign %21 to %5#0 : i32, !fir.ref<i32> - %22 = fir.load %9#0 : !fir.ref<i32> - %23 = fir.convert %22 : (i32) -> i64 - %24 = fir.load %5#0 : !fir.ref<i32> - %25 = fir.convert %24 : (i32) -> i64 - %26 = fir.convert %23 : (i64) -> index - %27 = fir.convert %25 : (i64) -> index - %28 = fir.load %10#0 : !fir.ref<i32> - %29 = fir.convert %28 : (i32) -> i64 - %30 = fir.convert %29 : (i64) -> index - %c0_2 = arith.constant 0 : index - %31 = arith.subi %27, %26 : index - %32 = arith.addi %31, %30 : index - %33 = arith.divsi %32, %30 : index - %34 = arith.cmpi sgt, %33, %c0_2 : index - %35 = arith.select %34, %33, %c0_2 : index - %36 = fir.shape %35 : (index) -> !fir.shape<1> - %37 = hlfir.designate %17#0 (%26:%27:%30) shape %36 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>> - %38 = fir.load %7#0 : !fir.ref<i32> - %39 = fir.convert %38 : (i32) -> i64 - %40 = fir.load %3#0 : !fir.ref<i32> - %41 = fir.convert %40 : (i32) -> i64 - %42 = fir.convert %39 : (i64) -> index - %43 = fir.convert %41 : (i64) -> index - %44 = fir.load %10#0 : !fir.ref<i32> - %45 = fir.convert %44 : (i32) -> i64 - %46 = fir.convert %45 : (i64) -> index - %c0_3 = arith.constant 0 : index - %47 = arith.subi %43, %42 : index - %48 = arith.addi %47, %46 : index - %49 = arith.divsi %48, %46 : index - %50 = arith.cmpi sgt, %49, %c0_3 : index - %51 = arith.select %50, %49, %c0_3 : index - %52 = fir.shape %51 : (index) -> !fir.shape<1> - %53 = hlfir.designate %17#0 (%42:%43:%46) shape %52 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>> - hlfir.assign %37 to %53 : !fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>> - return -} diff --git a/flang/test/HLFIR/inline-hlfir-assign-self-copy.fir b/flang/test/HLFIR/inline-hlfir-assign-self-copy.fir deleted file mode 100644 index ba1d278080a02..0000000000000 --- a/flang/test/HLFIR/inline-hlfir-assign-self-copy.fir +++ /dev/null @@ -1,178 +0,0 @@ -// Test inlining of hlfir.assign for self-copy array section - -// RUN: fir-opt --inline-hlfir-assign %s | FileCheck %s - -// Fortran source code: -// subroutine self_copy_ew(field, xm, ym, levs, xh, yh) -// integer, intent(in) :: xm, ym, levs, xh, yh -// real, intent(inout) :: field(xm + 2 * xh, ym + 2 * yh, levs) -// integer :: x1, x2, x5, x6 -// x1 = 1 -// x2 = xh -// x5 = xm + 1 -// x6 = xm + xh -// field(x1:x2, :, :) = field(x5:x6, :, :) -// end subroutine self_copy_ew - -// CHECK-LABEL: func.func @_QPself_copy_ew -// CHECK-SAME: %[[ARGF:.*]]: !fir.ref<!fir.array<?x?x?xf32>> {fir.bindc_name = "field"} - -// CHECK: hlfir.declare %[[ARGF]](%{{.*}}) {{.*}} uniq_name = "_QFself_copy_ewEfield" - -// Index-based runtime disjointness check: -// CHECK: %[[RHS:.*]] = hlfir.designate %{{.*}}#0 (%{{.*}}:%{{.*}}:%{{.*}}, %{{.*}}:%{{.*}}:%{{.*}}, %{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} -// CHECK: %[[LHS:.*]] = hlfir.designate %{{.*}}#0 (%{{.*}}:%{{.*}}:%{{.*}}, %{{.*}}:%{{.*}}:%{{.*}}, %{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} -// CHECK: %[[CMP1:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[CMP2:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[DIM1_DISJ:.*]] = arith.ori %[[CMP1]], %[[CMP2]] : i1 -// CHECK: %[[CMP3:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[CMP4:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[DIM2_DISJ:.*]] = arith.ori %[[CMP3]], %[[CMP4]] : i1 -// CHECK: %[[DISJ12:.*]] = arith.ori %[[DIM1_DISJ]], %[[DIM2_DISJ]] : i1 -// CHECK: %[[CMP5:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[CMP6:.*]] = arith.cmpi slt, %{{.*}}, %{{.*}} : index -// CHECK: %[[DIM3_DISJ:.*]] = arith.ori %[[CMP5]], %[[CMP6]] : i1 -// CHECK: %[[DISJOINT:.*]] = arith.ori %[[DISJ12]], %[[DIM3_DISJ]] : i1 -// CHECK: fir.if %[[DISJOINT]] { -// CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered { -// CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered { -// CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered { -// CHECK: %{{.*}} = hlfir.designate %[[RHS]] (%{{.*}}, %{{.*}}, %{{.*}}) -// CHECK: %{{.*}} = fir.load %{{.*}} -// CHECK: %{{.*}} = hlfir.designate %[[LHS]] (%{{.*}}, %{{.*}}, %{{.*}}) -// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32> -// CHECK: } -// CHECK: } -// CHECK: } -// CHECK: } else { -// CHECK: %[[EXPR:.*]] = hlfir.as_expr %[[RHS]] -// CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered { -// CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered { -// CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered { -// CHECK: %{{.*}} = hlfir.apply %[[EXPR]], %{{.*}}, %{{.*}}, %{{.*}} -// CHECK: %{{.*}} = hlfir.designate %[[LHS]] (%{{.*}}, %{{.*}}, %{{.*}}) -// CHECK: hlfir.assign %{{.*}} to %{{.*}} : f32, !fir.ref<f32> -// CHECK: } -// CHECK: } -// CHECK: } -// CHECK: hlfir.destroy %[[EXPR]] -// CHECK: } - -func.func @_QPself_copy_ew(%arg0: !fir.ref<!fir.array<?x?x?xf32>> {fir.bindc_name = "field"}, %arg1: !fir.ref<i32> {fir.bindc_name = "xm"}, %arg2: !fir.ref<i32> {fir.bindc_name = "ym"}, %arg3: !fir.ref<i32> {fir.bindc_name = "levs"}, %arg4: !fir.ref<i32> {fir.bindc_name = "xh"}, %arg5: !fir.ref<i32> {fir.bindc_name = "yh"}) { - %0 = fir.dummy_scope : !fir.dscope - %1:2 = hlfir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFself_copy_ewExm"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %2:2 = hlfir.declare %arg4 dummy_scope %0 arg 5 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFself_copy_ewExh"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %3:2 = hlfir.declare %arg2 dummy_scope %0 arg 3 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFself_copy_ewEym"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %4:2 = hlfir.declare %arg5 dummy_scope %0 arg 6 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFself_copy_ewEyh"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %5:2 = hlfir.declare %arg3 dummy_scope %0 arg 4 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFself_copy_ewElevs"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>) - %6 = fir.alloca i32 {bindc_name = "x1", uniq_name = "_QFself_copy_ewEx1"} - %7:2 = hlfir.declare %6 {uniq_name = "_QFself_copy_ewEx1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %8 = fir.alloca i32 {bindc_name = "x2", uniq_name = "_QFself_copy_ewEx2"} - %9:2 = hlfir.declare %8 {uniq_name = "_QFself_copy_ewEx2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %10 = fir.alloca i32 {bindc_name = "x5", uniq_name = "_QFself_copy_ewEx5"} - %11:2 = hlfir.declare %10 {uniq_name = "_QFself_copy_ewEx5"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %12 = fir.alloca i32 {bindc_name = "x6", uniq_name = "_QFself_copy_ewEx6"} - %13:2 = hlfir.declare %12 {uniq_name = "_QFself_copy_ewEx6"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) - %14 = fir.load %1#0 : !fir.ref<i32> - %c2_i32 = arith.constant 2 : i32 - %15 = fir.load %2#0 : !fir.ref<i32> - %16 = arith.muli %c2_i32, %15 : i32 - %17 = arith.addi %14, %16 : i32 - %18 = fir.convert %17 : (i32) -> i64 - %19 = fir.convert %18 : (i64) -> index - %c0 = arith.constant 0 : index - %20 = arith.cmpi sgt, %19, %c0 : index - %21 = arith.select %20, %19, %c0 : index - %22 = fir.load %3#0 : !fir.ref<i32> - %c2_i32_0 = arith.constant 2 : i32 - %23 = fir.load %4#0 : !fir.ref<i32> - %24 = arith.muli %c2_i32_0, %23 : i32 - %25 = arith.addi %22, %24 : i32 - %26 = fir.convert %25 : (i32) -> i64 - %27 = fir.convert %26 : (i64) -> index - %c0_1 = arith.constant 0 : index - %28 = arith.cmpi sgt, %27, %c0_1 : index - %29 = arith.select %28, %27, %c0_1 : index - %30 = fir.load %5#0 : !fir.ref<i32> - %31 = fir.convert %30 : (i32) -> i64 - %32 = fir.convert %31 : (i64) -> index - %c0_2 = arith.constant 0 : index - %33 = arith.cmpi sgt, %32, %c0_2 : index - %34 = arith.select %33, %32, %c0_2 : index - %35 = fir.shape %21, %29, %34 : (index, index, index) -> !fir.shape<3> - %36:2 = hlfir.declare %arg0(%35) dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QFself_copy_ewEfield"} : (!fir.ref<!fir.array<?x?x?xf32>>, !fir.shape<3>, !fir.dscope) -> (!fir.box<!fir.array<?x?x?xf32>>, !fir.ref<!fir.array<?x?x?xf32>>) - %c1_i32 = arith.constant 1 : i32 - hlfir.assign %c1_i32 to %7#0 : i32, !fir.ref<i32> - %37 = fir.load %2#0 : !fir.ref<i32> - hlfir.assign %37 to %9#0 : i32, !fir.ref<i32> - %38 = fir.load %1#0 : !fir.ref<i32> - %c1_i32_3 = arith.constant 1 : i32 - %39 = arith.addi %38, %c1_i32_3 : i32 - hlfir.assign %39 to %11#0 : i32, !fir.ref<i32> - %40 = fir.load %1#0 : !fir.ref<i32> - %41 = fir.load %2#0 : !fir.ref<i32> - %42 = arith.addi %40, %41 : i32 - hlfir.assign %42 to %13#0 : i32, !fir.ref<i32> - %43 = fir.load %11#0 : !fir.ref<i32> - %44 = fir.convert %43 : (i32) -> i64 - %45 = fir.load %13#0 : !fir.ref<i32> - %46 = fir.convert %45 : (i32) -> i64 - %47 = fir.convert %44 : (i64) -> index - %48 = fir.convert %46 : (i64) -> index - %c1 = arith.constant 1 : index - %c0_4 = arith.constant 0 : index - %49 = arith.subi %48, %47 : index - %50 = arith.addi %49, %c1 : index - %51 = arith.divsi %50, %c1 : index - %52 = arith.cmpi sgt, %51, %c0_4 : index - %53 = arith.select %52, %51, %c0_4 : index - %c1_5 = arith.constant 1 : index - %c1_6 = arith.constant 1 : index - %c0_7 = arith.constant 0 : index - %54 = arith.subi %29, %c1_5 : index - %55 = arith.addi %54, %c1_6 : index - %56 = arith.divsi %55, %c1_6 : index - %57 = arith.cmpi sgt, %56, %c0_7 : index - %58 = arith.select %57, %56, %c0_7 : index - %c1_8 = arith.constant 1 : index - %c0_9 = arith.constant 0 : index - %59 = arith.subi %34, %c1_5 : index - %60 = arith.addi %59, %c1_8 : index - %61 = arith.divsi %60, %c1_8 : index - %62 = arith.cmpi sgt, %61, %c0_9 : index - %63 = arith.select %62, %61, %c0_9 : index - %64 = fir.shape %53, %58, %63 : (index, index, index) -> !fir.shape<3> - %65 = hlfir.designate %36#0 (%47:%48:%c1, %c1_5:%29:%c1_6, %c1_5:%34:%c1_8) shape %64 : (!fir.box<!fir.array<?x?x?xf32>>, index, index, index, index, index, index, index, index, index, !fir.shape<3>) -> !fir.box<!fir.array<?x?x?xf32>> - %66 = fir.load %7#0 : !fir.ref<i32> - %67 = fir.convert %66 : (i32) -> i64 - %68 = fir.load %9#0 : !fir.ref<i32> - %69 = fir.convert %68 : (i32) -> i64 - %70 = fir.convert %67 : (i64) -> index - %71 = fir.convert %69 : (i64) -> index - %c1_10 = arith.constant 1 : index - %c0_11 = arith.constant 0 : index - %72 = arith.subi %71, %70 : index - %73 = arith.addi %72, %c1_10 : index - %74 = arith.divsi %73, %c1_10 : index - %75 = arith.cmpi sgt, %74, %c0_11 : index - %76 = arith.select %75, %74, %c0_11 : index - %c1_12 = arith.constant 1 : index - %c1_13 = arith.constant 1 : index - %c0_14 = arith.constant 0 : index - %77 = arith.subi %29, %c1_12 : index - %78 = arith.addi %77, %c1_13 : index - %79 = arith.divsi %78, %c1_13 : index - %80 = arith.cmpi sgt, %79, %c0_14 : index - %81 = arith.select %80, %79, %c0_14 : index - %c1_15 = arith.constant 1 : index - %c0_16 = arith.constant 0 : index - %82 = arith.subi %34, %c1_12 : index - %83 = arith.addi %82, %c1_15 : index - %84 = arith.divsi %83, %c1_15 : index - %85 = arith.cmpi sgt, %84, %c0_16 : index - %86 = arith.select %85, %84, %c0_16 : index - %87 = fir.shape %76, %81, %86 : (index, index, index) -> !fir.shape<3> - %88 = hlfir.designate %36#0 (%70:%71:%c1_10, %c1_12:%29:%c1_13, %c1_12:%34:%c1_15) shape %87 : (!fir.box<!fir.array<?x?x?xf32>>, index, index, index, index, index, index, index, index, index, !fir.shape<3>) -> !fir.box<!fir.array<?x?x?xf32>> - hlfir.assign %65 to %88 : !fir.box<!fir.array<?x?x?xf32>>, !fir.box<!fir.array<?x?x?xf32>> - return -} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
