summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Frontend/fixed_point.c162
-rw-r--r--clang/test/Frontend/fixed_point_bit_widths.c72
-rw-r--r--clang/test/Frontend/fixed_point_declarations.c113
-rw-r--r--clang/test/Frontend/fixed_point_errors.c57
-rw-r--r--clang/test/Frontend/fixed_point_same_fbits.c28
5 files changed, 395 insertions, 37 deletions
diff --git a/clang/test/Frontend/fixed_point.c b/clang/test/Frontend/fixed_point.c
index bc8cf2dcd7b..3a67718fba8 100644
--- a/clang/test/Frontend/fixed_point.c
+++ b/clang/test/Frontend/fixed_point.c
@@ -236,4 +236,164 @@ SatlF_t SatlF_type;
//CHECK-NEXT: |-VarDecl {{.*}} SatlA_type 'SatlA_t':'_Sat long _Accum'
//CHECK-NEXT: |-VarDecl {{.*}} SatsF_type 'SatsF_t':'_Sat short _Fract'
//CHECK-NEXT: |-VarDecl {{.*}} SatF_type 'SatF_t':'_Sat _Fract'
-//CHECK-NEXT: `-VarDecl {{.*}} SatlF_type 'SatlF_t':'_Sat long _Fract'
+//CHECK-NEXT: |-VarDecl {{.*}} SatlF_type 'SatlF_t':'_Sat long _Fract'
+
+// Fixed point literal exponent syntax
+_Accum decexp1 = 1.575e1k;
+_Accum decexp2 = 1.575E1k;
+_Accum decexp3 = 1575e-2k;
+_Accum decexp4 = 1575E-2k;
+
+_Accum hexexp1 = 0x0.3p10k;
+_Accum hexexp2 = 0x0.3P10k;
+_Accum hexexp3 = 0x30000p-10k;
+_Accum hexexp4 = 0x30000P-10k;
+
+_Accum zeroexp1 = 1e0k;
+_Accum zeroexp2 = 1e-0k;
+
+//CHECK-NEXT: |-VarDecl {{.*}} decexp1 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75
+//CHECK-NEXT: |-VarDecl {{.*}} decexp2 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75
+//CHECK-NEXT: |-VarDecl {{.*}} decexp3 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75
+//CHECK-NEXT: |-VarDecl {{.*}} decexp4 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 15.75
+
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp1 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp2 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp3 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp4 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 192.0
+
+//CHECK-NEXT: |-VarDecl {{.*}} zeroexp1 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0
+//CHECK-NEXT: |-VarDecl {{.*}} zeroexp2 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0
+
+// Fixed point literal values
+_Accum literal1 = 2.5k; // Precise decimal
+_Accum literal2 = 0.0k; // Zero
+_Accum literal3 = 1.1k; // Imprecise decimal
+_Accum literal4 = 1.11k;
+_Accum literal5 = 1.111k;
+_Accum literal6 = 1.1111k;
+_Accum literal7 = 1.11111k; // After some point after the radix, adding any more
+ // digits to the literal will not result in any
+ // further precision since the nth digit added may
+ // be less than the precision that can be
+ // represented by the fractional bits of the type.
+ // This results in the same value being stored for
+ // the type.
+
+//CHECK-NEXT: |-VarDecl {{.*}} literal1 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 2.5
+//CHECK-NEXT: |-VarDecl {{.*}} literal2 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.0
+//CHECK-NEXT: |-VarDecl {{.*}} literal3 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0999755859375
+//CHECK-NEXT: |-VarDecl {{.*}} literal4 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.1099853515625
+//CHECK-NEXT: |-VarDecl {{.*}} literal5 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.110992431640625
+//CHECK-NEXT: |-VarDecl {{.*}} literal6 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375
+//CHECK-NEXT: |-VarDecl {{.*}} literal7 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375
+
+long _Accum longaccumliteral = 0.99999999lk;
+long _Accum longaccumliteral2 = 0.999999999lk;
+long _Accum verylongaccumliteral = 0.99999999999999999999999999lk;
+long _Fract longfractliteral = 0.99999999lr;
+long _Fract longfractliteral2 = 0.999999999lr;
+long _Fract verylongfractliteral = 0.99999999999999999999999999lr;
+
+//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral 'long _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.999999989755451679229736328125
+//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral2 'long _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999986030161380767822265625
+//CHECK-NEXT: |-VarDecl {{.*}} verylongaccumliteral 'long _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875
+//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral 'long _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.999999989755451679229736328125
+//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral2 'long _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999986030161380767822265625
+//CHECK-NEXT: |-VarDecl {{.*}} verylongfractliteral 'long _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875
+
+unsigned _Accum uliteral1 = 2.5uk; // Unsigned
+_Accum literal8 = -2.5k; // Negative
+
+//CHECK-NEXT: |-VarDecl {{.*}} uliteral1 'unsigned _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned _Accum' 2.5
+//CHECK-NEXT: |-VarDecl {{.*}} literal8 '_Accum' cinit
+//CHECK-NEXT: `-UnaryOperator {{.*}} '_Accum' prefix '-'
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 2.5
+
+short _Accum literalexact1 = 0.9921875hk; // Exact value
+_Accum literalexact2 = 0.999969482421875k;
+
+//CHECK-NEXT: |-VarDecl {{.*}} literalexact1 'short _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.9921875
+//CHECK-NEXT: |-VarDecl {{.*}} literalexact2 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.999969482421875
+
+// Unfortunately we do not have enough space to store the exact decimal value of
+// 0.9999999995343387126922607421875 ((1 << 31) - 1), but we can still use a
+// large number of 9s to get the max fractional value.
+long _Accum long_accum_max = 0.999999999999999999999999999lk;
+
+//CHECK-NEXT: |-VarDecl {{.*}} long_accum_max 'long _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875
+
+// Epsilon
+short _Accum short_accum_eps = 0.0078125hk;
+short _Accum short_accum_eps2 = 0.0078124hk; // Less than epsilon floors to zero
+_Accum accum_eps = 0.000030517578125k;
+_Accum accum_eps2 = 0.000030517578124k;
+long _Accum long_accum_eps = 0x1p-31lk;
+long _Accum long_accum_eps2 = 0x0.99999999p-31lk;
+
+//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps 'short _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.0078125
+//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps2 'short _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Accum' 0.0
+//CHECK-NEXT: |-VarDecl {{.*}} accum_eps '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.000030517578125
+//CHECK-NEXT: |-VarDecl {{.*}} accum_eps2 '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 0.0
+//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps 'long _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.0000000004656612873077392578125
+//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps2 'long _Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Accum' 0.0
+
+// Fract literals can be one but evaluate to the respective Fract max
+short _Fract short_fract_one = 1.0hr;
+_Fract fract_one = 1.0r;
+long _Fract long_fract_one = 1.0lr;
+unsigned short _Fract u_short_fract_one = 1.0uhr;
+unsigned _Fract u_fract_one = 1.0ur;
+unsigned long _Fract u_long_fract_one = 1.0ulr;
+
+//CHECK-NEXT: |-VarDecl {{.*}} short_fract_one 'short _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'short _Fract' 0.9921875
+//CHECK-NEXT: |-VarDecl {{.*}} fract_one '_Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Fract' 0.999969482421875
+//CHECK-NEXT: |-VarDecl {{.*}} long_fract_one 'long _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875
+
+//CHECK-NEXT: |-VarDecl {{.*}} u_short_fract_one 'unsigned short _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned short _Fract' 0.99609375
+//CHECK-NEXT: |-VarDecl {{.*}} u_fract_one 'unsigned _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned _Fract' 0.9999847412109375
+//CHECK-NEXT: |-VarDecl {{.*}} u_long_fract_one 'unsigned long _Fract' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} 'unsigned long _Fract' 0.99999999976716935634613037109375
+
+_Accum literallast = 1.0k; // One
+
+//CHECK-NEXT: `-VarDecl {{.*}} literallast '_Accum' cinit
+//CHECK-NEXT: `-FixedPointLiteral {{.*}} '_Accum' 1.0
diff --git a/clang/test/Frontend/fixed_point_bit_widths.c b/clang/test/Frontend/fixed_point_bit_widths.c
index 8973a336660..ac8db49ed51 100644
--- a/clang/test/Frontend/fixed_point_bit_widths.c
+++ b/clang/test/Frontend/fixed_point_bit_widths.c
@@ -44,12 +44,12 @@ int align_SsF = __alignof(signed short _Fract);
int align_SF = __alignof(signed _Fract);
int align_SlF = __alignof(signed long _Fract);
-// CHECK-NEXT: @size_SsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @size_SF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @size_SlF = {{.*}}global i{{[0-9]+}} 8
-// CHECK-NEXT: @align_SsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @align_SF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @align_SlF = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @size_SsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @size_SF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_SlF = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_SsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @align_SF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_SlF = {{.*}}global i{{[0-9]+}} 4
/* Primary unsigned _Fract */
@@ -60,12 +60,12 @@ int align_UsF = __alignof(unsigned short _Fract);
int align_UF = __alignof(unsigned _Fract);
int align_UlF = __alignof(unsigned long _Fract);
-// CHECK-NEXT: @size_UsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @size_UF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @size_UlF = {{.*}}global i{{[0-9]+}} 8
-// CHECK-NEXT: @align_UsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @align_UF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @align_UlF = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @size_UsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @size_UF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_UlF = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_UsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @align_UF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_UlF = {{.*}}global i{{[0-9]+}} 4
/* Aliased _Accum */
@@ -92,12 +92,12 @@ int align_sF = __alignof(short _Fract);
int align_F = __alignof(_Fract);
int align_lF = __alignof(long _Fract);
-// CHECK-NEXT: @size_sF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @size_F = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @size_lF = {{.*}}global i{{[0-9]+}} 8
-// CHECK-NEXT: @align_sF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @align_F = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @align_lF = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @size_sF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @size_F = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_lF = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_sF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @align_F = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_lF = {{.*}}global i{{[0-9]+}} 4
/* Saturated signed _Accum */
@@ -140,12 +140,12 @@ int align_SatSsF = __alignof(_Sat signed short _Fract);
int align_SatSF = __alignof(_Sat signed _Fract);
int align_SatSlF = __alignof(_Sat signed long _Fract);
-// CHECK-NEXT: @size_SatSsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @size_SatSF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @size_SatSlF = {{.*}}global i{{[0-9]+}} 8
-// CHECK-NEXT: @align_SatSsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @align_SatSF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @align_SatSlF = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @size_SatSsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @size_SatSF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_SatSlF = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_SatSsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @align_SatSF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_SatSlF = {{.*}}global i{{[0-9]+}} 4
/* Saturated unsigned _Fract */
@@ -156,12 +156,12 @@ int align_SatUsF = __alignof(_Sat unsigned short _Fract);
int align_SatUF = __alignof(_Sat unsigned _Fract);
int align_SatUlF = __alignof(_Sat unsigned long _Fract);
-// CHECK-NEXT: @size_SatUsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @size_SatUF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @size_SatUlF = {{.*}}global i{{[0-9]+}} 8
-// CHECK-NEXT: @align_SatUsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @align_SatUF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @align_SatUlF = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @size_SatUsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @size_SatUF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_SatUlF = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_SatUsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @align_SatUF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_SatUlF = {{.*}}global i{{[0-9]+}} 4
/* Aliased saturated signed _Accum */
@@ -188,9 +188,9 @@ int align_SatsF = __alignof(_Sat short _Fract);
int align_SatF = __alignof(_Sat _Fract);
int align_SatlF = __alignof(_Sat long _Fract);
-// CHECK-NEXT: @size_SatsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @size_SatF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @size_SatlF = {{.*}}global i{{[0-9]+}} 8
-// CHECK-NEXT: @align_SatsF = {{.*}}global i{{[0-9]+}} 2
-// CHECK-NEXT: @align_SatF = {{.*}}global i{{[0-9]+}} 4
-// CHECK-NEXT: @align_SatlF = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @size_SatsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @size_SatF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_SatlF = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_SatsF = {{.*}}global i{{[0-9]+}} 1
+// CHECK-NEXT: @align_SatF = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_SatlF = {{.*}}global i{{[0-9]+}} 4
diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c
new file mode 100644
index 00000000000..47f7e9f8035
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_declarations.c
@@ -0,0 +1,113 @@
+// RUN: %clang -ffixed-point -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang -ffixed-point -S -emit-llvm %s -o - --target=x86_64-scei-ps4-ubuntu-fast | FileCheck %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum; // CHECK-DAG: @s_short_accum = {{.*}}global i16 0, align 2
+signed _Accum s_accum; // CHECK-DAG: @s_accum = {{.*}}global i32 0, align 4
+signed long _Accum s_long_accum; // CHECK-DAG: @s_long_accum = {{.*}}global i64 0, align 8
+unsigned short _Accum u_short_accum; // CHECK-DAG: @u_short_accum = {{.*}}global i16 0, align 2
+unsigned _Accum u_accum; // CHECK-DAG: @u_accum = {{.*}}global i32 0, align 4
+unsigned long _Accum u_long_accum; // CHECK-DAG: @u_long_accum = {{.*}}global i64 0, align 8
+signed short _Fract s_short_fract; // CHECK-DAG: @s_short_fract = {{.*}}global i8 0, align 1
+signed _Fract s_fract; // CHECK-DAG: @s_fract = {{.*}}global i16 0, align 2
+signed long _Fract s_long_fract; // CHECK-DAG: @s_long_fract = {{.*}}global i32 0, align 4
+unsigned short _Fract u_short_fract; // CHECK-DAG: @u_short_fract = {{.*}}global i8 0, align 1
+unsigned _Fract u_fract; // CHECK-DAG: @u_fract = {{.*}}global i16 0, align 2
+unsigned long _Fract u_long_fract; // CHECK-DAG: @u_long_fract = {{.*}}global i32 0, align 4
+
+// Aliased
+short _Accum short_accum; // CHECK-DAG: @short_accum = {{.*}}global i16 0, align 2
+_Accum accum; // CHECK-DAG: @accum = {{.*}}global i32 0, align 4
+long _Accum long_accum; // CHECK-DAG: @long_accum = {{.*}}global i64 0, align 8
+short _Fract short_fract; // CHECK-DAG: @short_fract = {{.*}}global i8 0, align 1
+_Fract fract; // CHECK-DAG: @fract = {{.*}}global i16 0, align 2
+long _Fract long_fract; // CHECK-DAG: @long_fract = {{.*}}global i32 0, align 4
+
+// Primary saturated
+_Sat signed short _Accum sat_s_short_accum; // CHECK-DAG: @sat_s_short_accum = {{.*}}global i16 0, align 2
+_Sat signed _Accum sat_s_accum; // CHECK-DAG: @sat_s_accum = {{.*}}global i32 0, align 4
+_Sat signed long _Accum sat_s_long_accum; // CHECK-DAG: @sat_s_long_accum = {{.*}}global i64 0, align 8
+_Sat unsigned short _Accum sat_u_short_accum; // CHECK-DAG: @sat_u_short_accum = {{.*}}global i16 0, align 2
+_Sat unsigned _Accum sat_u_accum; // CHECK-DAG: @sat_u_accum = {{.*}}global i32 0, align 4
+_Sat unsigned long _Accum sat_u_long_accum; // CHECK-DAG: @sat_u_long_accum = {{.*}}global i64 0, align 8
+_Sat signed short _Fract sat_s_short_fract; // CHECK-DAG: @sat_s_short_fract = {{.*}}global i8 0, align 1
+_Sat signed _Fract sat_s_fract; // CHECK-DAG: @sat_s_fract = {{.*}}global i16 0, align 2
+_Sat signed long _Fract sat_s_long_fract; // CHECK-DAG: @sat_s_long_fract = {{.*}}global i32 0, align 4
+_Sat unsigned short _Fract sat_u_short_fract; // CHECK-DAG: @sat_u_short_fract = {{.*}}global i8 0, align 1
+_Sat unsigned _Fract sat_u_fract; // CHECK-DAG: @sat_u_fract = {{.*}}global i16 0, align 2
+_Sat unsigned long _Fract sat_u_long_fract; // CHECK-DAG: @sat_u_long_fract = {{.*}}global i32 0, align 4
+
+// Aliased saturated
+_Sat short _Accum sat_short_accum; // CHECK-DAG: @sat_short_accum = {{.*}}global i16 0, align 2
+_Sat _Accum sat_accum; // CHECK-DAG: @sat_accum = {{.*}}global i32 0, align 4
+_Sat long _Accum sat_long_accum; // CHECK-DAG: @sat_long_accum = {{.*}}global i64 0, align 8
+_Sat short _Fract sat_short_fract; // CHECK-DAG: @sat_short_fract = {{.*}}global i8 0, align 1
+_Sat _Fract sat_fract; // CHECK-DAG: @sat_fract = {{.*}}global i16 0, align 2
+_Sat long _Fract sat_long_fract; // CHECK-DAG: @sat_long_fract = {{.*}}global i32 0, align 4
+
+/* Fixed point literals */
+short _Accum short_accum_literal = 2.5hk; // CHECK-DAG: @short_accum_literal = {{.*}}global i16 320, align 2
+_Accum accum_literal = 2.5k; // CHECK-DAG: @accum_literal = {{.*}}global i32 81920, align 4
+long _Accum long_accum_literal = 2.5lk; // CHECK-DAG: @long_accum_literal = {{.*}}global i64 5368709120, align 8
+short _Fract short_fract_literal = 0.5hr; // CHECK-DAG: @short_fract_literal = {{.*}}global i8 64, align 1
+_Fract fract_literal = 0.5r; // CHECK-DAG: @fract_literal = {{.*}}global i16 16384, align 2
+long _Fract long_fract_literal = 0.5lr; // CHECK-DAG: @long_fract_literal = {{.*}}global i32 1073741824, align 4
+
+unsigned short _Accum u_short_accum_literal = 2.5uhk; // CHECK-DAG: @u_short_accum_literal = {{.*}}global i16 640, align 2
+unsigned _Accum u_accum_literal = 2.5uk; // CHECK-DAG: @u_accum_literal = {{.*}}global i32 163840, align 4
+unsigned long _Accum u_long_accum_literal = 2.5ulk; // CHECK-DAG: @u_long_accum_literal = {{.*}}global i64 10737418240, align 8
+unsigned short _Fract u_short_fract_literal = 0.5uhr; // CHECK-DAG: @u_short_fract_literal = {{.*}}global i8 -128, align 1
+unsigned _Fract u_fract_literal = 0.5ur; // CHECK-DAG: @u_fract_literal = {{.*}}global i16 -32768, align 2
+unsigned long _Fract u_long_fract_literal = 0.5ulr; // CHECK-DAG: @u_long_fract_literal = {{.*}}global i32 -2147483648, align 4
+
+// Max literal values
+short _Accum short_accum_max = 255.9999999999999999hk; // CHECK-DAG: @short_accum_max = {{.*}}global i16 32767, align 2
+_Accum accum_max = 65535.9999999999999999k; // CHECK-DAG: @accum_max = {{.*}}global i32 2147483647, align 4
+long _Accum long_accum_max = 4294967295.9999999999999999lk; // CHECK-DAG: @long_accum_max = {{.*}}global i64 9223372036854775807, align 8
+unsigned short _Accum u_short_accum_max = 255.9999999999999999uhk; // CHECK-DAG: @u_short_accum_max = {{.*}}global i16 -1, align 2
+unsigned _Accum u_accum_max = 65535.9999999999999999uk; // CHECK-DAG: @u_accum_max = {{.*}}global i32 -1, align 4
+unsigned long _Accum u_long_accum_max = 4294967295.9999999999999999ulk; // CHECK-DAG: @u_long_accum_max = {{.*}}global i64 -1, align 8
+
+short _Fract short_fract_max = 0.9999999999999999hr; // CHECK-DAG: @short_fract_max = {{.*}}global i8 127, align 1
+_Fract fract_max = 0.9999999999999999r; // CHECK-DAG: @fract_max = {{.*}}global i16 32767, align 2
+long _Fract long_fract_max = 0.9999999999999999lr; // CHECK-DAG: @long_fract_max = {{.*}}global i32 2147483647, align 4
+unsigned short _Fract u_short_fract_max = 0.9999999999999999uhr; // CHECK-DAG: @u_short_fract_max = {{.*}}global i8 -1, align 1
+unsigned _Fract u_fract_max = 0.9999999999999999ur; // CHECK-DAG: @u_fract_max = {{.*}}global i16 -1, align 2
+unsigned long _Fract u_long_fract_max = 0.9999999999999999ulr; // CHECK-DAG: @u_long_fract_max = {{.*}}global i32 -1, align 4
+
+// Fracts may be exactly one but evaluate to the Fract max
+short _Fract short_fract_one = 1.0hr; // CHECK-DAG: @short_fract_one = {{.*}}global i8 127, align 1
+_Fract fract_one = 1.0r; // CHECK-DAG: @fract_one = {{.*}}global i16 32767, align 2
+long _Fract long_fract_one = 1.0lr; // CHECK-DAG: @long_fract_one = {{.*}}global i32 2147483647, align 4
+unsigned short _Fract u_short_fract_one = 1.0uhr; // CHECK-DAG: @u_short_fract_one = {{.*}}global i8 -1, align 1
+unsigned _Fract u_fract_one = 1.0ur; // CHECK-DAG: @u_fract_one = {{.*}}global i16 -1, align 2
+unsigned long _Fract u_long_fract_one = 1.0ulr; // CHECK-DAG: @u_long_fract_one = {{.*}}global i32 -1, align 4
+
+short _Fract short_fract_exp_one = 0.1e1hr; // CHECK-DAG: @short_fract_exp_one = {{.*}}global i8 127, align 1
+_Fract fract_exp_one = 0.1e1r; // CHECK-DAG: @fract_exp_one = {{.*}}global i16 32767, align 2
+long _Fract long_fract_exp_one = 0.1e1lr; // CHECK-DAG: @long_fract_exp_one = {{.*}}global i32 2147483647, align 4
+unsigned short _Fract u_short_fract_exp_one = 0.1e1uhr; // CHECK-DAG: @u_short_fract_exp_one = {{.*}}global i8 -1, align 1
+unsigned _Fract u_fract_exp_one = 0.1e1ur; // CHECK-DAG: @u_fract_exp_one = {{.*}}global i16 -1, align 2
+unsigned long _Fract u_long_fract_exp_one = 0.1e1ulr; // CHECK-DAG: @u_long_fract_exp_one = {{.*}}global i32 -1, align 4
+
+short _Fract short_fract_hex_exp_one = 0x0.8p1hr; // CHECK-DAG: @short_fract_hex_exp_one = {{.*}}global i8 127, align 1
+_Fract fract_hex_exp_one = 0x0.8p1r; // CHECK-DAG: @fract_hex_exp_one = {{.*}}global i16 32767, align 2
+long _Fract long_fract_hex_exp_one = 0x0.8p1lr; // CHECK-DAG: @long_fract_hex_exp_one = {{.*}}global i32 2147483647, align 4
+unsigned short _Fract u_short_fract_hex_exp_one = 0x0.8p1uhr; // CHECK-DAG: @u_short_fract_hex_exp_one = {{.*}}global i8 -1, align 1
+unsigned _Fract u_fract_hex_exp_one = 0x0.8p1ur; // CHECK-DAG: @u_fract_hex_exp_one = {{.*}}global i16 -1, align 2
+unsigned long _Fract u_long_fract_hex_exp_one = 0x0.8p1ulr; // CHECK-DAG: @u_long_fract_hex_exp_one = {{.*}}global i32 -1, align 4
+
+// Expsilon values
+short _Accum short_accum_eps = 0x1p-7hk; // CHECK-DAG: @short_accum_eps = {{.*}}global i16 1, align 2
+_Accum accum_eps = 0x1p-15k; // CHECK-DAG: @accum_eps = {{.*}}global i32 1, align 4
+long _Accum long_accum_eps = 0x1p-31lk; // CHECK-DAG: @long_accum_eps = {{.*}}global i64 1, align 8
+unsigned short _Accum u_short_accum_eps = 0x1p-8uhk; // CHECK-DAG: @u_short_accum_eps = {{.*}}global i16 1, align 2
+unsigned _Accum u_accum_eps = 0x1p-16uk; // CHECK-DAG: @u_accum_eps = {{.*}}global i32 1, align 4
+unsigned long _Accum u_long_accum_eps = 0x1p-32ulk; // CHECK-DAG: @u_long_accum_eps = {{.*}}global i64 1, align 8
+
+short _Fract short_fract_eps = 0x1p-7hr; // CHECK-DAG: @short_fract_eps = {{.*}}global i8 1, align 1
+_Fract fract_eps = 0x1p-15r; // CHECK-DAG: @fract_eps = {{.*}}global i16 1, align 2
+long _Fract long_fract_eps = 0x1p-31lr; // CHECK-DAG: @long_fract_eps = {{.*}}global i32 1, align 4
+unsigned short _Fract u_short_fract_eps = 0x1p-8uhr; // CHECK-DAG: @u_short_fract_eps = {{.*}}global i8 1, align 1
+unsigned _Fract u_fract_eps = 0x1p-16ur; // CHECK-DAG: @u_fract_eps = {{.*}}global i16 1, align 2
+unsigned long _Fract u_long_fract_eps = 0x1p-32ulr; // CHECK-DAG: @u_long_fract_eps = {{.*}}global i32 1, align 4
diff --git a/clang/test/Frontend/fixed_point_errors.c b/clang/test/Frontend/fixed_point_errors.c
index 7f0e0099576..f55fc82f917 100644
--- a/clang/test/Frontend/fixed_point_errors.c
+++ b/clang/test/Frontend/fixed_point_errors.c
@@ -78,6 +78,50 @@ _Sat char c; // expected-error{{'_Sat' specifier is only valid on '
_Sat int i; // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'int'}}
_Sat _Sat _Fract fract; // expected-warning{{duplicate '_Sat' declaration specifier}}
+
+/* Literals that cannot fit into types */
+signed short _Accum s_short_accum = 256.0hk; // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Accum u_short_accum = 256.0uhk; // expected-error{{this value is too large for this fixed point type}}
+signed _Accum s_accum = 65536.0k; // expected-error{{this value is too large for this fixed point type}}
+unsigned _Accum u_accum = 65536.0uk; // expected-error{{this value is too large for this fixed point type}}
+signed long _Accum s_long_accum = 4294967296.0lk; // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Accum u_long_accum = 4294967296.0ulk; // expected-error{{this value is too large for this fixed point type}}
+
+// Large values from decimal exponents
+short _Accum short_accum_exp = 2.56e2hk; // expected-error{{this value is too large for this fixed point type}}
+_Accum accum_exp = 6.5536e4k; // expected-error{{this value is too large for this fixed point type}}
+long _Accum long_accum_exp = 4.294967296e9lk; // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Accum u_short_accum_exp = 2.56e2uhk; // expected-error{{this value is too large for this fixed point type}}
+unsigned _Accum u_accum_exp = 6.5536e4uk; // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Accum u_long_accum_exp = 4.294967296e9ulk; // expected-error{{this value is too large for this fixed point type}}
+
+// Large value from hexidecimal exponents
+short _Accum short_accum_hex_exp = 0x1p8hk; // expected-error{{this value is too large for this fixed point type}}
+_Accum accum_hex_exp = 0x1p16k; // expected-error{{this value is too large for this fixed point type}}
+long _Accum long_accum_hex_exp = 0x1p32lk; // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Accum u_short_accum_hex_exp = 0x1p8uhk; // expected-error{{this value is too large for this fixed point type}}
+unsigned _Accum u_accum_hex_exp = 0x1p16uk; // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Accum u_long_accum_hex_exp = 0x1p32ulk; // expected-error{{this value is too large for this fixed point type}}
+
+// Very large exponent
+_Accum x = 1e1000000000000000000000000000000000k; // expected-error{{this value is too large for this fixed point type}}
+
+/* Although _Fract's cannot equal 1, _Fract literals written as 1 are allowed
+ * and the underlying value represents the max value for that _Fract type. */
+short _Fract short_fract_above_1 = 1.1hr; // expected-error{{this value is too large for this fixed point type}}
+_Fract fract_above_1 = 1.1r; // expected-error{{this value is too large for this fixed point type}}
+long _Fract long_fract_above_1 = 1.1lr; // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Fract u_short_fract_above_1 = 1.1uhr; // expected-error{{this value is too large for this fixed point type}}
+unsigned _Fract u_fract_above_1 = 1.1ur; // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Fract u_long_fract_above_1 = 1.1ulr; // expected-error{{this value is too large for this fixed point type}}
+
+short _Fract short_fract_hex_exp = 0x0.fp1hr; // expected-error{{this value is too large for this fixed point type}}
+_Fract fract_hex_exp = 0x0.fp1r; // expected-error{{this value is too large for this fixed point type}}
+long _Fract long_fract_hex_exp = 0x0.fp1lr; // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Fract u_short_fract_hex_exp = 0x0.fp1uhr; // expected-error{{this value is too large for this fixed point type}}
+unsigned _Fract u_fract_hex_exp = 0x0.fp1ur; // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Fract u_long_fract_hex_exp = 0x0.fp1ulr; // expected-error{{this value is too large for this fixed point type}}
+
/* Do not allow typedef to be used with typedef'd types */
typedef short _Fract shortfract_t;
typedef short _Accum shortaccum_t;
@@ -91,3 +135,16 @@ _Sat fract_t td_sat_fract; // expected-error{{'_Sat' specifier
_Sat accum_t td_sat_accum; // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat longfract_t td_sat_long_fract; // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat longaccum_t td_sat_long_accum; // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
+
+/* Bad suffixes */
+_Accum fk = 1.0fk; // expected-error{{invalid suffix 'fk' on integer constant}}
+_Accum kk = 1.0kk; // expected-error{{invalid suffix 'kk' on integer constant}}
+_Accum rk = 1.0rk; // expected-error{{invalid suffix 'rk' on integer constant}}
+_Accum rk = 1.0rr; // expected-error{{invalid suffix 'rr' on integer constant}}
+_Accum qk = 1.0qr; // expected-error{{invalid suffix 'qr' on integer constant}}
+
+/* Using wrong exponent notation */
+_Accum dec_with_hex_exp1 = 0.1p10k; // expected-error{{invalid suffix 'p10k' on integer constant}}
+_Accum dec_with_hex_exp2 = 0.1P10k; // expected-error{{invalid suffix 'P10k' on integer constant}}
+_Accum hex_with_dex_exp1 = 0x0.1e10k; // expected-error{{hexadecimal floating constant requires an exponent}}
+_Accum hex_with_dex_exp2 = 0x0.1E10k; // expected-error{{hexadecimal floating constant requires an exponent}}
diff --git a/clang/test/Frontend/fixed_point_same_fbits.c b/clang/test/Frontend/fixed_point_same_fbits.c
new file mode 100644
index 00000000000..ad88d1a73b7
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_same_fbits.c
@@ -0,0 +1,28 @@
+// RUN: %clang -ffixed-point -S -emit-llvm -o - %s | FileCheck %s -check-prefix=DEFAULT
+// RUN: %clang -ffixed-point -fsame-fbits -S -emit-llvm -o - %s | FileCheck %s -check-prefix=SAME
+
+/* The scale for unsigned fixed point types should be the same as that of signed
+ * fixed point types when -fsame-fbits is enabled. */
+
+void func() {
+ unsigned short _Accum u_short_accum = 0.5uhk;
+ unsigned _Accum u_accum = 0.5uk;
+ unsigned long _Accum u_long_accum = 0.5ulk;
+ unsigned short _Fract u_short_fract = 0.5uhr;
+ unsigned _Fract u_fract = 0.5ur;
+ unsigned long _Fract u_long_fract = 0.5ulr;
+
+// DEFAULT: store i16 128, i16* %u_short_accum, align 2
+// DEFAULT: store i32 32768, i32* %u_accum, align 4
+// DEFAULT: store i64 2147483648, i64* %u_long_accum, align 8
+// DEFAULT: store i8 -128, i8* %u_short_fract, align 1
+// DEFAULT: store i16 -32768, i16* %u_fract, align 2
+// DEFAULT: store i32 -2147483648, i32* %u_long_fract, align 4
+
+// SAME: store i16 64, i16* %u_short_accum, align 2
+// SAME: store i32 16384, i32* %u_accum, align 4
+// SAME: store i64 1073741824, i64* %u_long_accum, align 8
+// SAME: store i8 64, i8* %u_short_fract, align 1
+// SAME: store i16 16384, i16* %u_fract, align 2
+// SAME: store i32 1073741824, i32* %u_long_fract, align 4
+}
OpenPOWER on IntegriCloud