forked from OSchip/llvm-project
[flang][CodeGen] Transform `fir.emboxchar` to a sequence of LLVM MLIR
This patch extends the `FIRToLLVMLowering` pass in Flang by adding a hook to transform `fir.emboxchar` 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/D113666 Patch originally written by: Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This commit is contained in:
parent
7bac1985f4
commit
1e77b09538
|
@ -1388,6 +1388,41 @@ struct IsPresentOpConversion : public FIROpConversion<fir::IsPresentOp> {
|
|||
return success();
|
||||
}
|
||||
};
|
||||
|
||||
/// Convert `!fir.emboxchar<!fir.char<KIND, ?>, #n>` into a sequence of
|
||||
/// instructions that generate `!llvm.struct<(ptr<ik>, i64)>`. The 1st element
|
||||
/// in this struct is a pointer. Its type is determined from `KIND`. The 2nd
|
||||
/// element is the length of the character buffer (`#n`).
|
||||
struct EmboxCharOpConversion : public FIROpConversion<fir::EmboxCharOp> {
|
||||
using FIROpConversion::FIROpConversion;
|
||||
|
||||
mlir::LogicalResult
|
||||
matchAndRewrite(fir::EmboxCharOp emboxChar, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||
mlir::ValueRange operands = adaptor.getOperands();
|
||||
MLIRContext *ctx = emboxChar.getContext();
|
||||
|
||||
mlir::Value charBuffer = operands[0];
|
||||
mlir::Value charBufferLen = operands[1];
|
||||
|
||||
mlir::Location loc = emboxChar.getLoc();
|
||||
mlir::Type llvmStructTy = convertType(emboxChar.getType());
|
||||
auto llvmStruct = rewriter.create<mlir::LLVM::UndefOp>(loc, llvmStructTy);
|
||||
|
||||
mlir::Type lenTy =
|
||||
llvmStructTy.cast<mlir::LLVM::LLVMStructType>().getBody()[1];
|
||||
mlir::Value lenAfterCast = integerCast(loc, rewriter, lenTy, charBufferLen);
|
||||
|
||||
auto c0 = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(0));
|
||||
auto c1 = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(1));
|
||||
auto insertBufferOp = rewriter.create<mlir::LLVM::InsertValueOp>(
|
||||
loc, llvmStructTy, llvmStruct, charBuffer, c0);
|
||||
rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
|
||||
emboxChar, llvmStructTy, insertBufferOp, lenAfterCast, c1);
|
||||
|
||||
return success();
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
|
@ -1416,13 +1451,14 @@ public:
|
|||
BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion,
|
||||
BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion,
|
||||
ConvertOpConversion, DispatchOpConversion, DispatchTableOpConversion,
|
||||
DTEntryOpConversion, DivcOpConversion, ExtractValueOpConversion,
|
||||
HasValueOpConversion, GlobalOpConversion, InsertOnRangeOpConversion,
|
||||
InsertValueOpConversion, IsPresentOpConversion, LoadOpConversion,
|
||||
NegcOpConversion, MulcOpConversion, SelectCaseOpConversion,
|
||||
SelectOpConversion, SelectRankOpConversion, StoreOpConversion,
|
||||
SubcOpConversion, UndefOpConversion, UnreachableOpConversion,
|
||||
ZeroOpConversion>(typeConverter);
|
||||
DTEntryOpConversion, DivcOpConversion, EmboxCharOpConversion,
|
||||
ExtractValueOpConversion, HasValueOpConversion, GlobalOpConversion,
|
||||
InsertOnRangeOpConversion, InsertValueOpConversion,
|
||||
IsPresentOpConversion, LoadOpConversion, NegcOpConversion,
|
||||
MulcOpConversion, SelectCaseOpConversion, SelectOpConversion,
|
||||
SelectRankOpConversion, StoreOpConversion, SubcOpConversion,
|
||||
UndefOpConversion, UnreachableOpConversion, ZeroOpConversion>(
|
||||
typeConverter);
|
||||
mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
|
||||
mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
|
||||
pattern);
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix INT64
|
||||
// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT64
|
||||
// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s --check-prefixes INT32
|
||||
// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s --check-prefixes INT64
|
||||
|
||||
//=============================================================================
|
||||
// SUMMARY: Tests for FIR --> LLVM MLIR conversion that *depend* on the target
|
||||
//=============================================================================
|
||||
|
||||
// Test fir.emboxchar
|
||||
|
||||
func @test_embox(%char_array : !fir.ref<!fir.char<1,?>>) -> () {
|
||||
%c10 = arith.constant 10 : i64
|
||||
%box_char = fir.emboxchar %char_array, %c10 : (!fir.ref<!fir.char<1,?>>, i64) -> !fir.boxchar<1>
|
||||
return
|
||||
}
|
||||
|
||||
// INT64-LABEL: test_embox
|
||||
// INT64-SAME: (%[[char_array:.*]]: !llvm.ptr<i8>)
|
||||
// INT64: %[[c10:.*]] = llvm.mlir.constant(10 : i64) : i64
|
||||
// INT64: %[[empty_struct:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i8>, i{{.*}})>
|
||||
// INT64: %[[struct_with_buffer:.*]] = llvm.insertvalue %[[char_array]], %[[empty_struct]][0 : i32] : !llvm.struct<(ptr<i8>, i{{.*}})>
|
||||
// INT64: %{{.*}} = llvm.insertvalue %[[c10]], %[[struct_with_buffer]][1 : i32] : !llvm.struct<(ptr<i8>, i{{.*}})>
|
||||
// INT64-NEXT: llvm.return
|
||||
|
||||
// INT32-LABEL: llvm.func @test_embox
|
||||
// INT32-SAME: %[[char_array:.*]]: !llvm.ptr<i8>)
|
||||
// INT32: %[[c10:.*]] = llvm.mlir.constant(10 : i64) : i64
|
||||
// INT32: %[[empty_struct:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i8>, i32)>
|
||||
// INT32: %[[c10_truncated:.*]] = llvm.trunc %[[c10]] : i64 to i32
|
||||
// INT32: %[[struct_with_buffer:.*]] = llvm.insertvalue %[[char_array]], %[[empty_struct]][0 : i32] : !llvm.struct<(ptr<i8>, i32)>
|
||||
// INT32: %{{.*}} = llvm.insertvalue %[[c10_truncated:.*]], %[[struct_with_buffer]][1 : i32] : !llvm.struct<(ptr<i8>, i32)>
|
||||
// INT32-NEXT: llvm.return
|
|
@ -3,6 +3,9 @@
|
|||
// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=i386-unknown-linux-gnu" %s | FileCheck %s
|
||||
// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=powerpc64le-unknown-linux-gn" %s | FileCheck %s
|
||||
|
||||
//=============================================================================
|
||||
// SUMMARY: Tests for FIR --> LLVM MLIR conversion independent of the target
|
||||
//=============================================================================
|
||||
|
||||
// Test simple global LLVM conversion
|
||||
|
||||
|
|
Loading…
Reference in New Issue