forked from OSchip/llvm-project
[Clang] Allow 'Complex float __attribute__((mode(HC)))'
Adding half float to types that can be represented by __attribute__((mode(xx))). Original implementation authored by George Steed. Differential Revision: https://reviews.llvm.org/D126479
This commit is contained in:
parent
b3ebe3beed
commit
c80c57674e
|
@ -367,6 +367,8 @@ Attribute Changes in Clang
|
|||
- Added the ``clang::annotate_type`` attribute, which can be used to add
|
||||
annotations to types (see documentation for details).
|
||||
|
||||
- Added half float to types that can be represented by ``__attribute__((mode(XX)))``.
|
||||
|
||||
Windows Support
|
||||
---------------
|
||||
|
||||
|
|
|
@ -53,11 +53,13 @@ namespace Builtin { struct Info; }
|
|||
|
||||
enum class FloatModeKind {
|
||||
NoFloat = 255,
|
||||
Float = 0,
|
||||
Half = 0,
|
||||
Float,
|
||||
Double,
|
||||
LongDouble,
|
||||
Float128,
|
||||
Ibm128
|
||||
Ibm128,
|
||||
Last = Ibm128
|
||||
};
|
||||
|
||||
/// Fields controlling how types are laid out in memory; these may need to
|
||||
|
@ -219,7 +221,7 @@ protected:
|
|||
mutable VersionTuple PlatformMinVersion;
|
||||
|
||||
unsigned HasAlignMac68kSupport : 1;
|
||||
unsigned RealTypeUsesObjCFPRet : 3;
|
||||
unsigned RealTypeUsesObjCFPRetMask : (int)FloatModeKind::Last + 1;
|
||||
unsigned ComplexLongDoubleUsesFP2Ret : 1;
|
||||
|
||||
unsigned HasBuiltinMSVaList : 1;
|
||||
|
@ -888,7 +890,9 @@ public:
|
|||
/// Check whether the given real type should use the "fpret" flavor of
|
||||
/// Objective-C message passing on this target.
|
||||
bool useObjCFPRetForRealType(FloatModeKind T) const {
|
||||
return RealTypeUsesObjCFPRet & (1 << (int)T);
|
||||
assert(T <= FloatModeKind::Last &&
|
||||
"T value is larger than RealTypeUsesObjCFPRetMask can handle");
|
||||
return RealTypeUsesObjCFPRetMask & (1 << (int)T);
|
||||
}
|
||||
|
||||
/// Check whether _Complex long double should use the "fp2ret" flavor
|
||||
|
|
|
@ -11758,6 +11758,8 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth,
|
|||
FloatModeKind Ty =
|
||||
getTargetInfo().getRealTypeByWidth(DestWidth, ExplicitType);
|
||||
switch (Ty) {
|
||||
case FloatModeKind::Half:
|
||||
return HalfTy;
|
||||
case FloatModeKind::Float:
|
||||
return FloatTy;
|
||||
case FloatModeKind::Double:
|
||||
|
|
|
@ -131,7 +131,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
|
|||
ARMCDECoprocMask = 0;
|
||||
|
||||
// Default to no types using fpret.
|
||||
RealTypeUsesObjCFPRet = 0;
|
||||
RealTypeUsesObjCFPRetMask = 0;
|
||||
|
||||
// Default to not using fp2ret for __Complex long double
|
||||
ComplexLongDoubleUsesFP2Ret = false;
|
||||
|
@ -287,6 +287,8 @@ TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
|
|||
|
||||
FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth,
|
||||
FloatModeKind ExplicitType) const {
|
||||
if (getHalfWidth() == BitWidth)
|
||||
return FloatModeKind::Half;
|
||||
if (getFloatWidth() == BitWidth)
|
||||
return FloatModeKind::Float;
|
||||
if (getDoubleWidth() == BitWidth)
|
||||
|
|
|
@ -418,7 +418,7 @@ public:
|
|||
RegParmMax = 3;
|
||||
|
||||
// Use fpret for all types.
|
||||
RealTypeUsesObjCFPRet =
|
||||
RealTypeUsesObjCFPRetMask =
|
||||
((1 << (int)FloatModeKind::Float) | (1 << (int)FloatModeKind::Double) |
|
||||
(1 << (int)FloatModeKind::LongDouble));
|
||||
|
||||
|
@ -699,7 +699,7 @@ public:
|
|||
"64-i64:64-f80:128-n8:16:32:64-S128");
|
||||
|
||||
// Use fpret only for long double.
|
||||
RealTypeUsesObjCFPRet = (1 << (int)FloatModeKind::LongDouble);
|
||||
RealTypeUsesObjCFPRetMask = (1 << (int)FloatModeKind::LongDouble);
|
||||
|
||||
// Use fp2ret for _Complex long double.
|
||||
ComplexLongDoubleUsesFP2Ret = true;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
typedef _Complex float c16a __attribute((mode(HC)));
|
||||
typedef _Complex double c16b __attribute((mode(HC)));
|
||||
typedef _Complex float c32a __attribute((mode(SC)));
|
||||
typedef _Complex double c32b __attribute((mode(SC)));
|
||||
typedef _Complex float c64a __attribute((mode(DC)));
|
||||
typedef _Complex double c64b __attribute((mode(DC)));
|
||||
|
||||
// CHECK: define{{.*}} { half, half } @c16_test([2 x half] noundef {{.*}}
|
||||
// CHECK: ret { half, half } {{.*}}
|
||||
c16b c16_test(c16a x) {
|
||||
return x + x;
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} { float, float } @c32_test([2 x float] noundef {{.*}})
|
||||
// CHECK: ret { float, float } {{.*}}
|
||||
c32b c32_test(c32a x) {
|
||||
return x + x;
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} { double, double } @c64_test([2 x double] noundef {{.*}})
|
||||
// CHECK: ret { double, double } {{.*}}
|
||||
c64b c64_test(c64a x) {
|
||||
return x + x;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
typedef float f16a __attribute((mode(HF)));
|
||||
typedef double f16b __attribute((mode(HF)));
|
||||
typedef float f32a __attribute((mode(SF)));
|
||||
typedef double f32b __attribute((mode(SF)));
|
||||
typedef float f64a __attribute((mode(DF)));
|
||||
typedef double f64b __attribute((mode(DF)));
|
||||
f16b tmp;
|
||||
|
||||
// CHECK: define{{.*}} ptr @f16_test(ptr noundef {{.*}})
|
||||
// CHECK: store half {{.*}}, ptr @tmp, align 2
|
||||
// CHECK: ret ptr @tmp
|
||||
f16b *f16_test(f16a *x) {
|
||||
tmp = *x + *x;
|
||||
return &tmp;
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} float @f32_test(float noundef {{.*}})
|
||||
// CHECK: ret float {{.*}}
|
||||
f32b f32_test(f32a x) {
|
||||
return x + x;
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}} double @f64_test(double noundef {{.*}})
|
||||
// CHECK: ret double {{.*}}
|
||||
f64b f64_test(f64a x) {
|
||||
return x + x;
|
||||
}
|
|
@ -22,8 +22,7 @@ typedef float __attribute__((mode(QC))) __attribute__((vector_size(256))) vec_t8
|
|||
// expected-error@-1{{unsupported machine mode 'QC'}}
|
||||
// expected-error@-2{{type of machine mode does not match type of base type}}
|
||||
typedef _Complex float __attribute__((mode(HC))) __attribute__((vector_size(256))) vec_t9;
|
||||
// expected-error@-1{{unsupported machine mode 'HC'}}
|
||||
// expected-error@-2{{invalid vector element type '_Complex float'}}
|
||||
// expected-error@-1{{invalid vector element type '_Complex float'}}
|
||||
typedef int __attribute__((mode(SC))) __attribute__((vector_size(256))) vec_t10;
|
||||
// expected-error@-1{{type of machine mode does not match type of base type}}
|
||||
// expected-error@-2{{type of machine mode does not support base vector types}}
|
||||
|
|
|
@ -37,6 +37,11 @@ int **__attribute((mode(QI)))* i32; // expected-error{{mode attribute}}
|
|||
__attribute__((mode(QI))) int invalid_func(void) { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}}
|
||||
enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to}}
|
||||
|
||||
typedef _Complex float c16a __attribute((mode(HC)));
|
||||
int c16a_test[sizeof(c16a) == 4 ? 1 : -1];
|
||||
typedef _Complex double c16b __attribute((mode(HC)));
|
||||
int c16b_test[sizeof(c16b) == 4 ? 1 : -1];
|
||||
|
||||
typedef _Complex double c32 __attribute((mode(SC)));
|
||||
int c32_test[sizeof(c32) == 8 ? 1 : -1];
|
||||
typedef _Complex float c64 __attribute((mode(DC)));
|
||||
|
|
Loading…
Reference in New Issue