https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/120484
>From b76111ab93253a772156992e70acb5c78511a6bf Mon Sep 17 00:00:00 2001 From: David Olsen <dol...@nvidia.com> Date: Wed, 18 Dec 2024 13:52:58 -0800 Subject: [PATCH 1/3] [CIR] floating-point, pointer, and function types Upstream ClangIR support for `void` type, floating-point types, pointer types, and function types. Floating-point support is missing the IBM double-double format, because that hasn't been implemented in the incubator project yet. Pointer types do not yet support address spaces. Function type support includes only the return type and the parameter types. The many other properties and attributes of function types will be upstreamed later. --- clang/include/clang/CIR/CMakeLists.txt | 1 + .../CIR/Dialect/Builder/CIRBaseBuilder.h | 8 + clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 7 + .../include/clang/CIR/Dialect/IR/CIRTypes.td | 221 ++++++++++++++ .../clang/CIR/Interfaces/CIRFPTypeInterface.h | 22 ++ .../CIR/Interfaces/CIRFPTypeInterface.td | 52 ++++ .../clang/CIR/Interfaces/CMakeLists.txt | 14 + clang/lib/CIR/CMakeLists.txt | 1 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 12 + clang/lib/CIR/CodeGen/CIRGenModule.cpp | 7 + clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 11 + clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 143 +++++++++ clang/lib/CIR/CodeGen/CIRGenTypes.h | 9 + clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 280 ++++++++++++++++++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + .../lib/CIR/Interfaces/CIRFPTypeInterface.cpp | 14 + clang/lib/CIR/Interfaces/CMakeLists.txt | 14 + clang/test/CIR/global-var-simple.cpp | 39 +++ 19 files changed, 857 insertions(+) create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td create mode 100644 clang/include/clang/CIR/Interfaces/CMakeLists.txt create mode 100644 clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp create mode 100644 clang/lib/CIR/Interfaces/CMakeLists.txt diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index f8d6f407a03d02..e20c896171c928 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -4,3 +4,4 @@ include_directories(${MLIR_INCLUDE_DIR}) include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) add_subdirectory(Dialect) +add_subdirectory(Interfaces) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 75ae74e926fbc6..0e414921324b7f 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -18,6 +18,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { public: CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + + cir::PointerType getPointerTo(mlir::Type ty) { + return cir::PointerType::get(getContext(), ty); + } + + cir::PointerType getVoidPtrTy() { + return getPointerTo(cir::VoidType::get(getContext())); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2bc7d77b2bc8a3..5d1eb17e146d03 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -16,6 +16,13 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +namespace cir { + +bool isAnyFloatingPointType(mlir::Type t); + +} // namespace cir //===----------------------------------------------------------------------===// // CIR Dialect Tablegen'd Types diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index ce0b6ba1d68c55..ef00b26c1fd98c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -14,6 +14,7 @@ #define MLIR_CIR_DIALECT_CIR_TYPES include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Interfaces/CIRFPTypeInterface.td" include "mlir/Interfaces/DataLayoutInterfaces.td" include "mlir/IR/AttrTypeBase.td" @@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], "primitive int", "::cir::IntType">; +//===----------------------------------------------------------------------===// +// FloatType +//===----------------------------------------------------------------------===// + +class CIR_FloatType<string name, string mnemonic> + : CIR_Type<name, mnemonic, + [ + DeclareTypeInterfaceMethods<DataLayoutTypeInterface>, + DeclareTypeInterfaceMethods<CIRFPTypeInterface>, + ]> {} + +def CIR_Single : CIR_FloatType<"Single", "float"> { + let summary = "CIR single-precision 32-bit float type"; + let description = [{ + A 32-bit floating-point type whose format is IEEE-754 `binary32`. It + represents the types `float`, `_Float32`, and `std::float32_t` in C and C++. + }]; +} + +def CIR_Double : CIR_FloatType<"Double", "double"> { + let summary = "CIR double-precision 64-bit float type"; + let description = [{ + A 64-bit floating-point type whose format is IEEE-754 `binary64`. It + represents the types `double', '_Float64`, `std::float64_t`, and `_Float32x` + in C and C++. This is the underlying type for `long double` on some + platforms, including Windows. + }]; +} + +def CIR_FP16 : CIR_FloatType<"FP16", "f16"> { + let summary = "CIR half-precision 16-bit float type"; + let description = [{ + A 16-bit floating-point type whose format is IEEE-754 `binary16`. It + represents the types '_Float16` and `std::float16_t` in C and C++. + }]; +} + +def CIR_BFloat16 : CIR_FloatType<"BF16", "bf16"> { + let summary = "CIR bfloat16 16-bit float type"; + let description = [{ + A 16-bit floating-point type in the bfloat16 format, which is the same as + IEEE `binary32` except that the lower 16 bits of the mantissa are missing. + It represents the type `std::bfloat16_t` in C++, also spelled `__bf16` in + some implementations. + }]; +} + +def CIR_FP80 : CIR_FloatType<"FP80", "f80"> { + let summary = "CIR x87 80-bit float type"; + let description = [{ + An 80-bit floating-point type in the x87 extended precision format. The + size and alignment of the type are both 128 bits, even though only 80 of + those bits are used. This is the underlying type for `long double` on Linux + x86 platforms, and it is available as an extension in some implementations. + }]; +} + +def CIR_FP128 : CIR_FloatType<"FP128", "f128"> { + let summary = "CIR quad-precision 128-bit float type"; + let description = [{ + A 128-bit floating-point type whose format is IEEE-754 `binary128`. It + represents the types `_Float128` and `std::float128_t` in C and C++, and the + extension `__float128` in some implementations. This is the underlying type + for `long double` on some platforms including Linux Arm. + }]; +} + +def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { + let summary = "CIR float type for `long double`"; + let description = [{ + A floating-point type that represents the `long double` type in C and C++. + + The underlying floating-point format of a `long double` value depends on the + target platform and the implementation. The `underlying` parameter specifies + the CIR floating-point type that corresponds to this format. Underlying + types of IEEE 64-bit, IEEE 128-bit, x87 80-bit, and IBM's double-double + format are all in use. + }]; + + let parameters = (ins "mlir::Type":$underlying); + + let assemblyFormat = [{ + `<` $underlying `>` + }]; + + let genVerifyDecl = 1; +} + +// Constraints + +def CIR_AnyFloat: AnyTypeOf<[CIR_Single, CIR_Double, CIR_FP80, CIR_FP128, CIR_LongDouble, + CIR_FP16, CIR_BFloat16]>; +def CIR_AnyIntOrFloat: AnyTypeOf<[CIR_AnyFloat, CIR_IntType]>; + +//===----------------------------------------------------------------------===// +// PointerType +//===----------------------------------------------------------------------===// + +def CIR_PointerType : CIR_Type<"Pointer", "ptr", + [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { + + let summary = "CIR pointer type"; + let description = [{ + The `cir.ptr` type represents C and C++ pointer types and C++ reference + types, other than pointers-to-members. The `pointee` type is the type + pointed to. + + TODO(CIR): The address space attribute is not yet implemented. + }]; + + let parameters = (ins "mlir::Type":$pointee); + + let builders = [ + TypeBuilderWithInferredContext<(ins "mlir::Type":$pointee), [{ + return $_get(pointee.getContext(), pointee); + }]>, + TypeBuilder<(ins "mlir::Type":$pointee), [{ + return $_get($_ctxt, pointee); + }]> + ]; + + let assemblyFormat = [{ + `<` $pointee `>` + }]; + + let genVerifyDecl = 1; + + let skipDefaultBuilders = 1; + + let extraClassDeclaration = [{ + bool isVoidPtr() const { + return mlir::isa<cir::VoidType>(getPointee()); + } + }]; +} + +//===----------------------------------------------------------------------===// +// FuncType +//===----------------------------------------------------------------------===// + +def CIR_FuncType : CIR_Type<"Func", "func"> { + let summary = "CIR function type"; + let description = [{ + The `!cir.func` is a function type. It consists of a single return type, a + list of parameter types and can optionally be variadic. + + Example: + + ```mlir + !cir.func<!bool ()> + !cir.func<!s32i (!s8i, !s8i)> + !cir.func<!s32i (!s32i, ...)> + ``` + }]; + + let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, + "mlir::Type":$returnType, "bool":$varArg); + let assemblyFormat = [{ + `<` $returnType ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>` + }]; + + let builders = [ + TypeBuilderWithInferredContext<(ins + "llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType, + CArg<"bool", "false">:$isVarArg), [{ + return $_get(returnType.getContext(), inputs, returnType, isVarArg); + }]> + ]; + + let extraClassDeclaration = [{ + /// Returns whether the function is variadic. + bool isVarArg() const { return getVarArg(); } + + /// Returns the `i`th input operand type. Asserts if out of bounds. + mlir::Type getInput(unsigned i) const { return getInputs()[i]; } + + /// Returns the number of arguments to the function. + unsigned getNumInputs() const { return getInputs().size(); } + + /// Returns the result type of the function as an ArrayRef, enabling better + /// integration with generic MLIR utilities. + llvm::ArrayRef<mlir::Type> getReturnTypes() const; + + /// Returns whether the function is returns void. + bool isVoid() const; + + /// Returns a clone of this function type with the given argument + /// and result types. + FuncType clone(mlir::TypeRange inputs, mlir::TypeRange results) const; + }]; +} + +//===----------------------------------------------------------------------===// +// Void type +//===----------------------------------------------------------------------===// + +def CIR_VoidType : CIR_Type<"Void", "void"> { + let summary = "CIR void type"; + let description = [{ + The `!cir.void` type represents the C and C++ `void` type. + }]; + let extraClassDeclaration = [{ + std::string getAlias() const { return "void"; }; + }]; +} + +// Constraints + +// Pointer to void +def VoidPtr : Type< + And<[ + CPred<"::mlir::isa<::cir::PointerType>($_self)">, + CPred<"::mlir::isa<::cir::VoidType>(" + "::mlir::cast<::cir::PointerType>($_self).getPointee())">, + ]>, "void*">, + BuildableType< + "cir::PointerType::get($_builder.getContext()," + "cir::VoidType::get($_builder.getContext()))"> { +} + #endif // MLIR_CIR_DIALECT_CIR_TYPES diff --git a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h new file mode 100644 index 00000000000000..40b85ef6cfb626 --- /dev/null +++ b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h @@ -0,0 +1,22 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// +// +// Defines the interface to generically handle CIR floating-point types. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_H +#define LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_H + +#include "mlir/IR/Types.h" +#include "llvm/ADT/APFloat.h" + +/// Include the tablegen'd interface declarations. +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h.inc" + +#endif // LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_H diff --git a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td new file mode 100644 index 00000000000000..33ad0fc1aa53cb --- /dev/null +++ b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td @@ -0,0 +1,52 @@ +//===- CIRFPTypeInterface.td - CIR FP Interface Definitions -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD +#define LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD + +include "mlir/IR/OpBase.td" + +def CIRFPTypeInterface : TypeInterface<"CIRFPTypeInterface"> { + let description = [{ + Contains helper functions to query properties about a floating-point type. + }]; + let cppNamespace = "::cir"; + + let methods = [ + InterfaceMethod<[{ + Returns the bit width of this floating-point type. + }], + /*retTy=*/"unsigned", + /*methodName=*/"getWidth", + /*args=*/(ins), + /*methodBody=*/"", + /*defaultImplementation=*/[{ + return llvm::APFloat::semanticsSizeInBits($_type.getFloatSemantics()); + }] + >, + InterfaceMethod<[{ + Return the mantissa width. + }], + /*retTy=*/"unsigned", + /*methodName=*/"getFPMantissaWidth", + /*args=*/(ins), + /*methodBody=*/"", + /*defaultImplementation=*/[{ + return llvm::APFloat::semanticsPrecision($_type.getFloatSemantics()); + }] + >, + InterfaceMethod<[{ + Return the float semantics of this floating-point type. + }], + /*retTy=*/"const llvm::fltSemantics &", + /*methodName=*/"getFloatSemantics" + >, + ]; +} + +#endif // LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD diff --git a/clang/include/clang/CIR/Interfaces/CMakeLists.txt b/clang/include/clang/CIR/Interfaces/CMakeLists.txt new file mode 100644 index 00000000000000..1c90b6b5a23cb2 --- /dev/null +++ b/clang/include/clang/CIR/Interfaces/CMakeLists.txt @@ -0,0 +1,14 @@ +# This replicates part of the add_mlir_interface cmake function from MLIR that +# cannot be used here. This happens because it expects to be run inside MLIR +# directory which is not the case for CIR (and also FIR, both have similar +# workarounds). + +function(add_clang_mlir_type_interface interface) + set(LLVM_TARGET_DEFINITIONS ${interface}.td) + mlir_tablegen(${interface}.h.inc -gen-type-interface-decls) + mlir_tablegen(${interface}.cpp.inc -gen-type-interface-defs) + add_public_tablegen_target(MLIR${interface}IncGen) + add_dependencies(mlir-generic-headers MLIR${interface}IncGen) +endfunction() + +add_clang_mlir_type_interface(CIRFPTypeInterface) diff --git a/clang/lib/CIR/CMakeLists.txt b/clang/lib/CIR/CMakeLists.txt index 11cca734808dfa..f3ef8525e15c26 100644 --- a/clang/lib/CIR/CMakeLists.txt +++ b/clang/lib/CIR/CMakeLists.txt @@ -4,3 +4,4 @@ include_directories(${CMAKE_BINARY_DIR}/tools/mlir/include) add_subdirectory(Dialect) add_subdirectory(CodeGen) add_subdirectory(FrontendAction) +add_subdirectory(Interfaces) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 92115778518d4a..01d56963883cc2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -21,6 +21,18 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { public: CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc) : CIRBaseBuilderTy(mlirContext), typeCache(tc) {} + + cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const { + if (&format == &llvm::APFloat::IEEEdouble()) + return cir::LongDoubleType::get(getContext(), typeCache.DoubleTy); + if (&format == &llvm::APFloat::x87DoubleExtended()) + return cir::LongDoubleType::get(getContext(), typeCache.FP80Ty); + if (&format == &llvm::APFloat::IEEEquad()) + return cir::LongDoubleType::get(getContext(), typeCache.FP128Ty); + if (&format == &llvm::APFloat::PPCDoubleDouble()) + llvm_unreachable("NYI: PPC double-double format for long double"); + llvm_unreachable("Unsupported format for long double"); + } }; } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 0db24c3b41d18d..416d532028d090 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -35,6 +35,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, diags(diags), target(astContext.getTargetInfo()), genTypes(*this) { // Initialize cached types + VoidTy = cir::VoidType::get(&getMLIRContext()); SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true); SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true); SInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true); @@ -45,6 +46,12 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false); UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false); UInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false); + FP16Ty = cir::FP16Type::get(&getMLIRContext()); + BFloat16Ty = cir::BF16Type::get(&getMLIRContext()); + FloatTy = cir::SingleType::get(&getMLIRContext()); + DoubleTy = cir::DoubleType::get(&getMLIRContext()); + FP80Ty = cir::FP80Type::get(&getMLIRContext()); + FP128Ty = cir::FP128Type::get(&getMLIRContext()); } mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) { diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h index a357663c33e0f8..99c0123c64b28c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h @@ -23,6 +23,9 @@ namespace clang::CIRGen { struct CIRGenTypeCache { CIRGenTypeCache() = default; + // ClangIR void type + cir::VoidType VoidTy; + // ClangIR signed integral types of common sizes cir::IntType SInt8Ty; cir::IntType SInt16Ty; @@ -36,6 +39,14 @@ struct CIRGenTypeCache { cir::IntType UInt32Ty; cir::IntType UInt64Ty; cir::IntType UInt128Ty; + + // ClangIR floating-point types with fixed formats + cir::FP16Type FP16Ty; + cir::BF16Type BFloat16Ty; + cir::SingleType FloatTy; + cir::DoubleType DoubleTy; + cir::FP80Type FP80Ty; + cir::FP128Type FP128Ty; }; } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 181af1898baff2..7e4e2f58cfce18 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -4,6 +4,9 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" +#include "clang/Basic/TargetInfo.h" + +#include <cassert> using namespace clang; using namespace clang::CIRGen; @@ -18,6 +21,87 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { return *builder.getContext(); } +/// Return true if the specified type in a function parameter or result position +/// can be converted to a CIR type at this point. This boils down to being +/// whether it is complete, as well as whether we've temporarily deferred +/// expanding the type because we're in a recursive context. +bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType type) { + // Some ABIs cannot have their member pointers represented in LLVM IR unless + // certain circumstances have been reached. + assert(!type->getAs<MemberPointerType>() && "NYI"); + + // If this isn't a tagged type, we can convert it! + const TagType *tagType = type->getAs<TagType>(); + if (!tagType) + return true; + + // Incomplete types cannot be converted. + if (tagType->isIncompleteType()) + return false; + + // If this is an enum, then it is always safe to convert. + const RecordType *recordType = dyn_cast<RecordType>(tagType); + if (!recordType) + return true; + + // Otherwise, we have to be careful. If it is a struct that we're in the + // process of expanding, then we can't convert the function type. That's ok + // though because we must be in a pointer context under the struct, so we can + // just convert it to a dummy type. + // + // We decide this by checking whether ConvertRecordDeclType returns us an + // opaque type for a struct that we know is defined. + // TODO(cir): struct types are not implemented yet, so skip the final check. + // return isSafeToConvert(recordType->getDecl(), *this); + return true; +} + +/// Code to verify a given function type is complete, i.e. the return type and +/// all of the parameter types are complete. Also check to see if we are in a +/// RS_StructPointer context, and if so whether any struct types have been +/// pended. If so, we don't want to ask the ABI lowering code to handle a type +/// that cannot be converted to a CIR type. +bool CIRGenTypes::isFuncTypeConvertible(const FunctionType *ft) { + if (!isFuncParamTypeConvertible(ft->getReturnType())) + return false; + + if (const auto *fpt = dyn_cast<FunctionProtoType>(ft)) + for (unsigned i = 0, e = fpt->getNumParams(); i != e; i++) + if (!isFuncParamTypeConvertible(fpt->getParamType(i))) + return false; + + return true; +} + +mlir::Type CIRGenTypes::ConvertFunctionTypeInternal(QualType qft) { + assert(qft.isCanonical()); + const FunctionType *ft = cast<FunctionType>(qft.getTypePtr()); + // First, check whether we can build the full fucntion type. If the function + // type depends on an incomplete type (e.g. a struct or enum), we cannot lower + // the function type. + if (!isFuncTypeConvertible(ft)) { + cgm.errorNYI(SourceLocation(), "function type involving an incomplete type", + qft); + return cir::FuncType::get(SmallVector<mlir::Type, 1>{}, cgm.VoidTy); + } + + // TODO(CIR): This is a stub of what the final code will be. See the + // implementation of this function and the implementation of class + // CIRGenFunction in the ClangIR incubator project. + + if (const auto *fpt = dyn_cast<FunctionProtoType>(ft)) { + SmallVector<mlir::Type> mlirParamTypes; + for (unsigned i = 0; i < fpt->getNumParams(); ++i) { + mlirParamTypes.push_back(convertType(fpt->getParamType(i))); + } + return cir::FuncType::get( + mlirParamTypes, convertType(fpt->getReturnType().getUnqualifiedType()), + fpt->isVariadic()); + } + cgm.errorNYI(SourceLocation(), "non-prototype function type", qft); + return cir::FuncType::get(SmallVector<mlir::Type, 1>{}, cgm.VoidTy); +} + mlir::Type CIRGenTypes::convertType(QualType type) { type = astContext.getCanonicalType(type); const Type *ty = type.getTypePtr(); @@ -34,6 +118,12 @@ mlir::Type CIRGenTypes::convertType(QualType type) { switch (ty->getTypeClass()) { case Type::Builtin: { switch (cast<BuiltinType>(ty)->getKind()) { + + // void + case BuiltinType::Void: + resultType = cgm.VoidTy; + break; + // Signed integral types. case BuiltinType::Char_S: case BuiltinType::Int: @@ -63,6 +153,41 @@ mlir::Type CIRGenTypes::convertType(QualType type) { cir::IntType::get(&getMLIRContext(), astContext.getTypeSize(ty), /*isSigned=*/false); break; + + // Floating-point types + case BuiltinType::Float16: + resultType = cgm.FP16Ty; + break; + case BuiltinType::Half: + if (astContext.getLangOpts().NativeHalfType || + !astContext.getTargetInfo().useFP16ConversionIntrinsics()) { + resultType = cgm.FP16Ty; + } else { + cgm.errorNYI(SourceLocation(), "processing of built-in type", type); + resultType = cgm.SInt32Ty; + } + break; + case BuiltinType::BFloat16: + resultType = cgm.BFloat16Ty; + break; + case BuiltinType::Float: + resultType = cgm.FloatTy; + break; + case BuiltinType::Double: + resultType = cgm.DoubleTy; + break; + case BuiltinType::LongDouble: + resultType = + builder.getLongDoubleTy(astContext.getFloatTypeSemantics(type)); + break; + case BuiltinType::Float128: + resultType = cgm.FP128Ty; + break; + case BuiltinType::Ibm128: + cgm.errorNYI(SourceLocation(), "processing of built-in type", type); + resultType = cgm.SInt32Ty; + break; + default: cgm.errorNYI(SourceLocation(), "processing of built-in type", type); resultType = cgm.SInt32Ty; @@ -70,6 +195,23 @@ mlir::Type CIRGenTypes::convertType(QualType type) { } break; } + + case Type::Pointer: { + const PointerType *ptrTy = cast<PointerType>(ty); + QualType elemTy = ptrTy->getPointeeType(); + assert(!elemTy->isConstantMatrixType() && "not implemented"); + + mlir::Type pointeeType = convertType(elemTy); + + resultType = builder.getPointerTo(pointeeType); + break; + } + + case Type::FunctionNoProto: + case Type::FunctionProto: + resultType = ConvertFunctionTypeInternal(type); + break; + case Type::BitInt: { const auto *bitIntTy = cast<BitIntType>(type); if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) { @@ -81,6 +223,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { } break; } + default: cgm.errorNYI(SourceLocation(), "processing of type", type); resultType = cgm.SInt32Ty; diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h b/clang/lib/CIR/CodeGen/CIRGenTypes.h index 563d7759831fa5..71427e12000279 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h @@ -19,6 +19,7 @@ namespace clang { class ASTContext; +class FunctionType; class QualType; class Type; } // namespace clang @@ -39,10 +40,18 @@ class CIRGenTypes { clang::ASTContext &astContext; CIRGenBuilderTy &builder; + /// Heper for ConvertType. + mlir::Type ConvertFunctionTypeInternal(clang::QualType ft); + public: CIRGenTypes(CIRGenModule &cgm); ~CIRGenTypes(); + /// Utility to check whether a function type can be converted to a CIR type + /// (i.e. doesn't depend on an incomplete tag type). + bool isFuncTypeConvertible(const clang::FunctionType *ft); + bool isFuncParamTypeConvertible(clang::QualType type); + /// This map of clang::Type to mlir::Type (which includes CIR type) is a /// cache of types that have already been processed. using TypeCacheTy = llvm::DenseMap<const clang::Type *, mlir::Type>; diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt index 9ada31c11de950..782b814d75daaa 100644 --- a/clang/lib/CIR/CodeGen/CMakeLists.txt +++ b/clang/lib/CIR/CodeGen/CMakeLists.txt @@ -21,4 +21,5 @@ add_clang_library(clangCIR clangLex ${dialect_libs} MLIRCIR + MLIRCIRInterfaces ) diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index de38337057d3dc..48be11ba4e243d 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -16,6 +16,16 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "llvm/ADT/TypeSwitch.h" +//===----------------------------------------------------------------------===// +// CIR Custom Parser/Printer Signatures +//===----------------------------------------------------------------------===// + +static mlir::ParseResult +parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms, + bool &isVarArg); +static void printFuncTypeArgs(mlir::AsmPrinter &p, + mlir::ArrayRef<mlir::Type> params, bool isVarArg); + //===----------------------------------------------------------------------===// // Get autogenerated stuff //===----------------------------------------------------------------------===// @@ -133,6 +143,276 @@ IntType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, return mlir::success(); } +//===----------------------------------------------------------------------===// +// Floating-point type definitions +//===----------------------------------------------------------------------===// + +const llvm::fltSemantics &SingleType::getFloatSemantics() const { + return llvm::APFloat::IEEEsingle(); +} + +llvm::TypeSize +SingleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t +SingleType::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +SingleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &DoubleType::getFloatSemantics() const { + return llvm::APFloat::IEEEdouble(); +} + +llvm::TypeSize +DoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t +DoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +DoubleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &FP16Type::getFloatSemantics() const { + return llvm::APFloat::IEEEhalf(); +} + +llvm::TypeSize +FP16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t FP16Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +FP16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &BF16Type::getFloatSemantics() const { + return llvm::APFloat::BFloat(); +} + +llvm::TypeSize +BF16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t BF16Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +BF16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + 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 { + // Though only 80 bits are used for the value, the type is 128 bits in size. + return llvm::TypeSize::getFixed(128); +} + +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 &FP128Type::getFloatSemantics() const { + return llvm::APFloat::IEEEquad(); +} + +llvm::TypeSize +FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return 16; +} + +uint64_t +FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return 16; +} + +const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const { + return mlir::cast<cir::CIRFPTypeInterface>(getUnderlying()) + .getFloatSemantics(); +} + +llvm::TypeSize +LongDoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying()) + .getTypeSizeInBits(dataLayout, params); +} + +uint64_t +LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying()) + .getABIAlignment(dataLayout, params); +} + +uint64_t LongDoubleType::getPreferredAlignment( + const ::mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return mlir::cast<mlir::DataLayoutTypeInterface>(getUnderlying()) + .getPreferredAlignment(dataLayout, params); +} + +LogicalResult +LongDoubleType::verify(function_ref<InFlightDiagnostic()> emitError, + mlir::Type underlying) { + if (!mlir::isa<DoubleType, FP80Type, FP128Type>(underlying)) { + emitError() << "invalid underlying type for long double"; + return failure(); + } + + return success(); +} + +//===----------------------------------------------------------------------===// +// Floating-point type helpers +//===----------------------------------------------------------------------===// + +bool cir::isAnyFloatingPointType(mlir::Type t) { + return isa<cir::SingleType, cir::DoubleType, cir::LongDoubleType, + cir::FP80Type, cir::BF16Type, cir::FP16Type, cir::FP128Type>(t); +} + +//===----------------------------------------------------------------------===// +// FuncType Definitions +//===----------------------------------------------------------------------===// + +FuncType FuncType::clone(TypeRange inputs, TypeRange results) const { + assert(results.size() == 1 && "expected exactly one result type"); + return get(llvm::to_vector(inputs), results[0], isVarArg()); +} + +mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p, + llvm::SmallVector<mlir::Type> ¶ms, + bool &isVarArg) { + isVarArg = false; + // `(` `)` + if (succeeded(p.parseOptionalRParen())) + return mlir::success(); + + // `(` `...` `)` + if (succeeded(p.parseOptionalEllipsis())) { + isVarArg = true; + return p.parseRParen(); + } + + // type (`,` type)* (`,` `...`)? + mlir::Type type; + if (p.parseType(type)) + return mlir::failure(); + params.push_back(type); + while (succeeded(p.parseOptionalComma())) { + if (succeeded(p.parseOptionalEllipsis())) { + isVarArg = true; + return p.parseRParen(); + } + if (p.parseType(type)) + return mlir::failure(); + params.push_back(type); + } + + return p.parseRParen(); +} + +void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params, + bool isVarArg) { + llvm::interleaveComma(params, p, + [&p](mlir::Type type) { p.printType(type); }); + if (isVarArg) { + if (!params.empty()) + p << ", "; + p << "..."; + } + p << ')'; +} + +llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const { + return static_cast<detail::FuncTypeStorage *>(getImpl())->returnType; +} + +bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); } + +//===----------------------------------------------------------------------===// +// PointerType Definitions +//===----------------------------------------------------------------------===// + +llvm::TypeSize +PointerType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + // FIXME: improve this in face of address spaces + return llvm::TypeSize::getFixed(64); +} + +uint64_t +PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + // FIXME: improve this in face of address spaces + return 8; +} + +uint64_t PointerType::getPreferredAlignment( + const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + // FIXME: improve this in face of address spaces + return 8; +} + +mlir::LogicalResult +PointerType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, + mlir::Type pointee) { + // TODO(CIR): Verification of the address space goes here. + return mlir::success(); +} + //===----------------------------------------------------------------------===// // CIR Dialect //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt index 7ddc4ce501907d..df60f69df6fc0e 100644 --- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -11,5 +11,6 @@ add_clang_library(MLIRCIR MLIRDLTIDialect MLIRDataLayoutInterfaces MLIRFuncDialect + MLIRCIRInterfaces clangAST ) diff --git a/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp b/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp new file mode 100644 index 00000000000000..5bf6926283966c --- /dev/null +++ b/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp @@ -0,0 +1,14 @@ +//====- CIRFPTypeInterface.cpp - Interface for floating-point types -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +using namespace cir; + +/// Include the generated interfaces. +#include "clang/CIR/Interfaces/CIRFPTypeInterface.cpp.inc" diff --git a/clang/lib/CIR/Interfaces/CMakeLists.txt b/clang/lib/CIR/Interfaces/CMakeLists.txt new file mode 100644 index 00000000000000..fcd8b6963d06c2 --- /dev/null +++ b/clang/lib/CIR/Interfaces/CMakeLists.txt @@ -0,0 +1,14 @@ +add_clang_library(MLIRCIRInterfaces + CIRFPTypeInterface.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Interfaces + + DEPENDS + MLIRCIRFPTypeInterfaceIncGen + + LINK_LIBS + ${dialect_libs} + MLIRIR + MLIRSupport + ) diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp index 5230ff53f87d72..bbd452655a01bf 100644 --- a/clang/test/CIR/global-var-simple.cpp +++ b/clang/test/CIR/global-var-simple.cpp @@ -57,3 +57,42 @@ _BitInt(20) sb20; unsigned _BitInt(48) ub48; // CHECK: cir.global @ub48 : !cir.int<u, 48> + +_Float16 f16; +// CHECK: cir.global @f16 : !cir.f16 + +__bf16 bf16; +// CHECK: cir.global @bf16 : !cir.bf16 + +float f; +// CHECK: cir.global @f : !cir.float + +double d; +// CHECK: cir.global @d : !cir.double + +long double ld; +// CHECK: cir.global @ld : !cir.long_double<!cir.f80> + +__float128 f128; +// CHECK: cir.global @f128 : !cir.f128 + +void *vp; +// CHECK: cir.global @vp : !cir.ptr<!cir.void> + +int *ip; +// CHECK: cir.global @ip : !cir.ptr<!cir.int<s, 32>> + +double *dp; +// CHECK: cir.global @dp : !cir.ptr<!cir.double> + +char **cpp; +// CHECK: cir.global @cpp : !cir.ptr<!cir.ptr<!cir.int<s, 8>>> + +void (*fp)(); +// CHECK: cir.global @fp : !cir.ptr<!cir.func<!cir.void ()>> + +int (*fpii)(int); +// CHECK: cir.global @fpii : !cir.ptr<!cir.func<!cir.int<s, 32> (!cir.int<s, 32>)>> + +void (*fpvar)(int, ...); +// CHECK: cir.global @fpvar : !cir.ptr<!cir.func<!cir.void (!cir.int<s, 32>, ...)>> >From 512b4b5b7cddf4b2882dd1e1d7d44dbe653eed84 Mon Sep 17 00:00:00 2001 From: David Olsen <dol...@nvidia.com> Date: Wed, 18 Dec 2024 16:56:20 -0800 Subject: [PATCH 2/3] [CIR] Follow-up to floating-point upstream change Fix the opening comment on some newly added files. Add asserts that the Clang types `float` and `double` are IEEE 32-bit and 64-bit. --- clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td | 6 +++++- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 8 +++++++- clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp | 6 +++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td index 33ad0fc1aa53cb..973851b61444f0 100644 --- a/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td +++ b/clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td @@ -1,10 +1,14 @@ -//===- CIRFPTypeInterface.td - CIR FP Interface Definitions -----*- C++ -*-===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// Defines the interface to generically handle CIR floating-point types. +// +//===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD #define LLVM_CLANG_INCLUDE_CLANG_CIR_INTERFACES_CIRFPTYPEINTERFACE_TD diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 7e4e2f58cfce18..43f3cce4d248ce 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -30,7 +30,7 @@ bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType type) { // certain circumstances have been reached. assert(!type->getAs<MemberPointerType>() && "NYI"); - // If this isn't a tagged type, we can convert it! + // If this isn't a tag type, we can convert it. const TagType *tagType = type->getAs<TagType>(); if (!tagType) return true; @@ -171,9 +171,15 @@ mlir::Type CIRGenTypes::convertType(QualType type) { resultType = cgm.BFloat16Ty; break; case BuiltinType::Float: + assert(&astContext.getFloatTypeSemantics(type) == + &llvm::APFloat::IEEEsingle() && + "ClangIR only supports float as IEEE 32-bit"); resultType = cgm.FloatTy; break; case BuiltinType::Double: + assert(&astContext.getFloatTypeSemantics(type) == + &llvm::APFloat::IEEEdouble() && + "ClangIR only supports double as IEEE 64-bit"); resultType = cgm.DoubleTy; break; case BuiltinType::LongDouble: diff --git a/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp b/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp index 5bf6926283966c..41817e90b52328 100644 --- a/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp +++ b/clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp @@ -1,10 +1,14 @@ -//====- CIRFPTypeInterface.cpp - Interface for floating-point types -------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// Defines the interface to generically handle CIR floating-point types. +// +//===----------------------------------------------------------------------===// #include "clang/CIR/Interfaces/CIRFPTypeInterface.h" >From 666cda99f4d288adb5aa8334f50ebf9a09387c36 Mon Sep 17 00:00:00 2001 From: David Olsen <dol...@nvidia.com> Date: Thu, 19 Dec 2024 22:45:16 -0800 Subject: [PATCH 3/3] [CIR] Improve a couple assert messages --- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 43f3cce4d248ce..131bfcc26ec578 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -173,13 +173,13 @@ mlir::Type CIRGenTypes::convertType(QualType type) { case BuiltinType::Float: assert(&astContext.getFloatTypeSemantics(type) == &llvm::APFloat::IEEEsingle() && - "ClangIR only supports float as IEEE 32-bit"); + "ClangIR NYI: 'float' in a format other than IEEE 32-bit"); resultType = cgm.FloatTy; break; case BuiltinType::Double: assert(&astContext.getFloatTypeSemantics(type) == &llvm::APFloat::IEEEdouble() && - "ClangIR only supports double as IEEE 64-bit"); + "ClangIR NYI: 'double' in a format other than IEEE 64-bit"); resultType = cgm.DoubleTy; break; case BuiltinType::LongDouble: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits