[clang] 9021ce9 - [Clang] Enable KF and KC mode for [_Complex] __float128
Nemanja Ivanovic via cfe-commits
cfe-commits at lists.llvm.org
Thu May 28 13:48:35 PDT 2020
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];
More information about the cfe-commits
mailing list