[flang-commits] [flang] [flang][FIR] add fir.assumed_size_extent to abstract assumed-size extent encoding (PR #164452)
via flang-commits
flang-commits at lists.llvm.org
Wed Oct 22 01:07:49 PDT 2025
https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/164452
>From 0adf900cf82d7d751a2d548d7f3797d319ce9594 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Tue, 21 Oct 2025 02:56:24 -0700
Subject: [PATCH 1/3] [flang][FIR] add fir.assumed_size_extent to abstract
assumed-size extent encoding
---
.../include/flang/Optimizer/Dialect/FIROps.td | 35 +++++++++++++++++
flang/lib/Lower/Bridge.cpp | 4 +-
flang/lib/Lower/ConvertVariable.cpp | 2 +-
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 39 +++++++++++++++++++
flang/lib/Optimizer/Dialect/FIROps.cpp | 28 +++++++++++++
.../Optimizer/Transforms/ArrayValueCopy.cpp | 4 +-
flang/test/Fir/assumed-size-ops-codegen.fir | 19 +++++++++
flang/test/Fir/assumed-size-ops-folding.fir | 13 +++++++
flang/test/Fir/assumed-size-ops-roundtrip.fir | 13 +++++++
flang/test/HLFIR/assumed-type-actual-args.f90 | 2 +-
flang/test/Lower/HLFIR/assumed-rank-iface.f90 | 2 +-
flang/test/Lower/HLFIR/select-rank.f90 | 8 ++--
flang/test/Lower/Intrinsics/lbound.f90 | 2 +-
flang/test/Lower/Intrinsics/ubound.f90 | 2 +-
.../Lower/array-expression-assumed-size.f90 | 8 ++--
flang/test/Lower/entry-statement.f90 | 2 +-
16 files changed, 165 insertions(+), 18 deletions(-)
create mode 100644 flang/test/Fir/assumed-size-ops-codegen.fir
create mode 100644 flang/test/Fir/assumed-size-ops-folding.fir
create mode 100644 flang/test/Fir/assumed-size-ops-roundtrip.fir
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index fc6eedc6ed4c6..86502c6271d23 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -1249,6 +1249,41 @@ def fir_IsAssumedSizeOp : fir_SimpleOp<"is_assumed_size", [NoMemoryEffect]> {
let results = (outs BoolLike);
}
+def fir_AssumedSizeExtentOp : fir_SimpleOneResultOp<"assumed_size_extent", [NoMemoryEffect]> {
+ let summary = "get the assumed-size last extent sentinel";
+
+ let description = [{
+ Returns the special extent value representing the last dimension of an
+ assumed-size array. This is used to model the semantics in FIR without
+ directly materializing the sentinel value. The concrete encoding is
+ introduced during FIR to LLVM lowering.
+
+ ```
+ %e = fir.assumed_size_extent : index
+ ```
+ }];
+
+ let results = (outs Index);
+ let assemblyFormat = "attr-dict `:` type(results)";
+}
+
+def fir_IsAssumedSizeExtentOp : fir_SimpleOp<"is_assumed_size_extent", [NoMemoryEffect]> {
+ let summary = "is value the assumed-size last extent sentinel";
+
+ let description = [{
+ Returns true iff the given integer equals the assumed-size extent sentinel.
+
+ ```
+ %t = fir.is_assumed_size_extent %v : (index) -> i1
+ %c = fir.is_assumed_size_extent %x : (i32) -> i1
+ ```
+ }];
+
+ let arguments = (ins AnyIntegerLike:$val);
+ let results = (outs BoolLike);
+ let hasCanonicalizer = 1;
+}
+
def fir_BoxIsPtrOp : fir_SimpleOp<"box_isptr", [NoMemoryEffect]> {
let summary = "is the boxed value a POINTER?";
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 3b711ccbe786a..579e0b673955c 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -4010,8 +4010,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// parameters and dynamic type. The selector cannot be a
// POINTER/ALLOCATBLE as per F'2023 C1160.
fir::ExtendedValue newExv;
- llvm::SmallVector assumeSizeExtents{
- builder->createMinusOneInteger(loc, builder->getIndexType())};
+ llvm::SmallVector<mlir::Value> assumeSizeExtents{
+ builder->create<fir::AssumedSizeExtentOp>(loc)};
mlir::Value baseAddr =
hlfir::genVariableRawAddress(loc, *builder, selector);
const bool isVolatile = fir::isa_volatile_type(selector.getType());
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 00ec1b51e5400..dcee64f6a614d 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1711,7 +1711,7 @@ static void lowerExplicitLowerBounds(
/// CFI_desc_t requirements in 18.5.3 point 5.).
static mlir::Value getAssumedSizeExtent(mlir::Location loc,
fir::FirOpBuilder &builder) {
- return builder.createMinusOneInteger(loc, builder.getIndexType());
+ return builder.create<fir::AssumedSizeExtentOp>(loc);
}
/// Lower explicit extents into \p result if this is an explicit-shape or
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 70bb43a2510ba..e71f4e3cee49c 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -749,6 +749,44 @@ struct VolatileCastOpConversion
}
};
+/// Lower `fir.assumed_size_extent` to constant -1 of index type.
+struct AssumedSizeExtentOpConversion
+ : public fir::FIROpConversion<fir::AssumedSizeExtentOp> {
+ using FIROpConversion::FIROpConversion;
+
+ llvm::LogicalResult
+ matchAndRewrite(fir::AssumedSizeExtentOp op, OpAdaptor,
+ mlir::ConversionPatternRewriter &rewriter) const override {
+ mlir::Location loc = op.getLoc();
+ mlir::Type ity = lowerTy().indexType();
+ auto cst = fir::genConstantIndex(loc, ity, rewriter, -1);
+ rewriter.replaceOp(op, cst.getResult());
+ return mlir::success();
+ }
+};
+
+/// Lower `fir.is_assumed_size_extent` to integer equality with -1.
+struct IsAssumedSizeExtentOpConversion
+ : public fir::FIROpConversion<fir::IsAssumedSizeExtentOp> {
+ using FIROpConversion::FIROpConversion;
+
+ llvm::LogicalResult
+ matchAndRewrite(fir::IsAssumedSizeExtentOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const override {
+ mlir::Location loc = op.getLoc();
+ mlir::Value val = adaptor.getVal();
+ mlir::Type valTy = val.getType();
+ // Create constant -1 of the operand type.
+ auto negOneAttr = rewriter.getIntegerAttr(valTy, -1);
+ auto negOne =
+ mlir::LLVM::ConstantOp::create(rewriter, loc, valTy, negOneAttr);
+ auto cmp = mlir::LLVM::ICmpOp::create(
+ rewriter, loc, mlir::LLVM::ICmpPredicate::eq, val, negOne);
+ rewriter.replaceOp(op, cmp.getResult());
+ return mlir::success();
+ }
+};
+
/// convert value of from-type to value of to-type
struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
using FIROpConversion::FIROpConversion;
@@ -4360,6 +4398,7 @@ void fir::populateFIRToLLVMConversionPatterns(
AllocaOpConversion, AllocMemOpConversion, BoxAddrOpConversion,
BoxCharLenOpConversion, BoxDimsOpConversion, BoxEleSizeOpConversion,
BoxIsAllocOpConversion, BoxIsArrayOpConversion, BoxIsPtrOpConversion,
+ AssumedSizeExtentOpConversion, IsAssumedSizeExtentOpConversion,
BoxOffsetOpConversion, BoxProcHostOpConversion, BoxRankOpConversion,
BoxTypeCodeOpConversion, BoxTypeDescOpConversion, CallOpConversion,
CmpcOpConversion, VolatileCastOpConversion, ConvertOpConversion,
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 1712af1d1eba7..d0164f32d9b6a 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -5142,6 +5142,34 @@ void fir::BoxTotalElementsOp::getCanonicalizationPatterns(
patterns.add<SimplifyBoxTotalElementsOp>(context);
}
+//===----------------------------------------------------------------------===//
+// IsAssumedSizeExtentOp and AssumedSizeExtentOp
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct FoldIsAssumedSizeExtentOnCtor
+ : public mlir::OpRewritePattern<fir::IsAssumedSizeExtentOp> {
+ using mlir::OpRewritePattern<fir::IsAssumedSizeExtentOp>::OpRewritePattern;
+ mlir::LogicalResult
+ matchAndRewrite(fir::IsAssumedSizeExtentOp op,
+ mlir::PatternRewriter &rewriter) const override {
+ if (llvm::isa_and_nonnull<fir::AssumedSizeExtentOp>(
+ op.getVal().getDefiningOp())) {
+ mlir::Type i1 = rewriter.getI1Type();
+ rewriter.replaceOpWithNewOp<mlir::arith::ConstantOp>(
+ op, i1, rewriter.getIntegerAttr(i1, 1));
+ return mlir::success();
+ }
+ return mlir::failure();
+ }
+};
+} // namespace
+
+void fir::IsAssumedSizeExtentOp::getCanonicalizationPatterns(
+ mlir::RewritePatternSet &patterns, mlir::MLIRContext *context) {
+ patterns.add<FoldIsAssumedSizeExtentOnCtor>(context);
+}
+
//===----------------------------------------------------------------------===//
// LocalitySpecifierOp
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp b/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp
index ed9a2ae11f0d9..5bf783db92bf3 100644
--- a/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp
+++ b/flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp
@@ -832,8 +832,8 @@ static mlir::Type getEleTy(mlir::Type ty) {
static bool isAssumedSize(llvm::SmallVectorImpl<mlir::Value> &extents) {
if (extents.empty())
return false;
- auto cstLen = fir::getIntIfConstant(extents.back());
- return cstLen.has_value() && *cstLen == -1;
+ return llvm::isa_and_nonnull<fir::AssumedSizeExtentOp>(
+ extents.back().getDefiningOp());
}
// Extract extents from the ShapeOp/ShapeShiftOp into the result vector.
diff --git a/flang/test/Fir/assumed-size-ops-codegen.fir b/flang/test/Fir/assumed-size-ops-codegen.fir
new file mode 100644
index 0000000000000..54e9b3c8f30f4
--- /dev/null
+++ b/flang/test/Fir/assumed-size-ops-codegen.fir
@@ -0,0 +1,19 @@
+// RUN: fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s
+
+// CHECK-LABEL: @assumed_size_extent(
+// CHECK: %[[CNEG1:.*]] = llvm.mlir.constant(-1 : i64)
+// CHECK: llvm.return %[[CNEG1]] : i64
+func.func @assumed_size_extent() -> index {
+ %e = fir.assumed_size_extent : index
+ return %e : index
+}
+
+// CHECK-LABEL: @is_assumed_size_extent(
+// CHECK: %[[NEG1:.*]] = llvm.mlir.constant(-1 : i64)
+// CHECK: %[[CMP:.*]] = llvm.icmp "eq"
+// CHECK: llvm.return %[[CMP]] : i1
+func.func @is_assumed_size_extent(%x: index) -> i1 {
+ %c = fir.is_assumed_size_extent %x : (index) -> i1
+ return %c : i1
+}
+
diff --git a/flang/test/Fir/assumed-size-ops-folding.fir b/flang/test/Fir/assumed-size-ops-folding.fir
new file mode 100644
index 0000000000000..9fd5fabb7290b
--- /dev/null
+++ b/flang/test/Fir/assumed-size-ops-folding.fir
@@ -0,0 +1,13 @@
+// RUN: fir-opt --canonicalize %s | FileCheck %s
+
+// Verify: fir.is_assumed_size_extent(fir.assumed_size_extent) folds to i1 true.
+
+// CHECK-LABEL: func.func @fold(
+func.func @fold() -> i1 {
+ %e = fir.assumed_size_extent : index
+ // CHECK: %[[C:.*]] = arith.constant true
+ %t = fir.is_assumed_size_extent %e : (index) -> i1
+ return %t : i1
+}
+
+
diff --git a/flang/test/Fir/assumed-size-ops-roundtrip.fir b/flang/test/Fir/assumed-size-ops-roundtrip.fir
new file mode 100644
index 0000000000000..c3c1883a2b7c0
--- /dev/null
+++ b/flang/test/Fir/assumed-size-ops-roundtrip.fir
@@ -0,0 +1,13 @@
+// RUN: fir-opt %s | fir-opt | FileCheck %s
+
+func.func @roundtrip() {
+ // CHECK: %[[E:.*]] = fir.assumed_size_extent : index
+ %e = fir.assumed_size_extent : index
+
+ // CHECK: %[[T:.*]] = fir.is_assumed_size_extent %[[E]] : (index) -> i1
+ %t = fir.is_assumed_size_extent %e : (index) -> i1
+
+ return
+}
+
+
diff --git a/flang/test/HLFIR/assumed-type-actual-args.f90 b/flang/test/HLFIR/assumed-type-actual-args.f90
index 42e9ed27340e7..aaac98ba3c79d 100644
--- a/flang/test/HLFIR/assumed-type-actual-args.f90
+++ b/flang/test/HLFIR/assumed-type-actual-args.f90
@@ -113,7 +113,7 @@ subroutine s5b(x)
! CHECK-LABEL: func.func @_QPtest2(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<?xnone>> {fir.bindc_name = "x"}) {
! CHECK: %[[DSCOPE:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[VAL_1:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_1:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_2]]) dummy_scope %[[DSCOPE]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.array<?xnone>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xnone>>, !fir.ref<!fir.array<?xnone>>)
! CHECK: fir.call @_QPs2(%[[VAL_3]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
diff --git a/flang/test/Lower/HLFIR/assumed-rank-iface.f90 b/flang/test/Lower/HLFIR/assumed-rank-iface.f90
index 9ecbb7c9e5b94..ffb36fa4b7003 100644
--- a/flang/test/Lower/HLFIR/assumed-rank-iface.f90
+++ b/flang/test/Lower/HLFIR/assumed-rank-iface.f90
@@ -145,7 +145,7 @@ subroutine int_r2_assumed_size_to_assumed_rank(x)
! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_4:.*]] = arith.cmpi sgt, %[[VAL_2]], %[[VAL_3]] : index
! CHECK: %[[VAL_5:.*]] = arith.select %[[VAL_4]], %[[VAL_2]], %[[VAL_3]] : index
-! CHECK: %[[VAL_6:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_6:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_5]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_7]]) dummy_scope %{{[0-9]+}} {uniq_name = "_QFint_r2_assumed_size_to_assumed_rankEx"} : (!fir.ref<!fir.array<10x?xi32>>, !fir.shape<2>, !fir.dscope) -> (!fir.box<!fir.array<10x?xi32>>, !fir.ref<!fir.array<10x?xi32>>)
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]]#0 : (!fir.box<!fir.array<10x?xi32>>) -> !fir.box<!fir.array<*:i32>>
diff --git a/flang/test/Lower/HLFIR/select-rank.f90 b/flang/test/Lower/HLFIR/select-rank.f90
index 0f80c723e468f..f1f968decd412 100644
--- a/flang/test/Lower/HLFIR/select-rank.f90
+++ b/flang/test/Lower/HLFIR/select-rank.f90
@@ -371,7 +371,7 @@ subroutine test_branching(x)
! CHECK: fir.call @_QPr1(%[[VAL_11]]#0) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb5:
-! CHECK: %[[VAL_12:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_12:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_2]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.ref<!fir.array<*:f32>>
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.array<*:f32>>) -> !fir.ref<!fir.array<?xf32>>
! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_12]] : (index) -> !fir.shape<1>
@@ -435,7 +435,7 @@ subroutine test_branching(x)
! CHECK: fir.call @_QPrdefault(%[[VAL_8]]#0) fastmath<contract> : (!fir.box<!fir.array<*:f32>>) -> ()
! CHECK: cf.br ^bb5
! CHECK: ^bb4:
-! CHECK: %[[VAL_9:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_9:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_2]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.ref<!fir.array<*:f32>>
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.ref<!fir.array<*:f32>>) -> !fir.ref<!fir.array<?xf32>>
! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_9]] : (index) -> !fir.shape<1>
@@ -482,7 +482,7 @@ subroutine test_branching(x)
! CHECK: fir.call @_QPr1_implicit(%[[VAL_21]]#1) fastmath<contract> : (!fir.ref<!fir.array<?xf32>>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb5:
-! CHECK: %[[VAL_22:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_22:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_2]]#1 : (!fir.box<!fir.array<*:f32>>) -> !fir.ref<!fir.array<*:f32>>
! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (!fir.ref<!fir.array<*:f32>>) -> !fir.ref<!fir.array<?xf32>>
! CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_22]] : (index) -> !fir.shape<1>
@@ -534,7 +534,7 @@ subroutine test_branching(x)
! CHECK: fir.call @_QPrc1_implicit(%[[VAL_26]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
! CHECK: cf.br ^bb6
! CHECK: ^bb5:
-! CHECK: %[[VAL_27:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_27:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_8]]#1 : (!fir.box<!fir.array<*:!fir.char<1,?>>>) -> !fir.ref<!fir.array<*:!fir.char<1,?>>>
! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.array<*:!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
! CHECK: %[[VAL_30:.*]] = fir.shape %[[VAL_27]] : (index) -> !fir.shape<1>
diff --git a/flang/test/Lower/Intrinsics/lbound.f90 b/flang/test/Lower/Intrinsics/lbound.f90
index a5ca2d39a5ee4..75c11ff8bc95f 100644
--- a/flang/test/Lower/Intrinsics/lbound.f90
+++ b/flang/test/Lower/Intrinsics/lbound.f90
@@ -40,7 +40,7 @@ subroutine lbound_test_2(a, dim, res)
subroutine lbound_test_3(a, dim, res)
real, dimension(2:10, 3:*) :: a
integer(8):: dim, res
-! CHECK: %[[VAL_0:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_0:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_1:.*]] = fir.load %arg1 : !fir.ref<i64>
! CHECK: %[[VAL_2:.*]] = fir.shape_shift %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_0]] : (index, index, index, index) -> !fir.shapeshift<2>
! CHECK: %[[VAL_3:.*]] = fir.embox %arg0(%[[VAL_2]]) : (!fir.ref<!fir.array<9x?xf32>>, !fir.shapeshift<2>) -> !fir.box<!fir.array<9x?xf32>>
diff --git a/flang/test/Lower/Intrinsics/ubound.f90 b/flang/test/Lower/Intrinsics/ubound.f90
index dae21acda170d..bc8cff8982542 100644
--- a/flang/test/Lower/Intrinsics/ubound.f90
+++ b/flang/test/Lower/Intrinsics/ubound.f90
@@ -48,7 +48,7 @@ subroutine ubound_test_2(a, dim, res)
subroutine ubound_test_3(a, dim, res)
real, dimension(10, 20, *) :: a
integer(8):: dim, res
-! CHECK: %[[VAL_0:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_0:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_1:.*]] = fir.shape %{{.*}}, %{{.*}}, %[[VAL_0]] : (index, index, index) -> !fir.shape<3>
! CHECK: %[[VAL_2:.*]] = fir.embox %{{.*}}(%[[VAL_1]]) : (!fir.ref<!fir.array<10x20x?xf32>>, !fir.shape<3>) -> !fir.box<!fir.array<10x20x?xf32>>
! CHECK: %[[VAL_3:.*]] = fir.load %{{.*}} : !fir.ref<i64>
diff --git a/flang/test/Lower/array-expression-assumed-size.f90 b/flang/test/Lower/array-expression-assumed-size.f90
index 2fbf315aff114..a498148d07fc7 100644
--- a/flang/test/Lower/array-expression-assumed-size.f90
+++ b/flang/test/Lower/array-expression-assumed-size.f90
@@ -19,7 +19,7 @@ end subroutine assumed_size_forall_test
! CHECK: %[[VAL_1A:.*]] = fir.convert %c10{{.*}} : (i64) -> index
! CHECK: %[[VAL_1B:.*]] = arith.cmpi sgt, %[[VAL_1A]], %c0{{.*}} : index
! CHECK: %[[VAL_1:.*]] = arith.select %[[VAL_1B]], %[[VAL_1A]], %c0{{.*}} : index
-! CHECK: %[[VAL_2:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_2:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i64
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> index
@@ -82,7 +82,7 @@ end subroutine assumed_size_forall_test
! CHECK: %[[VAL_2A:.*]] = fir.convert %c10{{.*}} : (i64) -> index
! CHECK: %[[VAL_2B:.*]] = arith.cmpi sgt, %[[VAL_2A]], %c0{{.*}} : index
! CHECK: %[[VAL_2:.*]] = arith.select %[[VAL_2B]], %[[VAL_2A]], %c0{{.*}} : index
-! CHECK: %[[VAL_3:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_3:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_4:.*]] = arith.constant 2 : i32
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index
! CHECK: %[[VAL_6:.*]] = arith.constant 6 : i32
@@ -149,7 +149,7 @@ end subroutine assumed_size_forall_test
! PostOpt-DAG: %[[VAL_4:.*]] = arith.constant 0 : index
! PostOpt-DAG: %[[VAL_5:.*]] = arith.constant 3 : index
! PostOpt-DAG: %[[VAL_6:.*]] = arith.constant 4 : index
-! PostOpt-DAG: %[[VAL_7:.*]] = arith.constant -1 : index
+! PostOpt-DAG: %[[VAL_7:.*]] = fir.assumed_size_extent : index
! PostOpt: %[[VAL_8:.*]] = fir.shape %[[VAL_1]], %[[VAL_7]] : (index, index) -> !fir.shape<2>
! PostOpt: %[[VAL_9:.*]] = fir.slice %[[VAL_2]], %[[VAL_1]], %[[VAL_2]], %[[VAL_2]], %[[VAL_3]], %[[VAL_2]] : (index, index, index, index, index, index) -> !fir.slice<2>
! PostOpt: %[[VAL_10:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[VAL_3]]
@@ -227,8 +227,8 @@ end subroutine assumed_size_forall_test
! PostOpt-DAG: %[[VAL_4:.*]] = arith.constant 1 : index
! PostOpt-DAG: %[[VAL_5:.*]] = arith.constant 0 : index
! PostOpt-DAG: %[[VAL_6:.*]] = arith.constant 5 : index
-! PostOpt-DAG: %[[VAL_8:.*]] = arith.constant -1 : index
! PostOpt: %[[VAL_7:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! PostOpt: %[[VAL_8:.*]] = fir.assumed_size_extent : index
! PostOpt: %[[VAL_9:.*]] = fir.shape %[[VAL_2]], %[[VAL_8]] : (index, index) -> !fir.shape<2>
! PostOpt: %[[VAL_10:.*]] = fir.allocmem !fir.array<10x?xi32>, %[[VAL_4]]
! PostOpt: br ^bb1(%[[VAL_5]], %[[VAL_4]] : index, index)
diff --git a/flang/test/Lower/entry-statement.f90 b/flang/test/Lower/entry-statement.f90
index 83d2d324aed87..f1e535a2bd3a1 100644
--- a/flang/test/Lower/entry-statement.f90
+++ b/flang/test/Lower/entry-statement.f90
@@ -491,7 +491,7 @@ subroutine assumed_size()
! CHECK-LABEL: func.func @_QPentry_with_assumed_size(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<?xf32>> {fir.bindc_name = "x"}) {
! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[VAL_2:.*]] = arith.constant -1 : index
+! CHECK: %[[VAL_2:.*]] = fir.assumed_size_extent : index
! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_3]]) dummy_scope %[[VAL_1]] {uniq_name = "_QFassumed_sizeEx"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)
! CHECK: cf.br ^bb1
>From b3255131ec065df34a06de70382a37022532fb9a Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Wed, 22 Oct 2025 00:29:47 -0700
Subject: [PATCH 2/3] use new op builder API
---
flang/lib/Lower/Bridge.cpp | 2 +-
flang/lib/Lower/ConvertVariable.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 579e0b673955c..2f506ba4cc1b2 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -4011,7 +4011,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// POINTER/ALLOCATBLE as per F'2023 C1160.
fir::ExtendedValue newExv;
llvm::SmallVector<mlir::Value> assumeSizeExtents{
- builder->create<fir::AssumedSizeExtentOp>(loc)};
+ fir::AssumedSizeExtentOp::create(*builer, loc)};
mlir::Value baseAddr =
hlfir::genVariableRawAddress(loc, *builder, selector);
const bool isVolatile = fir::isa_volatile_type(selector.getType());
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index dcee64f6a614d..2517ab35d4ff0 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1711,7 +1711,7 @@ static void lowerExplicitLowerBounds(
/// CFI_desc_t requirements in 18.5.3 point 5.).
static mlir::Value getAssumedSizeExtent(mlir::Location loc,
fir::FirOpBuilder &builder) {
- return builder.create<fir::AssumedSizeExtentOp>(loc);
+ return fir::AssumedSizeExtentOp::create(builder, loc);
}
/// Lower explicit extents into \p result if this is an explicit-shape or
>From 90dd822da8b0563c04b6e6b2988aa6dc84045404 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Wed, 22 Oct 2025 01:07:09 -0700
Subject: [PATCH 3/3] fix typo
---
flang/lib/Lower/Bridge.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 2f506ba4cc1b2..238a623dc6c5d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -4011,7 +4011,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// POINTER/ALLOCATBLE as per F'2023 C1160.
fir::ExtendedValue newExv;
llvm::SmallVector<mlir::Value> assumeSizeExtents{
- fir::AssumedSizeExtentOp::create(*builer, loc)};
+ fir::AssumedSizeExtentOp::create(*builder, loc)};
mlir::Value baseAddr =
hlfir::genVariableRawAddress(loc, *builder, selector);
const bool isVolatile = fir::isa_volatile_type(selector.getType());
More information about the flang-commits
mailing list