forked from OSchip/llvm-project
[flang][CodeGen] Transform `fir.boxchar_len` to a sequence of LLVM MLIR
This patch extends the `FIRToLLVMLowering` pass in Flang by adding a hook to transform `fir.boxchar_len` to a sequence of LLVM MLIR instructions. This is part of the upstreaming effort from the `fir-dev` branch in [1]. [1] https://github.com/flang-compiler/f18-llvm-project Differential Revision: https://reviews.llvm.org/D113763 Originally written by: Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This commit is contained in:
parent
aa9bbb64be
commit
6c3d7fd4c5
|
@ -1517,6 +1517,29 @@ genExtractValueWithIndex(mlir::Location loc, mlir::Value tuple, mlir::Type ty,
|
||||||
return rewriter.create<mlir::LLVM::ExtractValueOp>(loc, xty, tuple, cx);
|
return rewriter.create<mlir::LLVM::ExtractValueOp>(loc, xty, tuple, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert `!fir.boxchar_len` to `!llvm.extractvalue` for the 2nd part of the
|
||||||
|
/// boxchar.
|
||||||
|
struct BoxCharLenOpConversion : public FIROpConversion<fir::BoxCharLenOp> {
|
||||||
|
using FIROpConversion::FIROpConversion;
|
||||||
|
|
||||||
|
mlir::LogicalResult
|
||||||
|
matchAndRewrite(fir::BoxCharLenOp boxCharLen, OpAdaptor adaptor,
|
||||||
|
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||||
|
mlir::Value boxChar = adaptor.getOperands()[0];
|
||||||
|
mlir::Location loc = boxChar.getLoc();
|
||||||
|
mlir::MLIRContext *ctx = boxChar.getContext();
|
||||||
|
mlir::Type returnValTy = boxCharLen.getResult().getType();
|
||||||
|
|
||||||
|
constexpr int boxcharLenIdx = 1;
|
||||||
|
mlir::LLVM::ExtractValueOp len = genExtractValueWithIndex(
|
||||||
|
loc, boxChar, boxChar.getType(), rewriter, ctx, boxcharLenIdx);
|
||||||
|
mlir::Value lenAfterCast = integerCast(loc, rewriter, returnValTy, len);
|
||||||
|
rewriter.replaceOp(boxCharLen, lenAfterCast);
|
||||||
|
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Convert `fir.unboxchar` into two `llvm.extractvalue` instructions. One for
|
/// Convert `fir.unboxchar` into two `llvm.extractvalue` instructions. One for
|
||||||
/// the character buffer and one for the buffer length.
|
/// the character buffer and one for the buffer length.
|
||||||
struct UnboxCharOpConversion : public FIROpConversion<fir::UnboxCharOp> {
|
struct UnboxCharOpConversion : public FIROpConversion<fir::UnboxCharOp> {
|
||||||
|
@ -1569,7 +1592,7 @@ public:
|
||||||
mlir::OwningRewritePatternList pattern(context);
|
mlir::OwningRewritePatternList pattern(context);
|
||||||
pattern.insert<
|
pattern.insert<
|
||||||
AbsentOpConversion, AddcOpConversion, AddrOfOpConversion,
|
AbsentOpConversion, AddcOpConversion, AddrOfOpConversion,
|
||||||
AllocaOpConversion, BoxAddrOpConversion, BoxDimsOpConversion,
|
AllocaOpConversion, BoxAddrOpConversion, BoxCharLenOpConversion, BoxDimsOpConversion,
|
||||||
BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion,
|
BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion,
|
||||||
BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion,
|
BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion,
|
||||||
CmpcOpConversion, ConvertOpConversion, DispatchOpConversion,
|
CmpcOpConversion, ConvertOpConversion, DispatchOpConversion,
|
||||||
|
|
|
@ -71,3 +71,79 @@ func @unboxchar_i32(%arg0 : !fir.boxchar<4>) -> () {
|
||||||
// INT32: %[[len_unextended:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
|
// INT32: %[[len_unextended:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
|
||||||
// INT32: %{{.*}} = llvm.sext %[[len_unextended]] : i32 to i64
|
// INT32: %{{.*}} = llvm.sext %[[len_unextended]] : i32 to i64
|
||||||
// INT32-NEXT: llvm.return
|
// INT32-NEXT: llvm.return
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
// Test fir.boxchar_len
|
||||||
|
|
||||||
|
func @boxchar_len_i8_i32(%arg0 : !fir.boxchar<1>) -> () {
|
||||||
|
fir.boxchar_len %arg0 : (!fir.boxchar<1>) -> i32
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// INT64-LABEL: llvm.func @boxchar_len_i8_i32
|
||||||
|
// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i64)>
|
||||||
|
// INT64: %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i64)>
|
||||||
|
// INT64: %{{.*}} = llvm.trunc %[[len]] : i64 to i32
|
||||||
|
// INT64-NEXT: llvm.return
|
||||||
|
|
||||||
|
// INT32-LABEL: llvm.func @boxchar_len_i8_i32
|
||||||
|
// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i32)>
|
||||||
|
// INT32: %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i32)>
|
||||||
|
// INT32-NOT: llvm.trunc
|
||||||
|
// INT32-NOT: llvm.sext
|
||||||
|
// INT32-NEXT: llvm.return
|
||||||
|
|
||||||
|
func @boxchar_len_i8_i64(%arg0 : !fir.boxchar<1>) -> () {
|
||||||
|
fir.boxchar_len %arg0 : (!fir.boxchar<1>) -> i64
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// INT64-LABEL: llvm.func @boxchar_len_i8_i64
|
||||||
|
// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i64)>
|
||||||
|
// INT64: %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i64)>
|
||||||
|
// INT64-NOT: llvm.trunc
|
||||||
|
// INT64-NOT: llvm.sext
|
||||||
|
// INT64-NEXT: llvm.return
|
||||||
|
|
||||||
|
// INT32-LABEL: llvm.func @boxchar_len_i8_i64
|
||||||
|
// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i8>, i32)>
|
||||||
|
// INT32: %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i8>, i32)>
|
||||||
|
// INT32: %{{.*}} = llvm.sext %0 : i32 to i64
|
||||||
|
// INT32-NEXT: llvm.return
|
||||||
|
|
||||||
|
func @boxchar_len_i32_i32(%arg0 : !fir.boxchar<4>) -> () {
|
||||||
|
fir.boxchar_len %arg0 : (!fir.boxchar<4>) -> i32
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// INT64-LABEL: llvm.func @boxchar_len_i32_i32
|
||||||
|
// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i64)>
|
||||||
|
// INT64: %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i64)>
|
||||||
|
// INT64: %{{.*}} = llvm.trunc %[[len]] : i64 to i32
|
||||||
|
// INT64-NEXT: llvm.return
|
||||||
|
|
||||||
|
// INT32-LABEL: llvm.func @boxchar_len_i32_i32
|
||||||
|
// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i32)>
|
||||||
|
// INT32: %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
|
||||||
|
// INT32-NOT: llvm.trunc
|
||||||
|
// INT32-NOT: llvm.sext
|
||||||
|
// INT32-NEXT: llvm.return
|
||||||
|
|
||||||
|
func @boxchar_len_i32_i64(%arg0 : !fir.boxchar<4>) -> (i64) {
|
||||||
|
%0 = fir.boxchar_len %arg0 : (!fir.boxchar<4>) -> i64
|
||||||
|
return %0 : i64
|
||||||
|
}
|
||||||
|
|
||||||
|
// INT64-LABEL: llvm.func @boxchar_len_i32_i64
|
||||||
|
// INT64-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i64)>
|
||||||
|
// INT64: %{{.*}} = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i64)>
|
||||||
|
// INT64-NOT: llvm.trunc
|
||||||
|
// INT64-NOT: llvm.sext
|
||||||
|
// INT64-NEXT: llvm.return
|
||||||
|
|
||||||
|
// INT32-LABEL: llvm.func @boxchar_len_i32_i64
|
||||||
|
// INT32-SAME: %[[box_char:.*]]: !llvm.struct<(ptr<i32>, i32)>
|
||||||
|
// INT32: %[[len:.*]] = llvm.extractvalue %[[box_char]][1 : i32] : !llvm.struct<(ptr<i32>, i32)>
|
||||||
|
// INT32: %{{.*}} = llvm.sext %0 : i32 to i64
|
||||||
|
// INT32-NEXT: llvm.return
|
||||||
|
|
Loading…
Reference in New Issue