[flang-commits] [flang] [flang] Inline hlfir.cshift as hlfir.elemental. (PR #119480)
via flang-commits
flang-commits at lists.llvm.org
Tue Dec 10 17:06:12 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Slava Zakharin (vzakhari)
<details>
<summary>Changes</summary>
---
Patch is 29.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119480.diff
2 Files Affected:
- (modified) flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp (+121)
- (added) flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir (+304)
``````````diff
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/119480
More information about the flang-commits
mailing list