[flang-commits] [flang] [FIR] add a fir.shape_extents operation (PR #199361)
via flang-commits
flang-commits at lists.llvm.org
Mon Jun 8 09:19:05 PDT 2026
================
@@ -4577,12 +4577,98 @@ struct MustBeDeadConversion : public fir::FIROpConversion<FromOp> {
}
};
-struct ShapeOpConversion : public MustBeDeadConversion<fir::ShapeOp> {
- using MustBeDeadConversion::MustBeDeadConversion;
+// Shape can now be lowered into an llvm struct
+struct ShapeOpConversion : public fir::FIROpConversion<fir::ShapeOp> {
+ using FIROpConversion::FIROpConversion;
+
+ llvm::LogicalResult
+ matchAndRewrite(fir::ShapeOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const override {
+ if (op->use_empty()) {
+ rewriter.eraseOp(op);
+ return mlir::success();
+ }
+ auto loc = op.getLoc();
+ auto shapeTy = mlir::cast<fir::ShapeType>(op.getType());
+ mlir::Type llvmShapeTy = convertType(shapeTy);
+ mlir::Type i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
+ mlir::Value structVal =
+ mlir::LLVM::UndefOp::create(rewriter, loc, llvmShapeTy);
+ for (auto [i, extent] : llvm::enumerate(adaptor.getExtents())) {
+ mlir::Value extentI64 =
+ integerCast(loc, rewriter, i64Ty, extent, /*fold=*/true);
+ structVal = mlir::LLVM::InsertValueOp::create(rewriter, loc, structVal,
+ extentI64, i);
+ }
+ rewriter.replaceOp(op, structVal);
+ return mlir::success();
+ }
};
-struct ShapeShiftOpConversion : public MustBeDeadConversion<fir::ShapeShiftOp> {
- using MustBeDeadConversion::MustBeDeadConversion;
+struct ShapeExtentsOpConversion
+ : public fir::FIROpConversion<fir::ShapeExtentsOp> {
+ using FIROpConversion::FIROpConversion;
+
+ llvm::LogicalResult
+ matchAndRewrite(fir::ShapeExtentsOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const override {
+ auto loc = op.getLoc();
+
+ mlir::Type ty = op.getShape().getType();
+ unsigned rank;
+ if (auto shapeTy = mlir::dyn_cast<fir::ShapeType>(ty))
+ rank = shapeTy.getRank();
+ else if (auto ssTy = mlir::dyn_cast<fir::ShapeShiftType>(ty))
+ rank = ssTy.getRank();
+ else
+ return mlir::failure();
+ if (rank != op.getNumResults())
+ return mlir::failure();
+
+ mlir::Type i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
+ mlir::Value llvmShape = adaptor.getShape();
+ llvm::SmallVector<mlir::Value> results;
+ for (unsigned i = 0; i < op.getNumResults(); ++i) {
+ mlir::Value extentI64 = mlir::LLVM::ExtractValueOp::create(
+ rewriter, loc, i64Ty, llvmShape, i);
+ mlir::Type resultTy = convertType(op.getExtents()[i].getType());
+ results.push_back(
+ integerCast(loc, rewriter, resultTy, extentI64, /*fold=*/true));
+ }
+ rewriter.replaceOp(op, results);
+ return mlir::success();
+ }
+};
+
+struct ShapeShiftOpConversion : public fir::FIROpConversion<fir::ShapeShiftOp> {
+ using FIROpConversion::FIROpConversion;
+
+ llvm::LogicalResult
+ matchAndRewrite(fir::ShapeShiftOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const override {
+ if (op->use_empty()) {
+ rewriter.eraseOp(op);
+ return mlir::success();
+ }
+ auto loc = op.getLoc();
+ auto ssTy = mlir::cast<fir::ShapeShiftType>(op.getType());
+ mlir::Type llvmTy = convertType(ssTy);
+ mlir::Type i64Ty = mlir::IntegerType::get(rewriter.getContext(), 64);
+ mlir::Value structVal =
+ mlir::LLVM::UndefOp::create(rewriter, loc, llvmTy);
+ // Pack extent operands only; lower bounds are not part of the LLVM shape
+ // bundle consumed by fir.shape_extents.
+ for (auto [i, extent] : llvm::enumerate(adaptor.getPairs())) {
+ if (i & 1)
+ continue;
+ mlir::Value extentI64 =
+ integerCast(loc, rewriter, i64Ty, extent, /*fold=*/true);
+ structVal = mlir::LLVM::InsertValueOp::create(rewriter, loc, structVal,
+ extentI64, i / 2);
+ }
+ rewriter.replaceOp(op, structVal);
+ return mlir::success();
+ }
----------------
jeanPerier wrote:
Can you add some codegen lit tests for the three new patterns?
https://github.com/llvm/llvm-project/pull/199361
More information about the flang-commits
mailing list