-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Reapply "[flang] Lower EOSHIFT into hlfir.eoshift." (#153907) #154241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This reverts commit 5178aef. In addition: * Scalar constant UNSIGNED BOUNDARY is explicitly casted to the result type so that the generated hlfir.eoshift operation is valid. The lowering produces signless constants by default. It might be a bigger issue in lowering, so I just want to "fix" it for EOSHIFT in this patch. * Since we have to create unsigned integer constant during HLFIR inlining, I added code in createIntegerConstant to make it possible.
@llvm/pr-subscribers-flang-fir-hlfir Author: Slava Zakharin (vzakhari) ChangesThis reverts commit 5178aef. In addition:
Patch is 24.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154241.diff 4 Files Affected:
diff --git a/flang/lib/Lower/HlfirIntrinsics.cpp b/flang/lib/Lower/HlfirIntrinsics.cpp
index 6e1d06a25924b..39595d6f519ad 100644
--- a/flang/lib/Lower/HlfirIntrinsics.cpp
+++ b/flang/lib/Lower/HlfirIntrinsics.cpp
@@ -170,6 +170,17 @@ class HlfirCShiftLowering : public HlfirTransformationalIntrinsic {
mlir::Type stmtResultType) override;
};
+class HlfirEOShiftLowering : public HlfirTransformationalIntrinsic {
+public:
+ using HlfirTransformationalIntrinsic::HlfirTransformationalIntrinsic;
+
+protected:
+ mlir::Value
+ lowerImpl(const Fortran::lower::PreparedActualArguments &loweredActuals,
+ const fir::IntrinsicArgumentLoweringRules *argLowering,
+ mlir::Type stmtResultType) override;
+};
+
class HlfirReshapeLowering : public HlfirTransformationalIntrinsic {
public:
using HlfirTransformationalIntrinsic::HlfirTransformationalIntrinsic;
@@ -430,6 +441,46 @@ mlir::Value HlfirCShiftLowering::lowerImpl(
return createOp<hlfir::CShiftOp>(resultType, operands);
}
+mlir::Value HlfirEOShiftLowering::lowerImpl(
+ const Fortran::lower::PreparedActualArguments &loweredActuals,
+ const fir::IntrinsicArgumentLoweringRules *argLowering,
+ mlir::Type stmtResultType) {
+ auto operands = getOperandVector(loweredActuals, argLowering);
+ assert(operands.size() == 4);
+ mlir::Value array = operands[0];
+ mlir::Value shift = operands[1];
+ mlir::Value boundary = operands[2];
+ mlir::Value dim = operands[3];
+ // If DIM is present, then dereference it if it is a ref.
+ if (dim)
+ dim = hlfir::loadTrivialScalar(loc, builder, hlfir::Entity{dim});
+
+ mlir::Type resultType = computeResultType(array, stmtResultType);
+
+ if (boundary && fir::isa_trivial(boundary.getType())) {
+ mlir::Type elementType = hlfir::getFortranElementType(resultType);
+ if (auto logicalTy = mlir::dyn_cast<fir::LogicalType>(elementType)) {
+ // Scalar logical constant boundary might be represented using i1, i2, ...
+ // type. We need to cast it to fir.logical type of the ARRAY/result.
+ if (boundary.getType() != logicalTy)
+ boundary = builder.createConvert(loc, logicalTy, boundary);
+ } else {
+ // When the boundary is a constant like '1u', the lowering converts
+ // it into a signless arith.constant value (which is a requirement
+ // of the Arith dialect). If the ARRAY/RESULT is also UNSIGNED,
+ // we have to cast the boundary to the same unsigned type.
+ auto resultIntTy = mlir::dyn_cast<mlir::IntegerType>(elementType);
+ auto boundaryIntTy =
+ mlir::dyn_cast<mlir::IntegerType>(boundary.getType());
+ if (resultIntTy && boundaryIntTy &&
+ resultIntTy.getSignedness() != boundaryIntTy.getSignedness())
+ boundary = builder.createConvert(loc, resultIntTy, boundary);
+ }
+ }
+
+ return createOp<hlfir::EOShiftOp>(resultType, array, shift, boundary, dim);
+}
+
mlir::Value HlfirReshapeLowering::lowerImpl(
const Fortran::lower::PreparedActualArguments &loweredActuals,
const fir::IntrinsicArgumentLoweringRules *argLowering,
@@ -489,6 +540,9 @@ std::optional<hlfir::EntityWithAttributes> Fortran::lower::lowerHlfirIntrinsic(
if (name == "cshift")
return HlfirCShiftLowering{builder, loc}.lower(loweredActuals, argLowering,
stmtResultType);
+ if (name == "eoshift")
+ return HlfirEOShiftLowering{builder, loc}.lower(loweredActuals, argLowering,
+ stmtResultType);
if (name == "reshape")
return HlfirReshapeLowering{builder, loc}.lower(loweredActuals, argLowering,
stmtResultType);
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index b6baefb67b4bf..99533690018eb 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -147,8 +147,20 @@ mlir::Value fir::FirOpBuilder::createIntegerConstant(mlir::Location loc,
assert((cst >= 0 || mlir::isa<mlir::IndexType>(ty) ||
mlir::cast<mlir::IntegerType>(ty).getWidth() <= 64) &&
"must use APint");
- return mlir::arith::ConstantOp::create(*this, loc, ty,
- getIntegerAttr(ty, cst));
+
+ mlir::Type cstType = ty;
+ if (auto intType = mlir::dyn_cast<mlir::IntegerType>(ty)) {
+ // Signed and unsigned constants must be encoded as signless
+ // arith.constant followed by fir.convert cast.
+ if (intType.isUnsigned())
+ cstType = mlir::IntegerType::get(getContext(), intType.getWidth());
+ else if (intType.isSigned())
+ TODO(loc, "signed integer constant");
+ }
+
+ mlir::Value cstValue = mlir::arith::ConstantOp::create(
+ *this, loc, cstType, getIntegerAttr(cstType, cst));
+ return createConvert(loc, ty, cstValue);
}
mlir::Value fir::FirOpBuilder::createAllOnesInteger(mlir::Location loc,
diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-eoshift.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-eoshift.fir
index 88191d517c2b5..d8975c9741287 100644
--- a/flang/test/HLFIR/simplify-hlfir-intrinsics-eoshift.fir
+++ b/flang/test/HLFIR/simplify-hlfir-intrinsics-eoshift.fir
@@ -697,6 +697,33 @@ func.func @_QPeoshift7(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.
// CHECK: return
// CHECK: }
+// Test UNSIGNED data type.
+// The default value of the BOUNDARY must be an integer 0
+// converted to ui32 type.
+// subroutine eoshift8(array)
+// unsigned :: array(:,:)
+// array = EOSHIFT(array, shift=1, dim=2)
+// end subroutine
+func.func @_QPeoshift8(%arg0: !fir.box<!fir.array<?x?xui32>> {fir.bindc_name = "array"}) {
+ %c2_i32 = arith.constant 2 : i32
+ %c1_i32 = arith.constant 1 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFeoshift8Earray"} : (!fir.box<!fir.array<?x?xui32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xui32>>, !fir.box<!fir.array<?x?xui32>>)
+ %2 = hlfir.eoshift %1#0 %c1_i32 dim %c2_i32 : (!fir.box<!fir.array<?x?xui32>>, i32, i32) -> !hlfir.expr<?x?xui32>
+ hlfir.assign %2 to %1#0 : !hlfir.expr<?x?xui32>, !fir.box<!fir.array<?x?xui32>>
+ hlfir.destroy %2 : !hlfir.expr<?x?xui32>
+ return
+}
+// CHECK-LABEL: func.func @_QPeoshift8(
+// CHECK-DAG: hlfir.elemental %{{.*}} unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xui32> {
+// CHECK-DAG: %[[VAL_24:.*]] = fir.load %{{.*}} : !fir.ref<ui32>
+// CHECK-DAG: fir.result %[[VAL_24]] : ui32
+// CHECK-DAG: } else {
+// CHECK-DAG: fir.result %[[VAL_12:.*]] : ui32
+// CHECK-DAG: }
+// CHECK-DAG: %[[VAL_12]] = fir.convert %[[VAL_1:.*]] : (i32) -> ui32
+// CHECK-DAG: %[[VAL_1]] = arith.constant 0 : i32
+
// ! Tests for CHARACTER type (lowered via hlfir.elemental).
// ! Test contiguous 1D array with statically absent boundary.
diff --git a/flang/test/Lower/HLFIR/eoshift.f90 b/flang/test/Lower/HLFIR/eoshift.f90
new file mode 100644
index 0000000000000..e7fb98c2b0401
--- /dev/null
+++ b/flang/test/Lower/HLFIR/eoshift.f90
@@ -0,0 +1,271 @@
+! Test lowering of EOSHIFT intrinsic to HLFIR
+! RUN: bbc -emit-hlfir -o - -I nowhere %s 2>&1 | FileCheck %s
+
+module eoshift_types
+ type t
+ end type t
+end module eoshift_types
+
+! 1d shift by scalar
+subroutine eoshift1(a, s)
+ integer :: a(:), s
+ a = EOSHIFT(a, 2)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift1(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box<!fir.array<?xi32>>, i32) -> !hlfir.expr<?xi32>
+! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr<?xi32>
+! CHECK: return
+! CHECK: }
+
+! 1d shift by scalar with dim
+subroutine eoshift2(a, s)
+ integer :: a(:), s
+ a = EOSHIFT(a, 2, dim=1)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift2(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_7:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_5]] dim %[[VAL_6]] : (!fir.box<!fir.array<?xi32>>, i32, i32) -> !hlfir.expr<?xi32>
+! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_3]]#0 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr<?xi32>
+! CHECK: return
+! CHECK: }
+
+! 2d shift by scalar
+subroutine eoshift3(a, s)
+ integer :: a(:,:), s
+ a = EOSHIFT(a, 2)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift3(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box<!fir.array<?x?xi32>>, i32) -> !hlfir.expr<?x?xi32>
+! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr<?x?xi32>, !fir.box<!fir.array<?x?xi32>>
+! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr<?x?xi32>
+! CHECK: return
+! CHECK: }
+
+! 2d shift by scalar with dim
+subroutine eoshift4(a, s)
+ integer :: a(:,:), s
+ a = EOSHIFT(a, 2, dim=2)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift4(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_7:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_5]] dim %[[VAL_6]] : (!fir.box<!fir.array<?x?xi32>>, i32, i32) -> !hlfir.expr<?x?xi32>
+! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_3]]#0 : !hlfir.expr<?x?xi32>, !fir.box<!fir.array<?x?xi32>>
+! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr<?x?xi32>
+! CHECK: return
+! CHECK: }
+
+! 2d shift by array
+subroutine eoshift5(a, s)
+ integer :: a(:,:), s(:)
+ a = EOSHIFT(a, s)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift5(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_4]]#0 : (!fir.box<!fir.array<?x?xi32>>, !fir.box<!fir.array<?xi32>>) -> !hlfir.expr<?x?xi32>
+! CHECK: hlfir.assign %[[VAL_5]] to %[[VAL_3]]#0 : !hlfir.expr<?x?xi32>, !fir.box<!fir.array<?x?xi32>>
+! CHECK: hlfir.destroy %[[VAL_5]] : !hlfir.expr<?x?xi32>
+! CHECK: return
+! CHECK: }
+
+! 2d shift by array expr
+subroutine eoshift6(a, s)
+ integer :: a(:,:), s(:)
+ a = EOSHIFT(a, s + 1)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift6(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_4]]#0, %[[VAL_6]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32>
+! CHECK: %[[VAL_14:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_9]] : (!fir.box<!fir.array<?x?xi32>>, !hlfir.expr<?xi32>) -> !hlfir.expr<?x?xi32>
+! CHECK: hlfir.assign %[[VAL_14]] to %[[VAL_3]]#0 : !hlfir.expr<?x?xi32>, !fir.box<!fir.array<?x?xi32>>
+! CHECK: hlfir.destroy %[[VAL_14]] : !hlfir.expr<?x?xi32>
+! CHECK: hlfir.destroy %[[VAL_9]] : !hlfir.expr<?xi32>
+! CHECK: return
+! CHECK: }
+
+! 1d character(10,2) shift by scalar
+subroutine eoshift7(a, s)
+ character(10,2) :: a(:)
+ a = EOSHIFT(a, 2)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift7(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<2,10>>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_6:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_7:.*]] = hlfir.eoshift %[[VAL_4]]#0 %[[VAL_6]] : (!fir.box<!fir.array<?x!fir.char<2,10>>>, i32) -> !hlfir.expr<?x!fir.char<2,10>>
+! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_4]]#0 : !hlfir.expr<?x!fir.char<2,10>>, !fir.box<!fir.array<?x!fir.char<2,10>>>
+! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr<?x!fir.char<2,10>>
+! CHECK: return
+! CHECK: }
+
+! 1d character(*) shift by scalar
+subroutine eoshift8(a, s)
+ character(*) :: a(:)
+ a = EOSHIFT(a, 2)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift8(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]]
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]]
+! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_6:.*]] = hlfir.eoshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, i32) -> !hlfir.expr<?x!fir.char<1,?>>
+! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr<?x!fir.char<1,?>>, !fir.box<!fir.array<?x!fir.char<1,?>>>
+! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr<?x!fir.char<1,?>>
+! CHECK: return
+! CHECK: }
+
+! 1d type(t) shift by scalar
+subroutine eoshift9(a, s)
+ use eoshift_types
+ type(t) :: a(:)
+ a = EOSHIFT(a, 2, boundary=t())
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift9(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMeoshift_typesTt>>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[ARG1:.*]]: !fir.ref<f32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {uniq_name = "_QFeoshift9Ea"} : (!fir.box<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>, !fir.box<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QFeoshift9Es"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QQro._QMeoshift_typesTt.0) : !fir.ref<!fir.type<_QMeoshift_typesTt>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QMeoshift_typesTt.0"} : (!fir.ref<!fir.type<_QMeoshift_typesTt>>) -> (!fir.ref<!fir.type<_QMeoshift_typesTt>>, !fir.ref<!fir.type<_QMeoshift_typesTt>>)
+! CHECK: %[[VAL_6:.*]] = hlfir.eoshift %[[VAL_1]]#0 %[[VAL_3]] boundary %[[VAL_5]]#0 : (!fir.box<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>, i32, !fir.ref<!fir.type<_QMeoshift_typesTt>>) -> !hlfir.expr<?x!fir.type<_QMeoshift_typesTt>>
+! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_1]]#0 : !hlfir.expr<?x!fir.type<_QMeoshift_typesTt>>, !fir.box<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>
+! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr<?x!fir.type<_QMeoshift_typesTt>>
+! CHECK: return
+! CHECK: }
+
+! 1d class(t) shift by scalar
+subroutine eoshift10(a, s)
+ use eoshift_types
+ class(t), allocatable :: a(:)
+ a = EOSHIFT(a, 2, boundary=t())
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift10(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[ARG1:.*]]: !fir.ref<f32> {fir.bindc_name = "s"}) {
+! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFeoshift10Ea"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>>)
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QFeoshift10Es"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_4:.*]] = fir.address_of(@_QQro._QMeoshift_typesTt.1) : !fir.ref<!fir.type<_QMeoshift_typesTt>>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QMeoshift_typesTt.1"} : (!fir.ref<!fir.type<_QMeoshift_typesTt>>) -> (!fir.ref<!fir.type<_QMeoshift_typesTt>>, !fir.ref<!fir.type<_QMeoshift_typesTt>>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>>
+! CHECK: %[[VAL_7:.*]] = hlfir.eoshift %[[VAL_6]] %[[VAL_3]] boundary %[[VAL_5]]#0 : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>, i32, !fir.ref<!fir.type<_QMeoshift_typesTt>>) -> !hlfir.expr<?x!fir.type<_QMeoshift_typesTt>?>
+! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_1]]#0 realloc : !hlfir.expr<?x!fir.type<_QMeoshift_typesTt>?>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMeoshift_typesTt>>>>>
+! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr<?x!fir.type<_QMeoshift_typesTt>?>
+! CHECK: return
+! CHECK: }
+
+! 1d shift by scalar with variable dim
+subroutine eoshift11(a, s, d)
+ integer :: a(:), s, d
+ a = EOSHIFT(a, 2, dim=d)
+end subroutine
+! CHECK-LABEL: func.func @_QPeoshift11(
+! CHECK-SAME: ...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix. Yes I imagine this could be a bigger issue in lowering. I know I haven't come across or considered this before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. LG.
This reverts commit 5178aef.
In addition:
to the result type so that the generated hlfir.eoshift
operation is valid. The lowering produces signless constants
by default. It might be a bigger issue in lowering, so I just
want to "fix" it for EOSHIFT in this patch.
HLFIR inlining, I added code in createIntegerConstant
to make it possible.