Author: Nemanja Ivanovic Date: 2020-05-28T15:48:15-05:00 New Revision: 9021ce9576e438ae5a6fdb574327d30ea6b67fa8
URL: https://github.com/llvm/llvm-project/commit/9021ce9576e438ae5a6fdb574327d30ea6b67fa8 DIFF: https://github.com/llvm/llvm-project/commit/9021ce9576e438ae5a6fdb574327d30ea6b67fa8.diff LOG: [Clang] Enable KF and KC mode for [_Complex] __float128 The headers provided with recent GNU toolchains for PPC have code that includes typedefs such as: typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__KC__))) This patch allows clang to compile programs that contain #include <math.h> with -mfloat128 which it currently fails to compile. Fixes: https://bugs.llvm.org/show_bug.cgi?id=46068 Differential revision: https://reviews.llvm.org/D80374 Added: Modified: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/TargetInfo.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Sema/attr-mode.c Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 509ada3c9696..a5bb9a34c2fb 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -657,7 +657,7 @@ class ASTContext : public RefCountedBase<ASTContext> { /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. - QualType getRealTypeForBitwidth(unsigned DestWidth) const; + QualType getRealTypeForBitwidth(unsigned DestWidth, bool ExplicitIEEE) const; bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 910a4d6846aa..0a5379225caf 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -368,8 +368,13 @@ class TargetInfo : public virtual TransferrableTargetInfo, virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; - /// Return floating point type with specified width. - RealType getRealTypeByWidth(unsigned BitWidth) const; + /// Return floating point type with specified width. On PPC, there are + /// three possible types for 128-bit floating point: "PPC double-double", + /// IEEE 754R quad precision, and "long double" (which under the covers + /// is represented as one of those two). At this time, there is no support + /// for an explicit "PPC double-double" type (i.e. __ibm128) so we only + /// need to diff erentiate between "long double" and IEEE quad precision. + RealType getRealTypeByWidth(unsigned BitWidth, bool ExplicitIEEE) const; /// Return the alignment (in bits) of the specified integer type enum. /// diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c457a5537168..bfb6014027f4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -10644,8 +10644,10 @@ QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth, /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. -QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const { - TargetInfo::RealType Ty = getTargetInfo().getRealTypeByWidth(DestWidth); +QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth, + bool ExplicitIEEE) const { + TargetInfo::RealType Ty = + getTargetInfo().getRealTypeByWidth(DestWidth, ExplicitIEEE); switch (Ty) { case TargetInfo::Float: return FloatTy; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 2f1e044bb106..a3c8da5885b8 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -265,7 +265,8 @@ TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth, return NoInt; } -TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { +TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth, + bool ExplicitIEEE) const { if (getFloatWidth() == BitWidth) return Float; if (getDoubleWidth() == BitWidth) @@ -277,6 +278,10 @@ TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { return LongDouble; break; case 128: + // The caller explicitly asked for an IEEE compliant type but we still + // have to check if the target supports it. + if (ExplicitIEEE) + return hasFloat128Type() ? Float128 : NoFloat; if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) return LongDouble; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0e062ba74a08..df44b6fcf2af 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3942,7 +3942,8 @@ bool Sema::checkMSInheritanceAttrOnDefinition( /// parseModeAttrArg - Parses attribute mode string and returns parsed type /// attribute. static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth, - bool &IntegerMode, bool &ComplexMode) { + bool &IntegerMode, bool &ComplexMode, + bool &ExplicitIEEE) { IntegerMode = true; ComplexMode = false; switch (Str.size()) { @@ -3963,7 +3964,12 @@ static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth, case 'X': DestWidth = 96; break; + case 'K': // KFmode - IEEE quad precision (__float128) + ExplicitIEEE = true; + DestWidth = Str[1] == 'I' ? 0 : 128; + break; case 'T': + ExplicitIEEE = false; DestWidth = 128; break; } @@ -4024,6 +4030,7 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI, unsigned DestWidth = 0; bool IntegerMode = true; bool ComplexMode = false; + bool ExplicitIEEE = false; llvm::APInt VectorSize(64, 0); if (Str.size() >= 4 && Str[0] == 'V') { // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2). @@ -4036,7 +4043,7 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI, !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) && VectorSize.isPowerOf2()) { parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth, - IntegerMode, ComplexMode); + IntegerMode, ComplexMode, ExplicitIEEE); // Avoid duplicate warning from template instantiation. if (!InInstantiation) Diag(AttrLoc, diag::warn_vector_mode_deprecated); @@ -4046,7 +4053,8 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI, } if (!VectorSize) - parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode); + parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode, + ExplicitIEEE); // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t // and friends, at least with glibc. @@ -4112,7 +4120,7 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI, NewElemTy = Context.getIntTypeForBitwidth(DestWidth, OldElemTy->isSignedIntegerType()); else - NewElemTy = Context.getRealTypeForBitwidth(DestWidth); + NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitIEEE); if (NewElemTy.isNull()) { Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name; diff --git a/clang/test/Sema/attr-mode.c b/clang/test/Sema/attr-mode.c index c89cb6524191..a4bac90b99fb 100644 --- a/clang/test/Sema/attr-mode.c +++ b/clang/test/Sema/attr-mode.c @@ -4,6 +4,8 @@ // RUN: -verify %s // RUN: %clang_cc1 -triple powerpc64-pc-linux-gnu -DTEST_64BIT_PPC64 -fsyntax-only \ // RUN: -verify %s +// RUN: %clang_cc1 -triple powerpc64-pc-linux-gnu -DTEST_F128_PPC64 -fsyntax-only \ +// RUN: -verify -target-feature +float128 %s // RUN: %clang_cc1 -triple x86_64-pc-linux-gnux32 -DTEST_64BIT_X86 -fsyntax-only \ // RUN: -verify %s // RUN: %clang_cc1 -triple mips-linux-gnu -DTEST_MIPS_32 -fsyntax-only \ @@ -90,6 +92,15 @@ void f_ft128_arg(long double *x); void f_ft128_complex_arg(_Complex long double *x); void test_TFtype(f128ibm *a) { f_ft128_arg (a); } void test_TCtype(c128ibm *a) { f_ft128_complex_arg (a); } +#elif TEST_F128_PPC64 +typedef int invalid_7 __attribute((mode(KF))); // expected-error{{type of machine mode does not match type of base type}} +typedef int invalid_8 __attribute((mode(KI))); // expected-error{{unknown machine mode}} +typedef _Complex float cf128 __attribute__((mode(KC))); +typedef float f128 __attribute__((mode(KF))); +void f_f128_arg(__float128 *x); +void f_f128_complex_arg(_Complex __float128 *x); +void test_KFtype(f128 *a) { f_f128_arg(a); } +void test_KCtype(cf128 *a) { f_f128_complex_arg(a); } #elif TEST_MIPS_32 typedef unsigned int gcc_unwind_word __attribute__((mode(unwind_word))); int foo[sizeof(gcc_unwind_word) == 4 ? 1 : -1]; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits