summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2021-11-16 09:07:51 +0000
committerDiana Picus <diana.picus@linaro.org>2021-11-18 08:46:10 +0000
commite81d73ed92336c607ac7c2aeec75f5cec873f2d1 (patch)
treeb8d6482c6a94a683b46e119ebedde4f2a7ef421e
parent54c99842079997b0fe208acdab01e540c0d81b51 (diff)
downloadllvm-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.cpp55
-rw-r--r--flang/test/Fir/convert-to-llvm.fir32
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>) {