[flang-commits] [flang] [flang] improve Entity::hasNonDefaultLowerBounds (PR #93848)
via flang-commits
flang-commits at lists.llvm.org
Thu May 30 23:42:58 PDT 2024
https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/93848
>From 6cc50c0fce39c61c973bca00ff3c9e67b1c972ad Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Thu, 30 May 2024 10:22:13 -0700
Subject: [PATCH 1/2] [flang] improve Entity::hasNonDefaultLowerBounds
---
.../flang/Optimizer/Builder/HLFIRTools.h | 16 +-----------
flang/lib/Optimizer/Builder/HLFIRTools.cpp | 26 ++++++++++++++++++-
flang/test/HLFIR/maxloc-elemental.fir | 10 ++-----
flang/test/HLFIR/minloc-elemental.fir | 20 +++-----------
4 files changed, 32 insertions(+), 40 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
index 6dce89d2ecabb..0b042f2646bca 100644
--- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h
+++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
@@ -116,21 +116,7 @@ class Entity : public mlir::Value {
return fir::isRecordWithTypeParameters(getFortranElementType());
}
- bool hasNonDefaultLowerBounds() const {
- if (!isBoxAddressOrValue() || isScalar())
- return false;
- if (isMutableBox())
- return true;
- if (auto varIface = getIfVariableInterface()) {
- if (auto shape = varIface.getShape()) {
- auto shapeTy = shape.getType();
- return mlir::isa<fir::ShiftType>(shapeTy) ||
- mlir::isa<fir::ShapeShiftType>(shapeTy);
- }
- return false;
- }
- return true;
- }
+ bool hasNonDefaultLowerBounds() const;
// Is this entity known to be contiguous at compile time?
// Note that when this returns false, the entity may still
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index e14e635a7f46b..fe5e260c749b7 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -195,6 +195,29 @@ mlir::Value hlfir::Entity::getFirBase() const {
return getBase();
}
+static bool isShapeWithLowerBounds(mlir::Value shape) {
+ if (!shape)
+ return false;
+ auto shapeTy = shape.getType();
+ return mlir::isa<fir::ShiftType>(shapeTy) ||
+ mlir::isa<fir::ShapeShiftType>(shapeTy);
+}
+
+bool hlfir::Entity::hasNonDefaultLowerBounds() const {
+ if (!isBoxAddressOrValue() || isScalar())
+ return false;
+ if (isMutableBox())
+ return true;
+ if (auto varIface = getIfVariableInterface())
+ return isShapeWithLowerBounds(varIface.getShape());
+ // Go through chain of fir.box converts.
+ if (auto convert = getDefiningOp<fir::ConvertOp>())
+ return hlfir::Entity{convert.getValue()}.hasNonDefaultLowerBounds();
+ // TODO: Embox and Rebox do not have hlfir variable interface, but are
+ // easy to reason about.
+ return true;
+}
+
fir::FortranVariableOpInterface
hlfir::genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
const fir::ExtendedValue &exv, llvm::StringRef name,
@@ -891,7 +914,8 @@ static fir::ExtendedValue translateVariableToExtendedValue(
llvm::SmallVector<mlir::Value> extents;
llvm::SmallVector<mlir::Value> nonDefaultLbounds;
if (mlir::isa<fir::BaseBoxType>(variable.getType()) &&
- !variable.getIfVariableInterface()) {
+ !variable.getIfVariableInterface() &&
+ variable.hasNonDefaultLowerBounds()) {
// This special case avoids generating two sets of identical
// fir.box_dim to get both the lower bounds and extents.
genLboundsAndExtentsFromBox(loc, builder, variable, nonDefaultLbounds,
diff --git a/flang/test/HLFIR/maxloc-elemental.fir b/flang/test/HLFIR/maxloc-elemental.fir
index c97117dd10de1..497a58c9bd1d4 100644
--- a/flang/test/HLFIR/maxloc-elemental.fir
+++ b/flang/test/HLFIR/maxloc-elemental.fir
@@ -47,10 +47,7 @@ func.func @_QPtest(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "array"}
// CHECK-NEXT: %[[V17:.*]] = arith.cmpi sge, %[[V16]], %[[V4]] : i32
// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (i32) {
// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref<i32>
-// CHECK-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-// CHECK-NEXT: %[[SUB:.*]] = arith.subi %[[DIMS]]#0, %c1 : index
-// CHECK-NEXT: %[[ADD:.*]] = arith.addi %[[V14]], %[[SUB]] : index
-// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[ADD]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref<i32>
// CHECK-NEXT: %[[V21:.*]] = arith.cmpi sgt, %[[V20]], %arg4 : i32
// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i32) -> i1
@@ -114,10 +111,7 @@ func.func @_QPtest_float(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a
// CHECK-NEXT: %[[V17:.*]] = arith.cmpf oge, %[[V16]], %[[V4:.*]] : f32
// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (f32) {
// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0:.*]] : !fir.ref<i32>
-// CHECK-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %2#0, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-// CHECK-NEXT: %[[SUB:.*]] = arith.subi %[[DIMS]]#0, %c1 : index
-// CHECK-NEXT: %[[ADD:.*]] = arith.addi %[[V14]], %[[SUB]] : index
-// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[ADD]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref<f32>
// CHECK-NEXT: %[[NEW_MIN:.*]] = arith.cmpf ogt, %[[V20]], %arg4 fastmath<contract> : f32
// CHECK-NEXT: %[[CONDRED:.*]] = arith.cmpf une, %arg4, %arg4 fastmath<contract> : f32
diff --git a/flang/test/HLFIR/minloc-elemental.fir b/flang/test/HLFIR/minloc-elemental.fir
index 58cfe3ea01279..45993c5eee0c9 100644
--- a/flang/test/HLFIR/minloc-elemental.fir
+++ b/flang/test/HLFIR/minloc-elemental.fir
@@ -47,10 +47,7 @@ func.func @_QPtest(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "array"}
// CHECK-NEXT: %[[V17:.*]] = arith.cmpi sge, %[[V16]], %[[V4]] : i32
// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (i32) {
// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref<i32>
-// CHECK-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-// CHECK-NEXT: %[[SUB:.*]] = arith.subi %[[DIMS]]#0, %c1 : index
-// CHECK-NEXT: %[[ADD:.*]] = arith.addi %[[V14]], %[[SUB]] : index
-// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[ADD]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref<i32>
// CHECK-NEXT: %[[V21:.*]] = arith.cmpi slt, %[[V20]], %arg4 : i32
// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i32) -> i1
@@ -129,10 +126,7 @@ func.func @_QPtest_kind2(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a
// CHECK-NEXT: %[[V17:.*]] = arith.cmpi sge, %[[V16]], %[[V4]] : i32
// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (i32) {
// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref<i16>
-// CHECK-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-// CHECK-NEXT: %[[SUB:.*]] = arith.subi %[[DIMS]]#0, %c1 : index
-// CHECK-NEXT: %[[ADD:.*]] = arith.addi %[[V14]], %[[SUB]] : index
-// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[ADD]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref<i32>
// CHECK-NEXT: %[[V21:.*]] = arith.cmpi slt, %[[V20]], %arg4 : i32
// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i16) -> i1
@@ -222,10 +216,7 @@ func.func @_QPtest_kind2_convert(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_n
// CHECK-NEXT: %[[V18:.*]] = arith.cmpi sge, %[[V17]], %[[V5]] : i32
// CHECK-NEXT: %[[V19:.*]] = fir.if %[[V18]] -> (i32) {
// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref<i16>
-// CHECK-NEXT: %[[V20:.*]]:3 = fir.box_dims %[[V2]]#0, %c0 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-// CHECK-NEXT: %[[V21:.*]] = arith.subi %[[V20]]#0, %c1 : index
-// CHECK-NEXT: %[[V22:.*]] = arith.addi %[[V15]], %[[V21]] : index
-// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %[[V2]]#0 (%[[V22]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %[[V2]]#0 (%[[V15]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
// CHECK-NEXT: %[[V24:.*]] = fir.load %[[V23]] : !fir.ref<i32>
// CHECK-NEXT: %[[V25:.*]] = arith.cmpi slt, %[[V24]], %arg4 : i32
// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i16) -> i1
@@ -291,10 +282,7 @@ func.func @_QPtest_float(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a
// CHECK-NEXT: %[[V17:.*]] = arith.cmpf oge, %[[V16]], %[[V4:.*]] : f32
// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (f32) {
// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0:.*]] : !fir.ref<i32>
-// CHECK-NEXT: %[[DIMS:.*]]:3 = fir.box_dims %2#0, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-// CHECK-NEXT: %[[SUB:.*]] = arith.subi %[[DIMS]]#0, %c1 : index
-// CHECK-NEXT: %[[ADD:.*]] = arith.addi %[[V14]], %[[SUB]] : index
-// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[ADD]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref<f32>
// CHECK-NEXT: %[[NEW_MIN:.*]] = arith.cmpf olt, %[[V20]], %arg4 fastmath<contract> : f32
// CHECK-NEXT: %[[CONDRED:.*]] = arith.cmpf une, %arg4, %arg4 fastmath<contract> : f32
>From ce0d9716bb45c78a00174f9838a86adaa9b61a61 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Thu, 30 May 2024 23:42:05 -0700
Subject: [PATCH 2/2] rename to mayHaveNonDefaultLowerBounds
---
flang/include/flang/Optimizer/Builder/HLFIRTools.h | 2 +-
flang/lib/Lower/ConvertExprToHLFIR.cpp | 8 ++++----
flang/lib/Optimizer/Builder/HLFIRTools.cpp | 12 ++++++------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
index 0b042f2646bca..6b41025eea078 100644
--- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h
+++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
@@ -116,7 +116,7 @@ class Entity : public mlir::Value {
return fir::isRecordWithTypeParameters(getFortranElementType());
}
- bool hasNonDefaultLowerBounds() const;
+ bool mayHaveNonDefaultLowerBounds() const;
// Is this entity known to be contiguous at compile time?
// Note that when this returns false, the entity may still
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index a4352ee3359e5..9035856eabfe7 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -151,7 +151,7 @@ class HlfirDesignatorBuilder {
}
extents.push_back(builder.createIntegerConstant(loc, idxTy, extent));
}
- if (!hasNonDefaultLowerBounds(componentSym))
+ if (!mayHaveNonDefaultLowerBounds(componentSym))
return builder.create<fir::ShapeOp>(loc, extents);
llvm::SmallVector<mlir::Value> lbounds;
@@ -215,7 +215,7 @@ class HlfirDesignatorBuilder {
// Arrays with non default lower bounds or dynamic length or dynamic extent
// need a fir.box to hold the dynamic or lower bound information.
if (fir::hasDynamicSize(resultValueType) ||
- hasNonDefaultLowerBounds(partInfo))
+ mayHaveNonDefaultLowerBounds(partInfo))
return fir::BoxType::get(resultValueType);
// Non simply contiguous ref require a fir.box to carry the byte stride.
if (mlir::isa<fir::SequenceType>(resultValueType) &&
@@ -600,7 +600,7 @@ class HlfirDesignatorBuilder {
}
static bool
- hasNonDefaultLowerBounds(const Fortran::semantics::Symbol &componentSym) {
+ mayHaveNonDefaultLowerBounds(const Fortran::semantics::Symbol &componentSym) {
if (const auto *objDetails =
componentSym.detailsIf<Fortran::semantics::ObjectEntityDetails>())
for (const Fortran::semantics::ShapeSpec &bounds : objDetails->shape())
@@ -610,7 +610,7 @@ class HlfirDesignatorBuilder {
return true;
return false;
}
- static bool hasNonDefaultLowerBounds(const PartInfo &partInfo) {
+ static bool mayHaveNonDefaultLowerBounds(const PartInfo &partInfo) {
return partInfo.resultShape &&
mlir::isa<fir::ShiftType, fir::ShapeShiftType>(
partInfo.resultShape.getType());
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index fe5e260c749b7..b80fcccfddef9 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -115,7 +115,7 @@ genLboundsAndExtentsFromBox(mlir::Location loc, fir::FirOpBuilder &builder,
static llvm::SmallVector<mlir::Value>
getNonDefaultLowerBounds(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity entity) {
- if (!entity.hasNonDefaultLowerBounds())
+ if (!entity.mayHaveNonDefaultLowerBounds())
return {};
if (auto varIface = entity.getIfVariableInterface()) {
llvm::SmallVector<mlir::Value> lbounds = getExplicitLbounds(varIface);
@@ -203,7 +203,7 @@ static bool isShapeWithLowerBounds(mlir::Value shape) {
mlir::isa<fir::ShapeShiftType>(shapeTy);
}
-bool hlfir::Entity::hasNonDefaultLowerBounds() const {
+bool hlfir::Entity::mayHaveNonDefaultLowerBounds() const {
if (!isBoxAddressOrValue() || isScalar())
return false;
if (isMutableBox())
@@ -212,7 +212,7 @@ bool hlfir::Entity::hasNonDefaultLowerBounds() const {
return isShapeWithLowerBounds(varIface.getShape());
// Go through chain of fir.box converts.
if (auto convert = getDefiningOp<fir::ConvertOp>())
- return hlfir::Entity{convert.getValue()}.hasNonDefaultLowerBounds();
+ return hlfir::Entity{convert.getValue()}.mayHaveNonDefaultLowerBounds();
// TODO: Embox and Rebox do not have hlfir variable interface, but are
// easy to reason about.
return true;
@@ -594,7 +594,7 @@ mlir::Value hlfir::genExtent(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value hlfir::genLBound(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity entity, unsigned dim) {
- if (!entity.hasNonDefaultLowerBounds())
+ if (!entity.mayHaveNonDefaultLowerBounds())
return builder.createIntegerConstant(loc, builder.getIndexType(), 1);
if (auto shape = tryRetrievingShapeOrShift(entity)) {
auto lbounds = getExplicitLboundsFromShape(shape);
@@ -915,7 +915,7 @@ static fir::ExtendedValue translateVariableToExtendedValue(
llvm::SmallVector<mlir::Value> nonDefaultLbounds;
if (mlir::isa<fir::BaseBoxType>(variable.getType()) &&
!variable.getIfVariableInterface() &&
- variable.hasNonDefaultLowerBounds()) {
+ variable.mayHaveNonDefaultLowerBounds()) {
// This special case avoids generating two sets of identical
// fir.box_dim to get both the lower bounds and extents.
genLboundsAndExtentsFromBox(loc, builder, variable, nonDefaultLbounds,
@@ -1243,7 +1243,7 @@ hlfir::genTypeAndKindConvert(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::genElementalOp(loc, builder, toType, shape, lenParams, genKernel,
/*isUnordered=*/true);
- if (preserveLowerBounds && source.hasNonDefaultLowerBounds()) {
+ if (preserveLowerBounds && source.mayHaveNonDefaultLowerBounds()) {
hlfir::AssociateOp associate =
genAssociateExpr(loc, builder, hlfir::Entity{convertedRhs},
convertedRhs.getType(), ".tmp.keeplbounds");
More information about the flang-commits
mailing list