Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR] Add support for long double type #536

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,36 @@ def CIR_Double : CIR_FloatType<"Double", "double"> {
}];
}

def CIR_FP80 : CIR_FloatType<"FP80", "f80"> {
let summary = "CIR type that represents x87 80-bit floating-point format";
let description = [{
Floating-point type that represents the x87 80-bit floating-point format.
}];
}

def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
let summary = "CIR extended-precision float type";
let description = [{
Floating-point type that represents the `long double` type in C/C++.

The underlying floating-point format of a long double value depends on the
implementation. The `underlying` parameter specifies the CIR floating-point
type that corresponds to this format. For now, it can only be either
`!cir.double` or `!cir.fp80`.
}];

let parameters = (ins "mlir::Type":$underlying);

let assemblyFormat = [{
`<` $underlying `>`
}];

let genVerifyDecl = 1;
}

// Constraints

def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double]>;
def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_LongDouble]>;
def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>;

//===----------------------------------------------------------------------===//
Expand Down
27 changes: 8 additions & 19 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,29 +373,18 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy {
}
bool isInt(mlir::Type i) { return i.isa<mlir::cir::IntType>(); }

mlir::Type getLongDouble80BitsTy() const { llvm_unreachable("NYI"); }

/// Get the proper floating point type for the given semantics.
mlir::Type getFloatTyForFormat(const llvm::fltSemantics &format,
bool useNativeHalf) const {
if (&format == &llvm::APFloat::IEEEhalf()) {
llvm_unreachable("IEEEhalf float format is NYI");
}

if (&format == &llvm::APFloat::BFloat())
llvm_unreachable("BFloat float format is NYI");
if (&format == &llvm::APFloat::IEEEsingle())
return typeCache.FloatTy;
mlir::cir::LongDoubleType
getLongDoubleTy(const llvm::fltSemantics &format) const {
if (&format == &llvm::APFloat::IEEEdouble())
return typeCache.DoubleTy;
return mlir::cir::LongDoubleType::get(getContext(), typeCache.DoubleTy);
if (&format == &llvm::APFloat::x87DoubleExtended())
return mlir::cir::LongDoubleType::get(getContext(), typeCache.FP80Ty);
if (&format == &llvm::APFloat::IEEEquad())
llvm_unreachable("IEEEquad float format is NYI");
llvm_unreachable("NYI");
if (&format == &llvm::APFloat::PPCDoubleDouble())
llvm_unreachable("PPCDoubleDouble float format is NYI");
if (&format == &llvm::APFloat::x87DoubleExtended())
return getLongDouble80BitsTy();
llvm_unreachable("NYI");

llvm_unreachable("Unknown float format!");
llvm_unreachable("unsupported long double format");
}

mlir::Type getVirtualFnPtrType(bool isVarArg = false) {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
// TODO: BFloatTy
FloatTy = ::mlir::cir::SingleType::get(builder.getContext());
DoubleTy = ::mlir::cir::DoubleType::get(builder.getContext());
FP80Ty = ::mlir::cir::FP80Type::get(builder.getContext());
// TODO(cir): perhaps we should abstract long double variations into a custom
// cir.long_double type. Said type would also hold the semantics for lowering.

Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenTypeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct CIRGenTypeCache {
// cir.long_double type. Said type would also hold the semantics for lowering.
mlir::cir::SingleType FloatTy;
mlir::cir::DoubleType DoubleTy;
mlir::cir::FP80Type FP80Ty;

/// int
mlir::Type UIntTy;
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,7 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
ResultType = CGM.DoubleTy;
break;
case BuiltinType::LongDouble:
ResultType = Builder.getFloatTyForFormat(Context.getFloatTypeSemantics(T),
/*useNativeHalf=*/false);
ResultType = Builder.getLongDoubleTy(Context.getFloatTypeSemantics(T));
break;
case BuiltinType::Float128:
case BuiltinType::Ibm128:
Expand Down
61 changes: 61 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,67 @@ DoubleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
return (uint64_t)(getWidth() / 8);
}

const llvm::fltSemantics &FP80Type::getFloatSemantics() const {
return llvm::APFloat::x87DoubleExtended();
}

llvm::TypeSize
FP80Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return llvm::TypeSize::getFixed(16);
}

uint64_t FP80Type::getABIAlignment(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return 16;
}

uint64_t
FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout,
::mlir::DataLayoutEntryListRef params) const {
return 16;
}

const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const {
return getUnderlying()
.cast<mlir::cir::CIRFPTypeInterface>()
.getFloatSemantics();
}

llvm::TypeSize
LongDoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return getUnderlying()
.cast<mlir::DataLayoutTypeInterface>()
.getTypeSizeInBits(dataLayout, params);
}

uint64_t
LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return getUnderlying().cast<mlir::DataLayoutTypeInterface>().getABIAlignment(
dataLayout, params);
}

uint64_t LongDoubleType::getPreferredAlignment(
const ::mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
return getUnderlying()
.cast<mlir::DataLayoutTypeInterface>()
.getPreferredAlignment(dataLayout, params);
}

LogicalResult
LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError,
mlir::Type underlying) {
if (!underlying.isa<DoubleType, FP80Type>()) {
emitError() << "invalid underlying type for long double";
return failure();
}

return success();
}

//===----------------------------------------------------------------------===//
// FuncType Definitions
//===----------------------------------------------------------------------===//
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3008,6 +3008,12 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
converter.addConversion([&](mlir::cir::DoubleType type) -> mlir::Type {
return mlir::FloatType::getF64(type.getContext());
});
converter.addConversion([&](mlir::cir::FP80Type type) -> mlir::Type {
return mlir::FloatType::getF80(type.getContext());
bcardosolopes marked this conversation as resolved.
Show resolved Hide resolved
});
converter.addConversion([&](mlir::cir::LongDoubleType type) -> mlir::Type {
return converter.convertType(type.getUnderlying());
});
converter.addConversion([&](mlir::cir::FuncType type) -> mlir::Type {
auto result = converter.convertType(type.getReturnType());
llvm::SmallVector<mlir::Type> arguments;
Expand Down
Loading
Loading