[flang-commits] [flang] 9d9019c - Revert "[fir] Add fir.convert op conversion from FIR to LLVM IR"
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Tue Nov 9 06:04:11 PST 2021
Author: Valentin Clement
Date: 2021-11-09T15:03:51+01:00
New Revision: 9d9019c77c55b286159a83fc1bf2db2798bfe3c1
URL: https://github.com/llvm/llvm-project/commit/9d9019c77c55b286159a83fc1bf2db2798bfe3c1
DIFF: https://github.com/llvm/llvm-project/commit/9d9019c77c55b286159a83fc1bf2db2798bfe3c1.diff
LOG: Revert "[fir] Add fir.convert op conversion from FIR to LLVM IR"
This reverts commit 165879ec31ed5cc6e4e1a2524c86fc80b81ebbda.
Windows buildbot failure
Added:
Modified:
flang/lib/Optimizer/CodeGen/CodeGen.cpp
flang/lib/Optimizer/CodeGen/TypeConverter.h
flang/test/Fir/convert-to-llvm.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index c81f385f21df..db95017f0ba3 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -96,121 +96,6 @@ struct CallOpConversion : public FIROpConversion<fir::CallOp> {
}
};
-static mlir::Type getComplexEleTy(mlir::Type complex) {
- if (auto cc = complex.dyn_cast<mlir::ComplexType>())
- return cc.getElementType();
- return complex.cast<fir::ComplexType>().getElementType();
-}
-
-/// convert value of from-type to value of to-type
-struct ConvertOpConversion : public FIROpConversion<fir::ConvertOp> {
- using FIROpConversion::FIROpConversion;
-
- static bool isFloatingPointTy(mlir::Type ty) {
- return ty.isa<mlir::FloatType>();
- }
-
- mlir::LogicalResult
- matchAndRewrite(fir::ConvertOp convert, OpAdaptor adaptor,
- mlir::ConversionPatternRewriter &rewriter) const override {
- auto fromTy = convertType(convert.value().getType());
- auto toTy = convertType(convert.res().getType());
- mlir::Value op0 = adaptor.getOperands()[0];
- if (fromTy == toTy) {
- rewriter.replaceOp(convert, op0);
- return success();
- }
- auto loc = convert.getLoc();
- auto convertFpToFp = [&](mlir::Value val, unsigned fromBits,
- unsigned toBits, mlir::Type toTy) -> mlir::Value {
- if (fromBits == toBits) {
- // TODO: Converting between two floating-point representations with the
- // same bitwidth is not allowed for now.
- mlir::emitError(loc,
- "cannot implicitly convert between two floating-point "
- "representations of the same bitwidth");
- return {};
- }
- if (fromBits > toBits)
- return rewriter.create<mlir::LLVM::FPTruncOp>(loc, toTy, val);
- return rewriter.create<mlir::LLVM::FPExtOp>(loc, toTy, val);
- };
- // Complex to complex conversion.
- if (fir::isa_complex(convert.value().getType()) &&
- fir::isa_complex(convert.res().getType())) {
- // Special case: handle the conversion of a complex such that both the
- // real and imaginary parts are converted together.
- auto zero = mlir::ArrayAttr::get(convert.getContext(),
- rewriter.getI32IntegerAttr(0));
- auto one = mlir::ArrayAttr::get(convert.getContext(),
- rewriter.getI32IntegerAttr(1));
- auto ty = convertType(getComplexEleTy(convert.value().getType()));
- auto rp = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, ty, op0, zero);
- auto ip = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, ty, op0, one);
- auto nt = convertType(getComplexEleTy(convert.res().getType()));
- auto fromBits = mlir::LLVM::getPrimitiveTypeSizeInBits(ty);
- auto toBits = mlir::LLVM::getPrimitiveTypeSizeInBits(nt);
- auto rc = convertFpToFp(rp, fromBits, toBits, nt);
- auto ic = convertFpToFp(ip, fromBits, toBits, nt);
- auto un = rewriter.create<mlir::LLVM::UndefOp>(loc, toTy);
- auto i1 =
- rewriter.create<mlir::LLVM::InsertValueOp>(loc, toTy, un, rc, zero);
- rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(convert, toTy, i1,
- ic, one);
- return mlir::success();
- }
- // Floating point to floating point conversion.
- if (isFloatingPointTy(fromTy)) {
- if (isFloatingPointTy(toTy)) {
- auto fromBits = mlir::LLVM::getPrimitiveTypeSizeInBits(fromTy);
- auto toBits = mlir::LLVM::getPrimitiveTypeSizeInBits(toTy);
- auto v = convertFpToFp(op0, fromBits, toBits, toTy);
- rewriter.replaceOp(convert, v);
- return mlir::success();
- }
- if (toTy.isa<mlir::IntegerType>()) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::FPToSIOp>(convert, toTy, op0);
- return mlir::success();
- }
- } else if (fromTy.isa<mlir::IntegerType>()) {
- // Integer to integer conversion.
- if (toTy.isa<mlir::IntegerType>()) {
- auto fromBits = mlir::LLVM::getPrimitiveTypeSizeInBits(fromTy);
- auto toBits = mlir::LLVM::getPrimitiveTypeSizeInBits(toTy);
- assert(fromBits != toBits);
- if (fromBits > toBits) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::TruncOp>(convert, toTy, op0);
- return mlir::success();
- }
- rewriter.replaceOpWithNewOp<mlir::LLVM::SExtOp>(convert, toTy, op0);
- return mlir::success();
- }
- // Integer to floating point conversion.
- if (isFloatingPointTy(toTy)) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::SIToFPOp>(convert, toTy, op0);
- return mlir::success();
- }
- // Integer to pointer conversion.
- if (toTy.isa<mlir::LLVM::LLVMPointerType>()) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::IntToPtrOp>(convert, toTy, op0);
- return mlir::success();
- }
- } else if (fromTy.isa<mlir::LLVM::LLVMPointerType>()) {
- // Pointer to integer conversion.
- if (toTy.isa<mlir::IntegerType>()) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::PtrToIntOp>(convert, toTy, op0);
- return mlir::success();
- }
- // Pointer to pointer conversion.
- if (toTy.isa<mlir::LLVM::LLVMPointerType>()) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(convert, toTy, op0);
- return mlir::success();
- }
- }
- return emitError(loc) << "cannot convert " << fromTy << " to " << toTy;
- }
-};
-
/// Lower `fir.has_value` operation to `llvm.return` operation.
struct HasValueOpConversion : public FIROpConversion<fir::HasValueOp> {
using FIROpConversion::FIROpConversion;
@@ -604,6 +489,12 @@ struct InsertOnRangeOpConversion
}
};
+static mlir::Type getComplexEleTy(mlir::Type complex) {
+ if (auto cc = complex.dyn_cast<mlir::ComplexType>())
+ return cc.getElementType();
+ return complex.cast<fir::ComplexType>().getElementType();
+}
+
//
// Primitive operations on Complex types
//
@@ -788,14 +679,13 @@ class FIRToLLVMLowering : public fir::FIRToLLVMLoweringBase<FIRToLLVMLowering> {
auto *context = getModule().getContext();
fir::LLVMTypeConverter typeConverter{getModule()};
mlir::OwningRewritePatternList pattern(context);
- pattern
- .insert<AddcOpConversion, AddrOfOpConversion, CallOpConversion,
- ConvertOpConversion, DivcOpConversion, ExtractValueOpConversion,
- HasValueOpConversion, GlobalOpConversion,
- InsertOnRangeOpConversion, InsertValueOpConversion,
- NegcOpConversion, MulcOpConversion, SelectOpConversion,
- SelectRankOpConversion, SubcOpConversion, UndefOpConversion,
- UnreachableOpConversion, ZeroOpConversion>(typeConverter);
+ pattern.insert<AddcOpConversion, AddrOfOpConversion, CallOpConversion,
+ DivcOpConversion, ExtractValueOpConversion,
+ HasValueOpConversion, GlobalOpConversion,
+ InsertOnRangeOpConversion, InsertValueOpConversion,
+ NegcOpConversion, MulcOpConversion, SelectOpConversion,
+ SelectRankOpConversion, SubcOpConversion, UndefOpConversion,
+ UnreachableOpConversion, ZeroOpConversion>(typeConverter);
mlir::populateStdToLLVMConversionPatterns(typeConverter, pattern);
mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
pattern);
diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h
index 3f8dda99e97c..f4d252dfc7ee 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.h
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h
@@ -148,6 +148,24 @@ class LLVMTypeConverter : public mlir::LLVMTypeConverter {
/*isPacked=*/false));
}
+ // Use the target specifics to figure out how to map complex to LLVM IR. The
+ // use of complex values in function signatures is handled before conversion
+ // to LLVM IR dialect here.
+ //
+ // fir.complex<T> | std.complex<T> --> llvm<"{t,t}">
+ template <typename C>
+ mlir::Type convertComplexType(C cmplx) {
+ LLVM_DEBUG(llvm::dbgs() << "type convert: " << cmplx << '\n');
+ auto eleTy = cmplx.getElementType();
+ return convertType(specifics->complexMemoryType(eleTy));
+ }
+
+ // convert a front-end kind value to either a std or LLVM IR dialect type
+ // fir.real<n> --> llvm.anyfloat where anyfloat is a kind mapping
+ mlir::Type convertRealType(fir::KindTy kind) {
+ return fromRealTypeID(kindMapping.getRealTypeID(kind), kind);
+ }
+
template <typename A>
mlir::Type convertPointerLike(A &ty) {
mlir::Type eleTy = ty.getEleTy();
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index b33a2294b3e3..cafac1de4e13 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -514,121 +514,3 @@ func @fir_complex_neg(%a: !fir.complex<16>) -> !fir.complex<16> {
// CHECK: %{{.*}} = llvm.insertvalue %[[NEGX]], %{{.*}}[0 : i32] : !llvm.struct<(f128, f128)>
// CHECK: %{{.*}} = llvm.insertvalue %[[NEGY]], %{{.*}}[1 : i32] : !llvm.struct<(f128, f128)>
// CHECK: llvm.return %{{.*}} : !llvm.struct<(f128, f128)>
-
-// -----
-
-// Test `fir.convert` operation conversion from Float type.
-
-func @convert_from_float(%arg0 : f32) {
- %0 = fir.convert %arg0 : (f32) -> f16
- %1 = fir.convert %arg0 : (f32) -> f32
- %2 = fir.convert %arg0 : (f32) -> f64
- %3 = fir.convert %arg0 : (f32) -> f80
- %4 = fir.convert %arg0 : (f32) -> f128
- %5 = fir.convert %arg0 : (f32) -> i1
- %6 = fir.convert %arg0 : (f32) -> i8
- %7 = fir.convert %arg0 : (f32) -> i16
- %8 = fir.convert %arg0 : (f32) -> i32
- %9 = fir.convert %arg0 : (f32) -> i64
- return
-}
-
-// CHECK-LABEL: convert_from_float(
-// CHECK-SAME: %[[ARG0:.*]]: f32
-// CHECK: %{{.*}} = llvm.fptrunc %[[ARG0]] : f32 to f16
-// CHECK-NOT: f32 to f32
-// CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f64
-// CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f80
-// CHECK: %{{.*}} = llvm.fpext %[[ARG0]] : f32 to f128
-// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i1
-// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i8
-// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i16
-// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i32
-// CHECK: %{{.*}} = llvm.fptosi %[[ARG0]] : f32 to i64
-
-// -----
-
-// Test `fir.convert` operation conversion from Integer type.
-
-func @convert_from_int(%arg0 : i32) {
- %0 = fir.convert %arg0 : (i32) -> f16
- %1 = fir.convert %arg0 : (i32) -> f32
- %2 = fir.convert %arg0 : (i32) -> f64
- %3 = fir.convert %arg0 : (i32) -> f80
- %4 = fir.convert %arg0 : (i32) -> f128
- %5 = fir.convert %arg0 : (i32) -> i1
- %6 = fir.convert %arg0 : (i32) -> i8
- %7 = fir.convert %arg0 : (i32) -> i16
- %8 = fir.convert %arg0 : (i32) -> i32
- %9 = fir.convert %arg0 : (i32) -> i64
- %10 = fir.convert %arg0 : (i32) -> i64
- %ptr = fir.convert %10 : (i64) -> !fir.ref<i64>
- return
-}
-
-// CHECK-LABEL: convert_from_int(
-// CHECK-SAME: %[[ARG0:.*]]: i32
-// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f16
-// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f32
-// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f64
-// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f80
-// CHECK: %{{.*}} = llvm.sitofp %[[ARG0]] : i32 to f128
-// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i1
-// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i8
-// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i16
-// CHECK-NOT: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i32
-// CHECK: %{{.*}} = llvm.sext %[[ARG0]] : i32 to i64
-// CHECK: %{{.*}} = llvm.inttoptr %{{.*}} : i64 to !llvm.ptr<i64>
-
-// -----
-
-// Test `fir.convert` operation conversion from !fir.ref<> type.
-
-func @convert_from_ref(%arg0 : !fir.ref<i32>) {
- %0 = fir.convert %arg0 : (!fir.ref<i32>) -> !fir.ref<i8>
- %1 = fir.convert %arg0 : (!fir.ref<i32>) -> i32
- return
-}
-
-// CHECK-LABEL: convert_from_ref(
-// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr<i32>
-// CHECK: %{{.*}} = llvm.bitcast %[[ARG0]] : !llvm.ptr<i32> to !llvm.ptr<i8>
-// CHECK: %{{.*}} = llvm.ptrtoint %[[ARG0]] : !llvm.ptr<i32> to i32
-
-// -----
-
-// Test `fir.convert` operation conversion between fir.complex types.
-
-func @convert_complex4(%arg0 : !fir.complex<4>) -> !fir.complex<8> {
- %0 = fir.convert %arg0 : (!fir.complex<4>) -> !fir.complex<8>
- return %0 : !fir.complex<8>
-}
-
-// CHECK-LABEL: func @convert_complex4(
-// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f32, f32)>) -> !llvm.struct<(f64, f64)>
-// CHECK: %[[X:.*]] = llvm.extractvalue %[[ARG0]][0 : i32] : !llvm.struct<(f32, f32)>
-// CHECK: %[[Y:.*]] = llvm.extractvalue %[[ARG0]][1 : i32] : !llvm.struct<(f32, f32)>
-// CHECK: %[[CONVERTX:.*]] = llvm.fpext %[[X]] : f32 to f64
-// CHECK: %[[CONVERTY:.*]] = llvm.fpext %[[Y]] : f32 to f64
-// CHECK: %[[STRUCT0:.*]] = llvm.mlir.undef : !llvm.struct<(f64, f64)>
-// CHECK: %[[STRUCT1:.*]] = llvm.insertvalue %[[CONVERTX]], %[[STRUCT0]][0 : i32] : !llvm.struct<(f64, f64)>
-// CHECK: %[[STRUCT2:.*]] = llvm.insertvalue %[[CONVERTY]], %[[STRUCT1]][1 : i32] : !llvm.struct<(f64, f64)>
-// CHECK: llvm.return %[[STRUCT2]] : !llvm.struct<(f64, f64)>
-
-// Test `fir.convert` operation conversion between fir.complex types.
-
-func @convert_complex16(%arg0 : !fir.complex<16>) -> !fir.complex<2> {
- %0 = fir.convert %arg0 : (!fir.complex<16>) -> !fir.complex<2>
- return %0 : !fir.complex<2>
-}
-
-// CHECK-LABEL: func @convert_complex16(
-// CHECK-SAME: %[[ARG0:.*]]: !llvm.struct<(f128, f128)>) -> !llvm.struct<(f16, f16)>
-// CHECK: %[[X:.*]] = llvm.extractvalue %[[ARG0]][0 : i32] : !llvm.struct<(f128, f128)>
-// CHECK: %[[Y:.*]] = llvm.extractvalue %[[ARG0]][1 : i32] : !llvm.struct<(f128, f128)>
-// CHECK: %[[CONVERTX:.*]] = llvm.fptrunc %[[X]] : f128 to f16
-// CHECK: %[[CONVERTY:.*]] = llvm.fptrunc %[[Y]] : f128 to f16
-// CHECK: %[[STRUCT0:.*]] = llvm.mlir.undef : !llvm.struct<(f16, f16)>
-// CHECK: %[[STRUCT1:.*]] = llvm.insertvalue %[[CONVERTX]], %[[STRUCT0]][0 : i32] : !llvm.struct<(f16, f16)>
-// CHECK: %[[STRUCT2:.*]] = llvm.insertvalue %[[CONVERTY]], %[[STRUCT1]][1 : i32] : !llvm.struct<(f16, f16)>
-// CHECK: llvm.return %[[STRUCT2]] : !llvm.struct<(f16, f16)>
More information about the flang-commits
mailing list