This reverts commit 5178aeff7b96e86b066f8407b9d9732ec660dd2e. 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.
This commit is contained in:
parent
c79a88ee0a
commit
6f489fb5e5
@ -170,6 +170,17 @@ protected:
|
||||
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);
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
271
flang/test/Lower/HLFIR/eoshift.f90
Normal file
271
flang/test/Lower/HLFIR/eoshift.f90
Normal file
@ -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: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"},
|
||||
! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "s"},
|
||||
! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "d"}) {
|
||||
! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope
|
||||
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_3]] {uniq_name = "_QFeoshift11Ea"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
|
||||
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] {uniq_name = "_QFeoshift11Ed"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_3]] {uniq_name = "_QFeoshift11Es"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[VAL_7:.*]] = arith.constant 2 : i32
|
||||
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
|
||||
! CHECK: %[[VAL_9:.*]] = hlfir.eoshift %[[VAL_4]]#0 %[[VAL_7]] dim %[[VAL_8]] : (!fir.box<!fir.array<?xi32>>, i32, i32) -> !hlfir.expr<?xi32>
|
||||
! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_4]]#0 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
|
||||
! CHECK: hlfir.destroy %[[VAL_9]] : !hlfir.expr<?xi32>
|
||||
! CHECK: return
|
||||
! CHECK: }
|
||||
|
||||
subroutine eoshift12(array, shift, boundary, dim)
|
||||
real :: array(:,:)
|
||||
real, optional :: boundary
|
||||
integer :: shift(:), dim
|
||||
array = EOSHIFT(array, shift, boundary, dim)
|
||||
end subroutine eoshift12
|
||||
! CHECK-LABEL: func.func @_QPeoshift12(
|
||||
! CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "array"},
|
||||
! CHECK-SAME: %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "shift"},
|
||||
! CHECK-SAME: %[[ARG2:.*]]: !fir.ref<f32> {fir.bindc_name = "boundary", fir.optional},
|
||||
! CHECK-SAME: %[[ARG3:.*]]: !fir.ref<i32> {fir.bindc_name = "dim"}) {
|
||||
! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope
|
||||
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {uniq_name = "_QFeoshift12Earray"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
|
||||
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG2]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFeoshift12Eboundary"} : (!fir.ref<f32>, !fir.dscope) -> (!fir.ref<f32>, !fir.ref<f32>)
|
||||
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[ARG3]] dummy_scope %[[VAL_0]] {uniq_name = "_QFeoshift12Edim"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QFeoshift12Eshift"} : (!fir.box<!fir.array<?xi32>>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
|
||||
! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_2]]#0 : (!fir.ref<f32>) -> i1
|
||||
! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_2]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
|
||||
! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box<f32>
|
||||
! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_5]], %[[VAL_6]], %[[VAL_7]] : !fir.box<f32>
|
||||
! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
|
||||
! CHECK: %[[VAL_10:.*]] = hlfir.eoshift %[[VAL_1]]#0 %[[VAL_4]]#0 boundary %[[VAL_8]] dim %[[VAL_9]] : (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?xi32>>, !fir.box<f32>, i32) -> !hlfir.expr<?x?xf32>
|
||||
! CHECK: hlfir.assign %[[VAL_10]] to %[[VAL_1]]#0 : !hlfir.expr<?x?xf32>, !fir.box<!fir.array<?x?xf32>>
|
||||
! CHECK: hlfir.destroy %[[VAL_10]] : !hlfir.expr<?x?xf32>
|
||||
! CHECK: return
|
||||
! CHECK: }
|
||||
|
||||
! Test scalar logical boundary.
|
||||
! CHECK-LABEL: func.func @_QPeoshift13(
|
||||
subroutine eoshift13(array)
|
||||
logical(1) :: array(:)
|
||||
array = EOSHIFT(array, -1, .true._1)
|
||||
! CHECK: %[[VAL_5:.*]] = hlfir.eoshift %{{.*}} %{{.*}} boundary %{{.*}} : (!fir.box<!fir.array<?x!fir.logical<1>>>, i32, !fir.logical<1>) -> !hlfir.expr<?x!fir.logical<1>>
|
||||
array = EOSHIFT(array.EQV..false., -1, .true.)
|
||||
! CHECK: %[[VAL_24:.*]] = hlfir.eoshift %{{.*}} %{{.*}} boundary %{{.*}} : (!hlfir.expr<?x!fir.logical<4>>, i32, !fir.logical<4>) -> !hlfir.expr<?x!fir.logical<4>>
|
||||
end subroutine eoshift13
|
||||
|
||||
! Test scalar constant BOUNDARY value of UNSIGNED type.
|
||||
! The BOUNDARY operand of hlfir.eoshift must have ui32 type
|
||||
! (i.e. consistent with the array/result type).
|
||||
! CHECK-LABEL: func.func @_QPeoshift14(
|
||||
subroutine eoshift14(array)
|
||||
unsigned :: array(:)
|
||||
array = EOSHIFT(array, shift=1, boundary=1u)
|
||||
! CHECK-DAG: %[[VAL_4:.*]] = fir.convert %[[VAL_3:.*]] : (i32) -> ui32
|
||||
! CHECK-DAG: %[[VAL_3]] = arith.constant 1 : i32
|
||||
! CHECK: %[[VAL_5:.*]] = hlfir.eoshift{{.*}}boundary %[[VAL_4]] : (!fir.box<!fir.array<?xui32>>, i32, ui32) -> !hlfir.expr<?xui32>
|
||||
end subroutine eoshift14
|
Loading…
x
Reference in New Issue
Block a user