diff options
author | Diana Picus <diana.picus@linaro.org> | 2021-11-16 09:07:51 +0000 |
---|---|---|
committer | Diana Picus <diana.picus@linaro.org> | 2021-11-18 08:46:10 +0000 |
commit | e81d73ed92336c607ac7c2aeec75f5cec873f2d1 (patch) | |
tree | b8d6482c6a94a683b46e119ebedde4f2a7ef421e | |
parent | 54c99842079997b0fe208acdab01e540c0d81b51 (diff) | |
download | llvm-e81d73ed92336c607ac7c2aeec75f5cec873f2d1.tar.gz |
[fir] Add fir.constc conversion
Add the codegen for fir.constc.
This patch is part of the upstreaming effort from fir-dev.
Differential Revision: https://reviews.llvm.org/D114063
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
-rw-r--r-- | flang/lib/Optimizer/CodeGen/CodeGen.cpp | 55 | ||||
-rw-r--r-- | flang/test/Fir/convert-to-llvm.fir | 32 |
2 files changed, 76 insertions, 11 deletions
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 4e12005777b4..92139d33da56 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -586,6 +586,38 @@ struct CmpcOpConversion : public FIROpConversion<fir::CmpcOp> { } }; +/// Lower complex constants +struct ConstcOpConversion : public FIROpConversion<fir::ConstcOp> { + using FIROpConversion::FIROpConversion; + + mlir::LogicalResult + matchAndRewrite(fir::ConstcOp conc, OpAdaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + mlir::Location loc = conc.getLoc(); + mlir::MLIRContext *ctx = conc.getContext(); + mlir::Type ty = convertType(conc.getType()); + mlir::Type ety = convertType(getComplexEleTy(conc.getType())); + auto realFloatAttr = mlir::FloatAttr::get(ety, getValue(conc.getReal())); + auto realPart = + rewriter.create<mlir::LLVM::ConstantOp>(loc, ety, realFloatAttr); + auto imFloatAttr = mlir::FloatAttr::get(ety, getValue(conc.getImaginary())); + auto imPart = + rewriter.create<mlir::LLVM::ConstantOp>(loc, ety, imFloatAttr); + auto realIndex = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(0)); + auto imIndex = mlir::ArrayAttr::get(ctx, rewriter.getI32IntegerAttr(1)); + auto undef = rewriter.create<mlir::LLVM::UndefOp>(loc, ty); + auto setReal = rewriter.create<mlir::LLVM::InsertValueOp>( + loc, ty, undef, realPart, realIndex); + rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(conc, ty, setReal, + imPart, imIndex); + return success(); + } + + inline APFloat getValue(mlir::Attribute attr) const { + return attr.cast<fir::RealAttr>().getValue(); + } +}; + /// convert value of from-type to value of to-type struct ConvertOpConversion : public FIROpConversion<fir::ConvertOp> { using FIROpConversion::FIROpConversion; @@ -1685,17 +1717,18 @@ public: BoxDimsOpConversion, BoxEleSizeOpConversion, BoxIsAllocOpConversion, BoxIsArrayOpConversion, BoxIsPtrOpConversion, BoxRankOpConversion, BoxTypeDescOpConversion, CallOpConversion, CmpcOpConversion, - ConvertOpConversion, DispatchOpConversion, DispatchTableOpConversion, - DTEntryOpConversion, DivcOpConversion, EmboxCharOpConversion, - ExtractValueOpConversion, HasValueOpConversion, GenTypeDescOpConversion, - GlobalLenOpConversion, GlobalOpConversion, InsertOnRangeOpConversion, - InsertValueOpConversion, IsPresentOpConversion, LoadOpConversion, - NegcOpConversion, MulcOpConversion, SelectCaseOpConversion, - SelectOpConversion, SelectRankOpConversion, SelectTypeOpConversion, - ShapeOpConversion, ShapeShiftOpConversion, ShiftOpConversion, - SliceOpConversion, StoreOpConversion, StringLitOpConversion, - SubcOpConversion, UnboxCharOpConversion, UndefOpConversion, - UnreachableOpConversion, ZeroOpConversion>(typeConverter); + ConstcOpConversion, ConvertOpConversion, DispatchOpConversion, + DispatchTableOpConversion, DTEntryOpConversion, DivcOpConversion, + EmboxCharOpConversion, ExtractValueOpConversion, HasValueOpConversion, + GenTypeDescOpConversion, GlobalLenOpConversion, GlobalOpConversion, + InsertOnRangeOpConversion, InsertValueOpConversion, + IsPresentOpConversion, LoadOpConversion, NegcOpConversion, + MulcOpConversion, SelectCaseOpConversion, SelectOpConversion, + SelectRankOpConversion, SelectTypeOpConversion, ShapeOpConversion, + ShapeShiftOpConversion, ShiftOpConversion, SliceOpConversion, + StoreOpConversion, 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 index 8465063312c8..8d0b8235b18f 100644 --- a/flang/test/Fir/convert-to-llvm.fir +++ b/flang/test/Fir/convert-to-llvm.fir @@ -690,6 +690,38 @@ func @convert_complex16(%arg0 : !fir.complex<16>) -> !fir.complex<2> { // ----- +// Test constc. + +func @test_constc4() -> !fir.complex<4> { + %0 = fir.constc (#fir.real<4, 1.4>, #fir.real<4, 2.3>) : !fir.complex<4> + return %0 : !fir.complex<4> +} + +// CHECK-LABEL: @test_constc4 +// CHECK_SAME: () -> !llvm.struct<(f32, f32)> +// CHECK-DAG: [[rp:%.*]] = llvm.mlir.constant(1.400000e+00 : f32) : f32 +// CHECK-DAG: [[ip:%.*]] = llvm.mlir.constant(2.300000e+00 : f32) : f32 +// CHECK: [[undef:%.*]] = llvm.mlir.undef : !llvm.struct<(f32, f32)> +// CHECK: [[withr:%.*]] = llvm.insertvalue [[rp]], [[undef]][0 : i32] : !llvm.struct<(f32, f32)> +// CHECK: [[full:%.*]] = llvm.insertvalue [[ip]], [[withr]][1 : i32] : !llvm.struct<(f32, f32)> +// CHECK: return [[full]] : !llvm.struct<(f32, f32)> + +func @test_constc8() -> !fir.complex<8> { + %0 = fir.constc (#fir.real<8, 1.8>, #fir.real<8, 2.3>) : !fir.complex<8> + return %0 : !fir.complex<8> +} + +// CHECK-LABEL: @test_constc8 +// CHECK_SAME: () -> !llvm.struct<(f64, f64)> +// CHECK-DAG: [[rp:%.*]] = llvm.mlir.constant(1.800000e+00 : f64) : f64 +// CHECK-DAG: [[ip:%.*]] = llvm.mlir.constant(2.300000e+00 : f64) : f64 +// CHECK: [[undef:%.*]] = llvm.mlir.undef : !llvm.struct<(f64, f64)> +// CHECK: [[withr:%.*]] = llvm.insertvalue [[rp]], [[undef]][0 : i32] : !llvm.struct<(f64, f64)> +// CHECK: [[full:%.*]] = llvm.insertvalue [[ip]], [[withr]][1 : i32] : !llvm.struct<(f64, f64)> +// CHECK: return [[full]] : !llvm.struct<(f64, f64)> + +// ----- + // Test `fir.store` --> `llvm.store` conversion func @test_store_index(%val_to_store : index, %addr : !fir.ref<index>) { |