-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[flang] Lower EOSHIFT into hlfir.eoshift. #153106
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
@llvm/pr-subscribers-flang-fir-hlfir Author: Slava Zakharin (vzakhari) ChangesStraightforward lowering of EOSHIFT intrinsic into the new hlfir.eoshift Patch is 35.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153106.diff 6 Files Affected:
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
index ee0b5aa9760b1..0bddfd85d436b 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
@@ -95,9 +95,9 @@ def IsFortranValuePred : CPred<"::hlfir::isFortranValueType($_self)">;
def AnyFortranValue
: TypeConstraint<IsFortranValuePred, "any Fortran value type">;
-
-def AnyFortranEntity : TypeConstraint<Or<[AnyFortranVariable.predicate,
- AnyFortranValue.predicate]>, "any Fortran value or variable type">;
+def AnyFortranEntity
+ : Type<Or<[AnyFortranVariable.predicate, AnyFortranValue.predicate]>,
+ "any Fortran value or variable type">;
def IsFortranScalarCharacterPred
: CPred<"::hlfir::isFortranScalarCharacterType($_self)">;
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index 2f5da720fbe1d..db3fb0b90464d 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -721,6 +721,28 @@ def hlfir_CShiftOp
let hasVerifier = 1;
}
+def hlfir_EOShiftOp
+ : hlfir_Op<
+ "eoshift", [AttrSizedOperandSegments,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ let summary = "EOSHIFT transformational intrinsic";
+ let description = [{
+ End-off shift of an array
+ }];
+
+ let arguments = (ins AnyFortranArrayObject:$array,
+ AnyFortranIntegerScalarOrArrayObject:$shift,
+ Optional<AnyFortranEntity>:$boundary, Optional<AnyIntegerType>:$dim);
+
+ let results = (outs hlfir_ExprType);
+
+ let assemblyFormat = [{
+ $array $shift (`boundary` $boundary^)? (`dim` $dim^)? attr-dict `:` functional-type(operands, results)
+ }];
+
+ let hasVerifier = 1;
+}
+
def hlfir_ReshapeOp
: hlfir_Op<
"reshape", [AttrSizedOperandSegments,
diff --git a/flang/lib/Lower/HlfirIntrinsics.cpp b/flang/lib/Lower/HlfirIntrinsics.cpp
index 6e1d06a25924b..3b0f2e35cd5b5 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,33 @@ 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);
+
+ // 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 (auto logicalTy = mlir::dyn_cast<fir::LogicalType>(
+ hlfir::getFortranElementType(resultType)))
+ if (boundary && fir::isa_trivial(boundary.getType()) &&
+ boundary.getType() != logicalTy)
+ boundary = builder.createConvert(loc, logicalTy, 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 +527,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/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index ed102db69dae3..93ee94a120aa1 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -1440,44 +1440,46 @@ void hlfir::MatmulTransposeOp::getEffects(
}
//===----------------------------------------------------------------------===//
-// CShiftOp
+// Array shifts: CShiftOp/EOShiftOp
//===----------------------------------------------------------------------===//
-llvm::LogicalResult hlfir::CShiftOp::verify() {
- mlir::Value array = getArray();
+template <typename Op>
+static llvm::LogicalResult verifyArrayShift(Op op) {
+ mlir::Value array = op.getArray();
fir::SequenceType arrayTy = mlir::cast<fir::SequenceType>(
hlfir::getFortranElementOrSequenceType(array.getType()));
llvm::ArrayRef<int64_t> inShape = arrayTy.getShape();
std::size_t arrayRank = inShape.size();
mlir::Type eleTy = arrayTy.getEleTy();
- hlfir::ExprType resultTy = mlir::cast<hlfir::ExprType>(getResult().getType());
+ hlfir::ExprType resultTy =
+ mlir::cast<hlfir::ExprType>(op.getResult().getType());
llvm::ArrayRef<int64_t> resultShape = resultTy.getShape();
std::size_t resultRank = resultShape.size();
mlir::Type resultEleTy = resultTy.getEleTy();
- mlir::Value shift = getShift();
+ mlir::Value shift = op.getShift();
mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType(shift.getType());
- // TODO: turn allowCharacterLenMismatch into true.
- if (auto match = areMatchingTypes(*this, eleTy, resultEleTy,
- /*allowCharacterLenMismatch=*/false);
+ if (auto match = areMatchingTypes(
+ op, eleTy, resultEleTy,
+ /*allowCharacterLenMismatch=*/!useStrictIntrinsicVerifier);
match.failed())
- return emitOpError(
+ return op.emitOpError(
"input and output arrays should have the same element type");
if (arrayRank != resultRank)
- return emitOpError("input and output arrays should have the same rank");
+ return op.emitOpError("input and output arrays should have the same rank");
constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent();
for (auto [inDim, resultDim] : llvm::zip(inShape, resultShape))
if (inDim != unknownExtent && resultDim != unknownExtent &&
inDim != resultDim)
- return emitOpError(
+ return op.emitOpError(
"output array's shape conflicts with the input array's shape");
int64_t dimVal = -1;
- if (!getDim())
+ if (!op.getDim())
dimVal = 1;
- else if (auto dim = fir::getIntIfConstant(getDim()))
+ else if (auto dim = fir::getIntIfConstant(op.getDim()))
dimVal = *dim;
// The DIM argument may be statically invalid (e.g. exceed the
@@ -1485,44 +1487,79 @@ llvm::LogicalResult hlfir::CShiftOp::verify() {
// so avoid some checks unless useStrictIntrinsicVerifier is true.
if (useStrictIntrinsicVerifier && dimVal != -1) {
if (dimVal < 1)
- return emitOpError("DIM must be >= 1");
+ return op.emitOpError("DIM must be >= 1");
if (dimVal > static_cast<int64_t>(arrayRank))
- return emitOpError("DIM must be <= input array's rank");
+ return op.emitOpError("DIM must be <= input array's rank");
}
- if (auto shiftSeqTy = mlir::dyn_cast<fir::SequenceType>(shiftTy)) {
- // SHIFT is an array. Verify the rank and the shape (if DIM is constant).
- llvm::ArrayRef<int64_t> shiftShape = shiftSeqTy.getShape();
- std::size_t shiftRank = shiftShape.size();
- if (shiftRank != arrayRank - 1)
- return emitOpError(
- "SHIFT's rank must be 1 less than the input array's rank");
-
- if (useStrictIntrinsicVerifier && dimVal != -1) {
- // SHIFT's shape must be [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)],
- // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY.
- int64_t arrayDimIdx = 0;
- int64_t shiftDimIdx = 0;
- for (auto shiftDim : shiftShape) {
- if (arrayDimIdx == dimVal - 1)
+ // A helper lambda to verify the shape of the array types of
+ // certain operands of the array shift (e.g. the SHIFT and BOUNDARY operands).
+ auto verifyOperandTypeShape = [&](mlir::Type type,
+ llvm::Twine name) -> llvm::LogicalResult {
+ if (auto opndSeqTy = mlir::dyn_cast<fir::SequenceType>(type)) {
+ // The operand is an array. Verify the rank and the shape (if DIM is
+ // constant).
+ llvm::ArrayRef<int64_t> opndShape = opndSeqTy.getShape();
+ std::size_t opndRank = opndShape.size();
+ if (opndRank != arrayRank - 1)
+ return op.emitOpError(
+ name + "'s rank must be 1 less than the input array's rank");
+
+ if (useStrictIntrinsicVerifier && dimVal != -1) {
+ // The operand's shape must be
+ // [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)],
+ // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY.
+ int64_t arrayDimIdx = 0;
+ int64_t opndDimIdx = 0;
+ for (auto opndDim : opndShape) {
+ if (arrayDimIdx == dimVal - 1)
+ ++arrayDimIdx;
+
+ if (inShape[arrayDimIdx] != unknownExtent &&
+ opndDim != unknownExtent && inShape[arrayDimIdx] != opndDim)
+ return op.emitOpError("SHAPE(ARRAY)(" +
+ llvm::Twine(arrayDimIdx + 1) +
+ ") must be equal to SHAPE(" + name + ")(" +
+ llvm::Twine(opndDimIdx + 1) +
+ "): " + llvm::Twine(inShape[arrayDimIdx]) +
+ " != " + llvm::Twine(opndDim));
++arrayDimIdx;
-
- if (inShape[arrayDimIdx] != unknownExtent &&
- shiftDim != unknownExtent && inShape[arrayDimIdx] != shiftDim)
- return emitOpError("SHAPE(ARRAY)(" + llvm::Twine(arrayDimIdx + 1) +
- ") must be equal to SHAPE(SHIFT)(" +
- llvm::Twine(shiftDimIdx + 1) +
- "): " + llvm::Twine(inShape[arrayDimIdx]) +
- " != " + llvm::Twine(shiftDim));
- ++arrayDimIdx;
- ++shiftDimIdx;
+ ++opndDimIdx;
+ }
}
}
+ return mlir::success();
+ };
+
+ if (failed(verifyOperandTypeShape(shiftTy, "SHIFT")))
+ return mlir::failure();
+
+ if constexpr (std::is_same_v<Op, hlfir::EOShiftOp>) {
+ if (mlir::Value boundary = op.getBoundary()) {
+ mlir::Type boundaryTy =
+ hlfir::getFortranElementOrSequenceType(boundary.getType());
+ if (auto match = areMatchingTypes(
+ op, eleTy, hlfir::getFortranElementType(boundaryTy),
+ /*allowCharacterLenMismatch=*/!useStrictIntrinsicVerifier);
+ match.failed())
+ return op.emitOpError(
+ "ARRAY and BOUNDARY operands must have the same element type");
+ if (failed(verifyOperandTypeShape(boundaryTy, "BOUNDARY")))
+ return mlir::failure();
+ }
}
return mlir::success();
}
+//===----------------------------------------------------------------------===//
+// CShiftOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult hlfir::CShiftOp::verify() {
+ return verifyArrayShift(*this);
+}
+
void hlfir::CShiftOp::getEffects(
llvm::SmallVectorImpl<
mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
@@ -1530,6 +1567,21 @@ void hlfir::CShiftOp::getEffects(
getIntrinsicEffects(getOperation(), effects);
}
+//===----------------------------------------------------------------------===//
+// EOShiftOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult hlfir::EOShiftOp::verify() {
+ return verifyArrayShift(*this);
+}
+
+void hlfir::EOShiftOp::getEffects(
+ llvm::SmallVectorImpl<
+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
+ &effects) {
+ getIntrinsicEffects(getOperation(), effects);
+}
+
//===----------------------------------------------------------------------===//
// ReshapeOp
//===----------------------------------------------------------------------===//
@@ -1543,7 +1595,8 @@ llvm::LogicalResult hlfir::ReshapeOp::verify() {
hlfir::getFortranElementOrSequenceType(array.getType()));
if (auto match = areMatchingTypes(
*this, hlfir::getFortranElementType(resultType),
- arrayType.getElementType(), /*allowCharacterLenMismatch=*/true);
+ arrayType.getElementType(),
+ /*allowCharacterLenMismatch=*/!useStrictIntrinsicVerifier);
match.failed())
return emitOpError("ARRAY and the result must have the same element type");
if (hlfir::isPolymorphicType(resultType) !=
@@ -1565,9 +1618,9 @@ llvm::LogicalResult hlfir::ReshapeOp::verify() {
if (mlir::Value pad = getPad()) {
auto padArrayType = mlir::cast<fir::SequenceType>(
hlfir::getFortranElementOrSequenceType(pad.getType()));
- if (auto match = areMatchingTypes(*this, arrayType.getElementType(),
- padArrayType.getElementType(),
- /*allowCharacterLenMismatch=*/true);
+ if (auto match = areMatchingTypes(
+ *this, arrayType.getElementType(), padArrayType.getElementType(),
+ /*allowCharacterLenMismatch=*/!useStrictIntrinsicVerifier);
match.failed())
return emitOpError("ARRAY and PAD must be of the same type");
}
diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir
index d61efe0062e69..0f54a0250294b 100644
--- a/flang/test/HLFIR/invalid.fir
+++ b/flang/test/HLFIR/invalid.fir
@@ -1555,3 +1555,96 @@ func.func @bad_reshape(%arg0: !hlfir.expr<1x!fir.char<1,2>>, %arg1: !hlfir.expr<
%0 = hlfir.reshape %arg0 %arg1 pad %arg2 : (!hlfir.expr<1x!fir.char<1,2>>, !hlfir.expr<1xi32>, !hlfir.expr<1x!fir.char<2,?>>) -> !hlfir.expr<?x!fir.char<1,?>>
return
}
+
+// -----
+
+func.func @bad_eoshift1(%arg0: !hlfir.expr<?x?xi32>, %arg1: i32) {
+ // expected-error@+1 {{'hlfir.eoshift' op input and output arrays should have the same element type}}
+ %0 = hlfir.eoshift %arg0 %arg1 : (!hlfir.expr<?x?xi32>, i32) -> !hlfir.expr<?x?xf32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift2(%arg0: !hlfir.expr<?x?xi32>, %arg1: i32) {
+ // expected-error@+1 {{'hlfir.eoshift' op input and output arrays should have the same rank}}
+ %0 = hlfir.eoshift %arg0 %arg1 : (!hlfir.expr<?x?xi32>, i32) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift3(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32) {
+ // expected-error@+1 {{'hlfir.eoshift' op output array's shape conflicts with the input array's shape}}
+ %0 = hlfir.eoshift %arg0 %arg1 : (!hlfir.expr<2x2xi32>, i32) -> !hlfir.expr<2x3xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift4(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32) {
+ %c0 = arith.constant 0 : index
+ // expected-error@+1 {{'hlfir.eoshift' op DIM must be >= 1}}
+ %0 = hlfir.eoshift %arg0 %arg1 dim %c0 : (!hlfir.expr<2x2xi32>, i32, index) -> !hlfir.expr<2x2xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift5(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32) {
+ %c10 = arith.constant 10 : index
+ // expected-error@+1 {{'hlfir.eoshift' op DIM must be <= input array's rank}}
+ %0 = hlfir.eoshift %arg0 %arg1 dim %c10 : (!hlfir.expr<2x2xi32>, i32, index) -> !hlfir.expr<2x2xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift6(%arg0: !hlfir.expr<2x2xi32>, %arg1: !hlfir.expr<2x2xi32>) {
+ // expected-error@+1 {{'hlfir.eoshift' op SHIFT's rank must be 1 less than the input array's rank}}
+ %0 = hlfir.eoshift %arg0 %arg1 : (!hlfir.expr<2x2xi32>, !hlfir.expr<2x2xi32>) -> !hlfir.expr<2x2xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift7(%arg0: !hlfir.expr<?x2xi32>, %arg1: !hlfir.expr<3xi32>) {
+ %c1 = arith.constant 1 : index
+ // expected-error@+1 {{'hlfir.eoshift' op SHAPE(ARRAY)(2) must be equal to SHAPE(SHIFT)(1): 2 != 3}}
+ %0 = hlfir.eoshift %arg0 %arg1 dim %c1 : (!hlfir.expr<?x2xi32>, !hlfir.expr<3xi32>, index) -> !hlfir.expr<2x2xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift8(%arg0: !hlfir.expr<?x!fir.char<1,?>>, %arg1: i32) {
+ // expected-error@+2 {{'hlfir.eoshift' op character KIND mismatch}}
+ // expected-error@+1 {{'hlfir.eoshift' op input and output arrays should have the same element type}}
+ %0 = hlfir.eoshift %arg0 %arg1 : (!hlfir.expr<?x!fir.char<1,?>>, i32) -> !hlfir.expr<?x!fir.char<2,?>>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift9(%arg0: !hlfir.expr<?x!fir.char<1,1>>, %arg1: i32) {
+ // expected-error@+2 {{'hlfir.eoshift' op character LEN mismatch}}
+ // expected-error@+1 {{'hlfir.eoshift' op input and output arrays should have the same element type}}
+ %0 = hlfir.eoshift %arg0 %arg1 : (!hlfir.expr<?x!fir.char<1,1>>, i32) -> !hlfir.expr<?x!fir.char<1,2>>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift10(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32, %arg2: f32) {
+ // expected-error@+1 {{'hlfir.eoshift' op ARRAY and BOUNDARY operands must have the same element type}}
+ %0 = hlfir.eoshift %arg0 %arg1 boundary %arg2 : (!hlfir.expr<2x2xi32>, i32, f32) -> !hlfir.expr<2x2xi32>
+ return
+}
+
+// -----
+
+func.func @bad_eoshift11(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32, %arg2: !hlfir.expr<2x2xi32>) {
+ // expected-error@+1 {{'hlfir.eoshift' op BOUNDARY's rank must be 1 less than the input array's rank}}
+ %0 = hlfir.eoshift %arg0 %arg1 boundary %arg2 : (!hlfir.expr<2x2xi32>, i32, !hlfir.expr<2x2xi32>) -> !hlfir.expr<2x2xi32>
+ return
+}
diff --git a/flang/test/Lower/HLFIR/eoshift.f90 b/flang/test/Lower/HLFIR/eoshift.f90
new file mode 100644
index 0000000000000..3b2570ab59365
--- /dev/null
+++ b/flang/test/Lower/HLFIR/eoshift.f90
@@ -0,0 +1,259 @@
+! 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...
[truncated]
|
This PR includes the basic op definition from #153105. |
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.
LGTM, thanks!
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.
Looks good. Thank you.
Straightforward lowering of EOSHIFT intrinsic into the new hlfir.eoshift operation.
The test will start failing at >-O0, when I reland llvm/llvm-project#153106 The bounds checking is not yet supported for HLFIR inlined intrinsics. Related feature request: https://github.com/orgs/llvm/projects/12?pane=issue&itemId=29048733
The test will start failing at >-O0, when I reland llvm/llvm-project#153106 The bounds checking is not yet supported for HLFIR inlined intrinsics. Related feature request: https://github.com/orgs/llvm/projects/12?pane=issue&itemId=29048733
Straightforward lowering of EOSHIFT intrinsic into the new hlfir.eoshift
operation.