[fir] Add fir.string_lit conversion

This patch adds the conversion pattern for
the fir.string_lit operation.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: awarzynski

Differential Revision: https://reviews.llvm.org/D113992

Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
This commit is contained in:
Valentin Clement 2021-11-16 20:37:08 +01:00
parent 8d85e945b2
commit 1a2ec6670a
No known key found for this signature in database
GPG Key ID: 086D54783C928776
2 changed files with 64 additions and 10 deletions

View File

@ -465,6 +465,39 @@ struct BoxRankOpConversion : public FIROpConversion<fir::BoxRankOp> {
}
};
/// Lower `fir.string_lit` to LLVM IR dialect operation.
struct StringLitOpConversion : public FIROpConversion<fir::StringLitOp> {
using FIROpConversion::FIROpConversion;
mlir::LogicalResult
matchAndRewrite(fir::StringLitOp constop, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
auto ty = convertType(constop.getType());
auto attr = constop.getValue();
if (attr.isa<mlir::StringAttr>()) {
rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(constop, ty, attr);
return success();
}
auto arr = attr.cast<mlir::ArrayAttr>();
auto charTy = constop.getType().cast<fir::CharacterType>();
unsigned bits = lowerTy().characterBitsize(charTy);
mlir::Type intTy = rewriter.getIntegerType(bits);
auto attrs = llvm::map_range(
arr.getValue(), [intTy, bits](mlir::Attribute attr) -> Attribute {
return mlir::IntegerAttr::get(
intTy,
attr.cast<mlir::IntegerAttr>().getValue().sextOrTrunc(bits));
});
mlir::Type vecType = mlir::VectorType::get(arr.size(), intTy);
auto denseAttr = mlir::DenseElementsAttr::get(
vecType.cast<mlir::ShapedType>(), llvm::to_vector<8>(attrs));
rewriter.replaceOpWithNewOp<mlir::arith::ConstantOp>(constop, ty,
denseAttr);
return success();
}
};
// `fir.call` -> `llvm.call`
struct CallOpConversion : public FIROpConversion<fir::CallOp> {
using FIROpConversion::FIROpConversion;
@ -1592,19 +1625,20 @@ public:
mlir::OwningRewritePatternList pattern(context);
pattern.insert<
AbsentOpConversion, AddcOpConversion, AddrOfOpConversion,
AllocaOpConversion, BoxAddrOpConversion, BoxCharLenOpConversion, BoxDimsOpConversion,
BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion,
BoxIsPtrOpConversion, BoxRankOpConversion, CallOpConversion,
CmpcOpConversion, ConvertOpConversion, DispatchOpConversion,
DispatchTableOpConversion, DTEntryOpConversion, DivcOpConversion,
EmboxCharOpConversion, ExtractValueOpConversion, HasValueOpConversion,
GenTypeDescOpConversion, GlobalLenOpConversion, GlobalOpConversion,
InsertOnRangeOpConversion, InsertValueOpConversion,
AllocaOpConversion, BoxAddrOpConversion, BoxCharLenOpConversion,
BoxDimsOpConversion, BoxEleSizeOpConversion, BoxIsAllocOpConversion,
BoxIsArrayOpConversion, BoxIsPtrOpConversion, BoxRankOpConversion,
CallOpConversion, CmpcOpConversion, ConvertOpConversion,
DispatchOpConversion, DispatchTableOpConversion, DTEntryOpConversion,
DivcOpConversion, EmboxCharOpConversion, ExtractValueOpConversion,
HasValueOpConversion, GenTypeDescOpConversion, GlobalLenOpConversion,
GlobalOpConversion, InsertOnRangeOpConversion, InsertValueOpConversion,
IsPresentOpConversion, LoadOpConversion, NegcOpConversion,
MulcOpConversion, SelectCaseOpConversion, SelectOpConversion,
SelectRankOpConversion, SelectTypeOpConversion, StoreOpConversion,
SubcOpConversion, UnboxCharOpConversion, UndefOpConversion,
UnreachableOpConversion, ZeroOpConversion>(typeConverter);
StringLitOpConversion, SubcOpConversion, UnboxCharOpConversion,
UndefOpConversion, UnreachableOpConversion, ZeroOpConversion>(
typeConverter);
mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
pattern);

View File

@ -1251,3 +1251,23 @@ func @absent() -> i1 {
// CHECK-NEXT: %[[ptr:.*]] = llvm.mlir.null : !llvm.ptr<i64>
// CHECK-NEXT: %[[ret_val:.*]] = llvm.call @is_present(%[[ptr]]) : (!llvm.ptr<i64>) -> i1
// CHECK-NEXT: llvm.return %[[ret_val]] : i1
// -----
// Test `fir.string_lit` conversion.
func @string_lit0() {
%1 = fir.string_lit "Hello, World!"(13) : !fir.char<1>
return
}
// CHECK-LABEL: llvm.func @string_lit0
// CHECK: %{{.*}} = llvm.mlir.constant("Hello, World!") : !llvm.array<13 x i8>
func @string_lit1() {
%2 = fir.string_lit [158, 2345](2) : !fir.char<2>
return
}
// CHECK-LABEL: llvm.func @string_lit1
// %{{.*}} = llvm.mlir.constant(dense<[158, 2345]> : vector<2xi16>) : !llvm.array<2 x i16>