-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
[flang] Inline hlfir.cshift as hlfir.elemental. #119480
Conversation
@llvm/pr-subscribers-flang-fir-hlfir Author: Slava Zakharin (vzakhari) ChangesPatch is 29.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119480.diff 2 Files Affected:
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp
index b61f9767ccc2b8..0bd8af5475a81b 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp
@@ -13,6 +13,7 @@
#include "flang/Optimizer/Builder/Complex.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Builder/IntrinsicCall.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
@@ -331,6 +332,107 @@ class SumAsElementalConversion : public mlir::OpRewritePattern<hlfir::SumOp> {
}
};
+class CShiftAsElementalConversion
+ : public mlir::OpRewritePattern<hlfir::CShiftOp> {
+public:
+ using mlir::OpRewritePattern<hlfir::CShiftOp>::OpRewritePattern;
+
+ explicit CShiftAsElementalConversion(mlir::MLIRContext *ctx)
+ : OpRewritePattern(ctx) {
+ setHasBoundedRewriteRecursion();
+ }
+
+ llvm::LogicalResult
+ matchAndRewrite(hlfir::CShiftOp cshift,
+ mlir::PatternRewriter &rewriter) const override {
+ using Fortran::common::maxRank;
+
+ mlir::Location loc = cshift.getLoc();
+ fir::FirOpBuilder builder{rewriter, cshift.getOperation()};
+ hlfir::ExprType expr = mlir::dyn_cast<hlfir::ExprType>(cshift.getType());
+ assert(expr && "expected an expression type for the result of hlfir.sum");
+ mlir::Type elementType = expr.getElementType();
+ hlfir::Entity array = hlfir::Entity{cshift.getArray()};
+ mlir::Value arrayShape = hlfir::genShape(loc, builder, array);
+ llvm::SmallVector<mlir::Value> arrayExtents =
+ hlfir::getExplicitExtentsFromShape(arrayShape, builder);
+ unsigned arrayRank = expr.getRank();
+ llvm::SmallVector<mlir::Value, 1> typeParams;
+ hlfir::genLengthParameters(loc, builder, array, typeParams);
+ hlfir::Entity shift = hlfir::Entity{cshift.getShift()};
+ // The new index computation involves MODULO, which is not implemented
+ // for IndexType, so use I64 instead.
+ mlir::Type calcType = builder.getI64Type();
+
+ mlir::Value one = builder.createIntegerConstant(loc, calcType, 1);
+ mlir::Value shiftVal;
+ if (shift.isScalar()) {
+ shiftVal = hlfir::loadTrivialScalar(loc, builder, shift);
+ shiftVal = builder.createConvert(loc, calcType, shiftVal);
+ }
+
+ int64_t dimVal = 1;
+ if (arrayRank == 1) {
+ // When it is a 1D CSHIFT, we may assume that the DIM argument
+ // (whether it is present or absent) is equal to 1, otherwise,
+ // the program is illegal.
+ assert(shiftVal && "SHIFT must be scalar");
+ } else {
+ if (mlir::Value dim = cshift.getDim())
+ dimVal = fir::getIntIfConstant(dim).value_or(0);
+ assert(dimVal > 0 && dimVal <= arrayRank &&
+ "DIM must be present and a positive constant not exceeding "
+ "the array's rank");
+ }
+
+ auto genKernel = [&](mlir::Location loc, fir::FirOpBuilder &builder,
+ mlir::ValueRange inputIndices) -> hlfir::Entity {
+ llvm::SmallVector<mlir::Value, maxRank> indices{inputIndices};
+ if (!shift.isScalar()) {
+ // When the array is not a vector, section
+ // (s(1), s(2), ..., s(dim-1), :, s(dim+1), ..., s(n)
+ // of the result has a value equal to:
+ // CSHIFT(ARRAY(s(1), s(2), ..., s(dim-1), :, s(dim+1), ..., s(n)),
+ // SH, 1),
+ // where SH is either SHIFT (if scalar) or
+ // SHIFT(s(1), s(2), ..., s(dim-1), s(dim+1), ..., s(n)).
+ llvm::SmallVector<mlir::Value, maxRank> shiftIndices{indices};
+ shiftIndices.erase(shiftIndices.begin() + dimVal - 1);
+ hlfir::Entity shiftElement =
+ hlfir::getElementAt(loc, builder, shift, shiftIndices);
+ shiftVal = hlfir::loadTrivialScalar(loc, builder, shiftElement);
+ shiftVal = builder.createConvert(loc, calcType, shiftVal);
+ }
+
+ // Element i of the result (1-based) is element
+ // 'MODULO(i + SH - 1, SIZE(ARRAY)) + 1' (1-based) of the original
+ // ARRAY (or its section, when ARRAY is not a vector).
+ mlir::Value index =
+ builder.createConvert(loc, calcType, inputIndices[dimVal - 1]);
+ mlir::Value extent = arrayExtents[dimVal - 1];
+ mlir::Value newIndex =
+ builder.create<mlir::arith::AddIOp>(loc, index, shiftVal);
+ newIndex = builder.create<mlir::arith::SubIOp>(loc, newIndex, one);
+ newIndex = fir::IntrinsicLibrary{builder, loc}.genModulo(
+ calcType, {newIndex, builder.createConvert(loc, calcType, extent)});
+ newIndex = builder.create<mlir::arith::AddIOp>(loc, newIndex, one);
+ newIndex = builder.createConvert(loc, builder.getIndexType(), newIndex);
+
+ indices[dimVal - 1] = newIndex;
+ hlfir::Entity element = hlfir::getElementAt(loc, builder, array, indices);
+ return hlfir::loadTrivialScalar(loc, builder, element);
+ };
+
+ hlfir::ElementalOp elementalOp = hlfir::genElementalOp(
+ loc, builder, elementType, arrayShape, typeParams, genKernel,
+ /*isUnordered=*/true,
+ array.isPolymorphic() ? static_cast<mlir::Value>(array) : nullptr,
+ cshift.getResult().getType());
+ rewriter.replaceOp(cshift, elementalOp);
+ return mlir::success();
+ }
+};
+
class SimplifyHLFIRIntrinsics
: public hlfir::impl::SimplifyHLFIRIntrinsicsBase<SimplifyHLFIRIntrinsics> {
public:
@@ -339,6 +441,7 @@ class SimplifyHLFIRIntrinsics
mlir::RewritePatternSet patterns(context);
patterns.insert<TransposeAsElementalConversion>(context);
patterns.insert<SumAsElementalConversion>(context);
+ patterns.insert<CShiftAsElementalConversion>(context);
mlir::ConversionTarget target(*context);
// don't transform transpose of polymorphic arrays (not currently supported
// by hlfir.elemental)
@@ -375,6 +478,24 @@ class SimplifyHLFIRIntrinsics
}
return true;
});
+ target.addDynamicallyLegalOp<hlfir::CShiftOp>([](hlfir::CShiftOp cshift) {
+ unsigned resultRank = hlfir::Entity{cshift}.getRank();
+ if (resultRank == 1)
+ return false;
+
+ mlir::Value dim = cshift.getDim();
+ if (!dim)
+ return false;
+
+ // If DIM is present, then it must be constant to please
+ // the conversion. In addition, ignore cases with
+ // illegal DIM values.
+ if (auto dimVal = fir::getIntIfConstant(dim))
+ if (*dimVal > 0 && *dimVal <= resultRank)
+ return false;
+
+ return true;
+ });
target.markUnknownOpDynamicallyLegal(
[](mlir::Operation *) { return true; });
if (mlir::failed(mlir::applyFullConversion(getOperation(), target,
diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir
new file mode 100644
index 00000000000000..acb89c0719aa08
--- /dev/null
+++ b/flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir
@@ -0,0 +1,304 @@
+// Test hlfir.cshift simplification to hlfir.elemental:
+// RUN: fir-opt --simplify-hlfir-intrinsics %s | FileCheck %s
+
+func.func @cshift_vector(%arg0: !fir.box<!fir.array<?xi32>>, %arg1: !fir.ref<i32>) {
+ %res = hlfir.cshift %arg0 %arg1 : (!fir.box<!fir.array<?xi32>>, !fir.ref<i32>) -> !hlfir.expr<?xi32>
+ return
+}
+// CHECK-LABEL: func.func @cshift_vector(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_5:.*]] = arith.constant 1 : i64
+// CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64
+// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
+// CHECK: ^bb0(%[[VAL_9:.*]]: index):
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i64
+// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_10]], %[[VAL_7]] : i64
+// CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_11]], %[[VAL_5]] : i64
+// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64
+// CHECK: %[[VAL_14:.*]] = arith.remsi %[[VAL_12]], %[[VAL_13]] : i64
+// CHECK: %[[VAL_15:.*]] = arith.xori %[[VAL_12]], %[[VAL_13]] : i64
+// CHECK: %[[VAL_16:.*]] = arith.constant 0 : i64
+// CHECK: %[[VAL_17:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_16]] : i64
+// CHECK: %[[VAL_18:.*]] = arith.cmpi ne, %[[VAL_14]], %[[VAL_16]] : i64
+// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_18]], %[[VAL_17]] : i1
+// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_14]], %[[VAL_13]] : i64
+// CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_19]], %[[VAL_20]], %[[VAL_14]] : i64
+// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_21]], %[[VAL_5]] : i64
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index
+// CHECK: %[[VAL_24:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_24]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_26:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_25]]#0, %[[VAL_26]] : index
+// CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_23]], %[[VAL_27]] : index
+// CHECK: %[[VAL_29:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_28]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK: %[[VAL_30:.*]] = fir.load %[[VAL_29]] : !fir.ref<i32>
+// CHECK: hlfir.yield_element %[[VAL_30]] : i32
+// CHECK: }
+// CHECK: return
+// CHECK: }
+
+func.func @cshift_2d_by_scalar(%arg0: !fir.box<!fir.array<?x?xi32>>, %arg1: !fir.ref<i32>) {
+ %dim = arith.constant 2 : i32
+ %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box<!fir.array<?x?xi32>>, !fir.ref<i32>, i32) -> !hlfir.expr<?x?xi32>
+ return
+}
+// CHECK-LABEL: func.func @cshift_2d_by_scalar(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK: %[[VAL_2:.*]] = arith.constant 2 : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]]#1, %[[VAL_6]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64
+// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64
+// CHECK: %[[VAL_11:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xi32> {
+// CHECK: ^bb0(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index):
+// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (index) -> i64
+// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_14]], %[[VAL_10]] : i64
+// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_15]], %[[VAL_8]] : i64
+// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_6]]#1 : (index) -> i64
+// CHECK: %[[VAL_18:.*]] = arith.remsi %[[VAL_16]], %[[VAL_17]] : i64
+// CHECK: %[[VAL_19:.*]] = arith.xori %[[VAL_16]], %[[VAL_17]] : i64
+// CHECK: %[[VAL_20:.*]] = arith.constant 0 : i64
+// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_19]], %[[VAL_20]] : i64
+// CHECK: %[[VAL_22:.*]] = arith.cmpi ne, %[[VAL_18]], %[[VAL_20]] : i64
+// CHECK: %[[VAL_23:.*]] = arith.andi %[[VAL_22]], %[[VAL_21]] : i1
+// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_18]], %[[VAL_17]] : i64
+// CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_23]], %[[VAL_24]], %[[VAL_18]] : i64
+// CHECK: %[[VAL_26:.*]] = arith.addi %[[VAL_25]], %[[VAL_8]] : i64
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i64) -> index
+// CHECK: %[[VAL_28:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_29:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_28]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_30:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_31:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_30]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_32:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_29]]#0, %[[VAL_32]] : index
+// CHECK: %[[VAL_34:.*]] = arith.addi %[[VAL_12]], %[[VAL_33]] : index
+// CHECK: %[[VAL_35:.*]] = arith.subi %[[VAL_31]]#0, %[[VAL_32]] : index
+// CHECK: %[[VAL_36:.*]] = arith.addi %[[VAL_27]], %[[VAL_35]] : index
+// CHECK: %[[VAL_37:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_34]], %[[VAL_36]]) : (!fir.box<!fir.array<?x?xi32>>, index, index) -> !fir.ref<i32>
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_37]] : !fir.ref<i32>
+// CHECK: hlfir.yield_element %[[VAL_38]] : i32
+// CHECK: }
+// CHECK: return
+// CHECK: }
+
+func.func @cshift_2d_by_vector(%arg0: !fir.box<!fir.array<?x?xi32>>, %arg1: !fir.box<!fir.array<?xi32>>) {
+ %dim = arith.constant 2 : i32
+ %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box<!fir.array<?x?xi32>>, !fir.box<!fir.array<?xi32>>, i32) -> !hlfir.expr<?x?xi32>
+ return
+}
+// CHECK-LABEL: func.func @cshift_2d_by_vector(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x?xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>) {
+// CHECK: %[[VAL_2:.*]] = arith.constant 2 : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]]#1, %[[VAL_6]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64
+// CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<2>) -> !hlfir.expr<?x?xi32> {
+// CHECK: ^bb0(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index):
+// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_12]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_14]] : index
+// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_10]], %[[VAL_15]] : index
+// CHECK: %[[VAL_17:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_16]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+// CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_17]] : !fir.ref<i32>
+// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64
+// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_11]] : (index) -> i64
+// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_20]], %[[VAL_19]] : i64
+// CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_8]] : i64
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_6]]#1 : (index) -> i64
+// CHECK: %[[VAL_24:.*]] = arith.remsi %[[VAL_22]], %[[VAL_23]] : i64
+// CHECK: %[[VAL_25:.*]] = arith.xori %[[VAL_22]], %[[VAL_23]] : i64
+// CHECK: %[[VAL_26:.*]] = arith.constant 0 : i64
+// CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i64
+// CHECK: %[[VAL_28:.*]] = arith.cmpi ne, %[[VAL_24]], %[[VAL_26]] : i64
+// CHECK: %[[VAL_29:.*]] = arith.andi %[[VAL_28]], %[[VAL_27]] : i1
+// CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_24]], %[[VAL_23]] : i64
+// CHECK: %[[VAL_31:.*]] = arith.select %[[VAL_29]], %[[VAL_30]], %[[VAL_24]] : i64
+// CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_31]], %[[VAL_8]] : i64
+// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (i64) -> index
+// CHECK: %[[VAL_34:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_35:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_34]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_36:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_37:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_36]] : (!fir.box<!fir.array<?x?xi32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_38:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_39:.*]] = arith.subi %[[VAL_35]]#0, %[[VAL_38]] : index
+// CHECK: %[[VAL_40:.*]] = arith.addi %[[VAL_10]], %[[VAL_39]] : index
+// CHECK: %[[VAL_41:.*]] = arith.subi %[[VAL_37]]#0, %[[VAL_38]] : index
+// CHECK: %[[VAL_42:.*]] = arith.addi %[[VAL_33]], %[[VAL_41]] : index
+// CHECK: %[[VAL_43:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_40]], %[[VAL_42]]) : (!fir.box<!fir.array<?x?xi32>>, index, index) -> !fir.ref<i32>
+// CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_43]] : !fir.ref<i32>
+// CHECK: hlfir.yield_element %[[VAL_44]] : i32
+// CHECK: }
+// CHECK: return
+// CHECK: }
+
+func.func @cshift_vector_char(%arg0: !fir.box<!fir.array<?x!fir.char<2,?>>>, %arg1: !fir.ref<i32>) {
+ %res = hlfir.cshift %arg0 %arg1 : (!fir.box<!fir.array<?x!fir.char<2,?>>>, !fir.ref<i32>) -> !hlfir.expr<?x!fir.char<2,?>>
+ return
+}
+// CHECK-LABEL: func.func @cshift_vector_char(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<2,?>>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x!fir.char<2,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_5:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<2,?>>>) -> index
+// CHECK: %[[VAL_6:.*]] = arith.constant 2 : index
+// CHECK: %[[VAL_7:.*]] = arith.divsi %[[VAL_5]], %[[VAL_6]] : index
+// CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64
+// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64
+// CHECK: %[[VAL_11:.*]] = hlfir.elemental %[[VAL_4]] typeparams %[[VAL_7]] unordered : (!fir.shape<1>, index) -> !hlfir.expr<?x!fir.char<2,?>> {
+// CHECK: ^bb0(%[[VAL_12:.*]]: index):
+// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (index) -> i64
+// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_13]], %[[VAL_10]] : i64
+// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_14]], %[[VAL_8]] : i64
+// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64
+// CHECK: %[[VAL_17:.*]] = arith.remsi %[[VAL_15]], %[[VAL_16]] : i64
+// CHECK: %[[VAL_18:.*]] = arith.xori %[[VAL_15]], %[[VAL...
[truncated]
|
@@ -375,6 +478,24 @@ class SimplifyHLFIRIntrinsics | |||
} | |||
return true; | |||
}); | |||
target.addDynamicallyLegalOp<hlfir::CShiftOp>([](hlfir::CShiftOp cshift) { |
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.
I think it would be easier to turn this pass into a greedy conversion, and check all the conditions in the patterns themselves. If there are no objections, I will clean it up in a separate NFC patch.
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!
mlir::Location loc = cshift.getLoc(); | ||
fir::FirOpBuilder builder{rewriter, cshift.getOperation()}; | ||
hlfir::ExprType expr = mlir::dyn_cast<hlfir::ExprType>(cshift.getType()); | ||
assert(expr && "expected an expression type for the result of hlfir.sum"); |
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.
assert(expr && "expected an expression type for the result of hlfir.sum"); | |
assert(expr && "expected an expression type for the result of hlfir.cshift"); |
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 great!
There is no support for `-fbounds-check` in Flang yet. There is a related feature request at https://github.com/orgs/llvm/projects/12?pane=issue&itemId=29048733 Until then, the optimizations may replace the Fortran runtime calls (which usually provide all the error checking) with inline sequences that do not check for errors to provide the fast code (e.g. llvm/llvm-project#119480). For the time being I would like to explicitly pass `-O0` to these tests.
* [Fortran/gfortran] Use -O0 for cshift_bounds_[34]. There is no support for `-fbounds-check` in Flang yet. There is a related feature request at https://github.com/orgs/llvm/projects/12?pane=issue&itemId=29048733 Until then, the optimizations may replace the Fortran runtime calls (which usually provide all the error checking) with inline sequences that do not check for errors to provide the fast code (e.g. llvm/llvm-project#119480). For the time being I would like to explicitly pass `-O0` to these tests. * Disabled tests. * Reverted tests.cmake
This is breaking |
Sorry for the inconvenience. This should be resolved by llvm/llvm-test-suite#191 |
No description provided.