diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -465,6 +465,39 @@ } }; +/// Lower `fir.string_lit` to LLVM IR dialect operation. +struct StringLitOpConversion : public FIROpConversion { + 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()) { + rewriter.replaceOpWithNewOp(constop, ty, attr); + return success(); + } + + auto arr = attr.cast(); + auto charTy = constop.getType().cast(); + 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().getValue().sextOrTrunc(bits)); + }); + mlir::Type vecType = mlir::VectorType::get(arr.size(), intTy); + auto denseAttr = mlir::DenseElementsAttr::get( + vecType.cast(), llvm::to_vector<8>(attrs)); + rewriter.replaceOpWithNewOp(constop, ty, + denseAttr); + return success(); + } +}; + // `fir.call` -> `llvm.call` struct CallOpConversion : public FIROpConversion { using FIROpConversion::FIROpConversion; @@ -1592,19 +1625,20 @@ 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); diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir --- a/flang/test/Fir/convert-to-llvm.fir +++ b/flang/test/Fir/convert-to-llvm.fir @@ -1251,3 +1251,23 @@ // CHECK-NEXT: %[[ptr:.*]] = llvm.mlir.null : !llvm.ptr // CHECK-NEXT: %[[ret_val:.*]] = llvm.call @is_present(%[[ptr]]) : (!llvm.ptr) -> 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>