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,38 @@ } }; +/// 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); + } else { + 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; @@ -1521,8 +1553,9 @@ 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 @@ -1200,3 +1200,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>