[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>
This commit is contained in:
Diana Picus 2021-11-16 09:07:51 +00:00
parent 54c9984207
commit e81d73ed92
2 changed files with 76 additions and 11 deletions

View File

@ -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);

View File

@ -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>) {