[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-31 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: lib/Sema/DeclSpec.cpp:1123
+if (!(TypeSpecType == TST_accum || TypeSpecType == TST_fract)) {
+  S.Diag(TSSatLoc, diag::err_invalid_saturation_spec)
+  << getSpecifierName((TST)TypeSpecType, Policy);

ebevhan wrote:
> Handling this case here means that placing _Sat on something other than 
> exactly a fixed-point type is a parsing error rather than a semantic error. 
> How does this handle _Sat on sugared types? Should _Sat on things like 
> typedefs work?
> 
>   typedef _Fract myfract;
>   _Sat myfract F;
> 
> The primary issue (and this is one that we have encountered as well) is that 
> you cannot have a true _Sat typedef since _Sat only exists as part of builtin 
> types. You need to desugar/canonicalize the type and then do 
> getCorrespondingSaturatingType (or have getCorrespondingSaturatingType look 
> at the canonical type internally).
I think _Sat is analogous to _Complex where it only works with specific builtin 
types, albeit the only builtin type _Complex doesn't work with is _Bool.

Currently this example would throw the error `'_Sat' specifier is only valid on 
'_Fract' or '_Accum', not 'type-name'` which is similar to what _Complex does 
when paired with a typedef:

```
typedef double mydouble;
mydouble _Complex D;  // _Complex type-name' is invalid
```

I don't see this as a big problem right now, but am willing to come back to 
this in the future if it becomes more urgent. For now, I added a test that 
asserts this error is thrown.



Comment at: lib/Sema/SemaType.cpp:1410
+
+if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned)
+  Result = fixedpoint::getCorrespondingSignedType(Context, Result);

ebevhan wrote:
> The logic is a bit reversed. The default should be to select the signed 
> variant, and if the TSS is unsigned, then convert it to the unsigned variant.
Using getCorrespondingUnsignedType(). Also changed 
getCorrespondingUnsignedType() to accept fixed point types.


Repository:
  rC Clang

https://reviews.llvm.org/D46911



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-31 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: lib/Basic/TargetInfo.cpp:45
+  AccumWidth = AccumAlign = 32;
+  LongAccumWidth = LongAccumAlign = 64;
   SuitableAlign = 64;

leonardchan wrote:
> ebevhan wrote:
> > leonardchan wrote:
> > > rsmith wrote:
> > > > jfb wrote:
> > > > > This seems weird because Targets which don't have these values for 
> > > > > the non-Accum versions will have .e.g. `sizeof(short) != sizeof(short 
> > > > > _Accum)`. Is there a point in ever having `_Accum` differ in size, 
> > > > > width, and alignment from the underlying type? If not, can you set 
> > > > > these values after the sub-target has specified its preferences?
> > > > I'm uncomfortable about opting all targets into this behavior with 
> > > > these default values; this will result in an ABI break if later a 
> > > > target updates these to the correct values. A per-target 
> > > > `AccumSupported` flag would help substantially. But this is OK for the 
> > > > short term while you're still working on the feature.
> > > > 
> > > > We'll also need the target to inform us of the number of integer and 
> > > > fractional bits for each such type.
> > > The integral and fractional bits will be set in the target and is 
> > > available in a later patch.
> > > We'll also need the target to inform us of the number of integer and 
> > > fractional bits for each such type.
> > 
> > I believe the only one that is needed is for the number of fractional bits; 
> > the number of integer bits is implied by the difference between the type 
> > width and fractional bits. I think I mention this in one of the other 
> > patches.
> > 
> > 
> You're right. I was stuck in the mindset that we would be providing an 
> integral and fractional value.
> The integral and fractional bits will be set in the target and is available 
> in a later patch.

I mean just the fractional bits since the integral will just be the bit width 
minus fractional.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-31 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: include/clang/Basic/TokenKinds.def:393
+// ISO/IEC JTC1 SC22 WG14 N1169 Extension
+KEYWORD(_Accum  , KEYALL)
+

rsmith wrote:
> leonardchan wrote:
> > jfb wrote:
> > > ebevhan wrote:
> > > > I believe that having KEYALL will enable the keyword even if 
> > > > -fno-fixed-point is given. Is this desired? It will mean that `_Accum` 
> > > > will not be a valid identifier in standard C regardless of the flag.
> > > That seems fine: identifiers starting with underscore and a capital 
> > > letter already aren't valid identifiers in C and C++ because they're 
> > > reserved for the implementation.
> > I think my test for `-fno-fixed-point` already catches this, but I did not 
> > notice until now the `KEYNOCXX` keyword until now. Using this instead 
> > allows for not having to check if the language is c++ since `_Accum` is no 
> > longer treated as a typename. The corresponding test checking fixed points 
> > in c++ has been updated to reflect this.
> Just to make sure we're on the same page: it's OK to disable this feature for 
> C++ while you're working on it, but it needs to support C++ by the time 
> you're done.
That's the goal. Just disabled in c++ for now with the end goal of getting c++ 
support. Right now I'm waiting for these types to be added in the next Itanium 
ABI, which I believe you responded to on Github. Afterwards I'll need to 
request Microsoft mangling.



Comment at: lib/Basic/TargetInfo.cpp:45
+  AccumWidth = AccumAlign = 32;
+  LongAccumWidth = LongAccumAlign = 64;
   SuitableAlign = 64;

rsmith wrote:
> jfb wrote:
> > This seems weird because Targets which don't have these values for the 
> > non-Accum versions will have .e.g. `sizeof(short) != sizeof(short _Accum)`. 
> > Is there a point in ever having `_Accum` differ in size, width, and 
> > alignment from the underlying type? If not, can you set these values after 
> > the sub-target has specified its preferences?
> I'm uncomfortable about opting all targets into this behavior with these 
> default values; this will result in an ABI break if later a target updates 
> these to the correct values. A per-target `AccumSupported` flag would help 
> substantially. But this is OK for the short term while you're still working 
> on the feature.
> 
> We'll also need the target to inform us of the number of integer and 
> fractional bits for each such type.
The integral and fractional bits will be set in the target and is available in 
a later patch.



Comment at: lib/Basic/TargetInfo.cpp:45
+  AccumWidth = AccumAlign = 32;
+  LongAccumWidth = LongAccumAlign = 64;
   SuitableAlign = 64;

ebevhan wrote:
> leonardchan wrote:
> > rsmith wrote:
> > > jfb wrote:
> > > > This seems weird because Targets which don't have these values for the 
> > > > non-Accum versions will have .e.g. `sizeof(short) != sizeof(short 
> > > > _Accum)`. Is there a point in ever having `_Accum` differ in size, 
> > > > width, and alignment from the underlying type? If not, can you set 
> > > > these values after the sub-target has specified its preferences?
> > > I'm uncomfortable about opting all targets into this behavior with these 
> > > default values; this will result in an ABI break if later a target 
> > > updates these to the correct values. A per-target `AccumSupported` flag 
> > > would help substantially. But this is OK for the short term while you're 
> > > still working on the feature.
> > > 
> > > We'll also need the target to inform us of the number of integer and 
> > > fractional bits for each such type.
> > The integral and fractional bits will be set in the target and is available 
> > in a later patch.
> > We'll also need the target to inform us of the number of integer and 
> > fractional bits for each such type.
> 
> I believe the only one that is needed is for the number of fractional bits; 
> the number of integer bits is implied by the difference between the type 
> width and fractional bits. I think I mention this in one of the other patches.
> 
> 
You're right. I was stuck in the mindset that we would be providing an integral 
and fractional value.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-31 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 149305.
leonardchan marked 6 inline comments as done.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+_Accum accum;   // expected-error{{unknown type name '_Accum'}}
Index: test/Frontend/fixed_point_errors.c
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+/* We do not yet support long long. No recommended bit widths are given for this
+ * size. */
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+
+/* Although _Complex types work with floating point numbers, the extension
+ * provides no info for complex fixed point types. */
+
+_Complex signed short _Accum cmplx_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed _Accum cmplx_s_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed long _Accum cmplx_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned short _Accum cmplx_u_short_accum; // 

[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-30 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 149169.
leonardchan added a comment.

Forgot to include tests for the `_Fract` and `_Sat` keywords in c++ usage


Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp

Index: test/Frontend/fixed_point_errors.cpp
===
--- test/Frontend/fixed_point_errors.cpp
+++ test/Frontend/fixed_point_errors.cpp
@@ -1,5 +1,9 @@
+// RUN: %clang_cc1 -x c++ %s -verify
 // RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
 
 // Name namgling is not provided for fixed point types in c++
 
 _Accum accum;   // expected-error{{unknown type name '_Accum'}}
+_Fract fract;   // expected-error{{unknown type name '_Fract'}}
+_Sat _Accum sat_accum;  // expected-error{{unknown type name '_Sat'}}
+// expected-error@-1{{expected ';' after top level declarator}}
Index: test/Frontend/fixed_point_errors.c
===
--- test/Frontend/fixed_point_errors.c
+++ test/Frontend/fixed_point_errors.c
@@ -5,6 +5,14 @@
 
 long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
 unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;   // expected-error{{'long long _Fract' is invalid}}
+
+_Sat long long _Accum sat_longlong_accum; // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract; // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
 
 /* Although _Complex types work with floating point numbers, the extension
  * provides no info for complex fixed point types. */
@@ -19,9 +27,53 @@
 _Complex _Accum cmplx_s_accum;  // expected-error{{'_Complex _Accum' is invalid}}
 _Complex long _Accum cmplx_s_long_accum;// expected-error{{'_Complex _Accum' is invalid}}
 
+_Complex signed short _Fract cmplx_s_short_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed _Fract cmplx_s_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed long _Fract cmplx_s_long_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned short _Fract cmplx_u_short_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned _Fract cmplx_u_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned long _Fract cmplx_u_long_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex short _Fract cmplx_s_short_fract;  // expected-error{{'_Complex _Fract' is invalid}}
+_Complex _Fract cmplx_s_fract;  // expected-error{{'_Complex _Fract' is invalid}}
+_Complex long _Fract cmplx_s_long_fract;// expected-error{{'_Complex _Fract' is invalid}}
+
+_Complex _Sat signed short _Accum cmplx_sat_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat signed _Accum cmplx_sat_s_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat signed long _Accum cmplx_sat_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned short _Accum cmplx_sat_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned _Accum cmplx_sat_u_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned long _Accum cmplx_sat_u_long_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat short _Accum 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-30 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: include/clang/Basic/TokenKinds.def:393
+// ISO/IEC JTC1 SC22 WG14 N1169 Extension
+KEYWORD(_Accum  , KEYALL)
+

jfb wrote:
> ebevhan wrote:
> > I believe that having KEYALL will enable the keyword even if 
> > -fno-fixed-point is given. Is this desired? It will mean that `_Accum` will 
> > not be a valid identifier in standard C regardless of the flag.
> That seems fine: identifiers starting with underscore and a capital letter 
> already aren't valid identifiers in C and C++ because they're reserved for 
> the implementation.
I think my test for `-fno-fixed-point` already catches this, but I did not 
notice until now the `KEYNOCXX` keyword until now. Using this instead allows 
for not having to check if the language is c++ since `_Accum` is no longer 
treated as a typename. The corresponding test checking fixed points in c++ has 
been updated to reflect this.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-30 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 149162.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -x c -verify %s
+// RUN: %clang_cc1 -x c -fno-fixed-point -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+_Accum accum;   // expected-error{{unknown type name '_Accum'}}
Index: test/Frontend/fixed_point_errors.c
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+/* We do not yet support long long. No recommended bit widths are given for this
+ * size. */
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+
+/* Although _Complex types work with floating point numbers, the extension
+ * provides no info for complex fixed point types. */
+
+_Complex signed short _Accum cmplx_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed _Accum cmplx_s_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed long _Accum cmplx_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned short _Accum cmplx_u_short_accum; // 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-29 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added a comment.

Hi all, I think I've addressed all comments on this patch and will be 
committing tomorrow morning unless anyone has any more comments they'd like to 
bring up.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-29 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: lib/Sema/SemaType.cpp:1430
 } else {
-  switch (DS.getTypeSpecWidth()) {
-case DeclSpec::TSW_short:
-  Result = Context.UnsignedShortAccumTy;
-  break;
-case DeclSpec::TSW_unspecified:
-  Result = Context.UnsignedAccumTy;
-  break;
-case DeclSpec::TSW_long:
-  Result = Context.UnsignedLongAccumTy;
-  break;
-case DeclSpec::TSW_longlong:
-  // TODO: Replace with diag
-  llvm_unreachable("Unable to specify long long as _Accum width");
-  break;
+  if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
+switch (DS.getTypeSpecWidth()) {

ebevhan wrote:
> You should probably use the 'getCorrespondingSaturatingType' function instead 
> of disambiguating the whole thing here again.
Also used getCorrespondingSignedType() for the signage


Repository:
  rC Clang

https://reviews.llvm.org/D46911



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-29 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148918.
leonardchan marked 4 inline comments as done.

Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c

Index: test/Frontend/fixed_point_errors.c
===
--- test/Frontend/fixed_point_errors.c
+++ test/Frontend/fixed_point_errors.c
@@ -5,6 +5,14 @@
 
 long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
 unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;   // expected-error{{'long long _Fract' is invalid}}
+
+_Sat long long _Accum sat_longlong_accum; // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract; // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
 
 /* Although _Complex types work with floating point numbers, the extension
  * provides no info for complex fixed point types. */
@@ -19,9 +27,53 @@
 _Complex _Accum cmplx_s_accum;  // expected-error{{'_Complex _Accum' is invalid}}
 _Complex long _Accum cmplx_s_long_accum;// expected-error{{'_Complex _Accum' is invalid}}
 
+_Complex signed short _Fract cmplx_s_short_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed _Fract cmplx_s_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed long _Fract cmplx_s_long_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned short _Fract cmplx_u_short_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned _Fract cmplx_u_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned long _Fract cmplx_u_long_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex short _Fract cmplx_s_short_fract;  // expected-error{{'_Complex _Fract' is invalid}}
+_Complex _Fract cmplx_s_fract;  // expected-error{{'_Complex _Fract' is invalid}}
+_Complex long _Fract cmplx_s_long_fract;// expected-error{{'_Complex _Fract' is invalid}}
+
+_Complex _Sat signed short _Accum cmplx_sat_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat signed _Accum cmplx_sat_s_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat signed long _Accum cmplx_sat_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned short _Accum cmplx_sat_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned _Accum cmplx_sat_u_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat unsigned long _Accum cmplx_sat_u_long_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat short _Accum cmplx_sat_s_short_accum;  // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat _Accum cmplx_sat_s_accum;  // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Sat long _Accum cmplx_sat_s_long_accum;// expected-error{{'_Complex _Accum' is invalid}}
+
+_Complex signed short _Fract cmplx_sat_s_short_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed _Fract cmplx_sat_s_fract;   // expected-error{{'_Complex _Fract' is invalid}}
+_Complex signed long _Fract cmplx_sat_s_long_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned short _Fract cmplx_sat_u_short_fract; // expected-error{{'_Complex _Fract' is invalid}}
+_Complex unsigned _Fract cmplx_sat_u_fract; // expected-error{{'_Complex _Fract' is invalid}}

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-25 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan marked 2 inline comments as done.
leonardchan added inline comments.



Comment at: include/clang/Driver/Options.td:882
 
+def enable_fixed_point : Flag<["-", "--"], "enable-fixed-point">, 
Group,
+ Flags<[CC1Option]>, HelpText<"Enable fixed point 
types">;

ebevhan wrote:
> Shouldn't this be an `-f` flag, like `-ffixed-point`? I'm not for or against 
> either, just wondering what anyone else thinks.
Makes sense since this flag is target independent.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-25 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148637.
leonardchan added a comment.

Changed flag names


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -x c -verify %s
+// RUN: %clang_cc1 -x c -fno-fixed-point -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{fixed point types are only allowed in C}}
+// expected-error@-1{{C++ requires a type specifier for all declarations}}
+long _Accum long_accum; // expected-error{{fixed point types are only allowed in C}}
Index: 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: include/clang/Basic/TargetInfo.h:382
+// enough bits to fit the minumum.
+if (getIntWidth() < MinSignedAccumDataBits)
+  return getLongWidth();

ebevhan wrote:
> I'm not sure I agree with this interpretation. It's simply not correct to 
> consider 'short' the 'underlying type' of 'short _Accum', 'int' the 
> 'underlying type' of '_Accum', etc. They are wholly independent and should 
> have separate settings altogether.
> 
> Asserting/ensuring that a target has set an invalid width for its types 
> should be done separately. This currently feels a bit like the TargetInfo is 
> guessing.
> 
> (For the record, the reason I'm requesting this change is because this 
> implementation does not work for us downstream.)
You're right. They should be different types. I was stuck in the mindset that 
`short _Accum` should be tied to `short`, `_Accum` be tied to `int`, etc.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148506.
leonardchan added a comment.

Re-added individual getters/members for _Accum types


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -enable-fixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{fixed point types are only allowed in C}}
+// expected-error@-1{{C++ requires a type specifier for all declarations}}
+long _Accum long_accum; // expected-error{{fixed point types are only 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added a comment.

In https://reviews.llvm.org/D46084#374, @jfb wrote:

> Can you also add a test for `_Bool _Accum`.
>
> Also, `-enable-fixed-point -x c++` failing.


.
Done. Also the failing c++ case is under `test/Frontend/fixed_point_errors.cpp`


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148481.
leonardchan marked 2 inline comments as done.
leonardchan added a comment.

- Added test case for `_Bool _Accum`
- Getters for the `_Accum` bit widths return values for their corresponding 
integral types (ie. `sizeof(short _Accum) == sizeof(short)`). The only case 
where this may not happen is if the target architecture uses 16 bits for an 
int. N1169 requires that a `signed/unsigned _Accum` hold at least 15 fractional 
bits and 4 integral bits. To be able to fit these bits, the size is upgraded to 
that of a long which is guaranteed to be large enough to hold them.


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_bit_widths.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -enable-fixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148452.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -enable-fixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{fixed point types are only allowed in C}}
+// expected-error@-1{{C++ requires a type specifier for all declarations}}
+long _Accum long_accum; // expected-error{{fixed point types are only allowed in C}}
Index: test/Frontend/fixed_point_errors.c
===
--- 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan marked 6 inline comments as done.
leonardchan added inline comments.



Comment at: lib/CodeGen/ItaniumCXXABI.cpp:2684
 
   // Types added here must also be added to EmitFundamentalRTTIDescriptors.
   switch (Ty->getKind()) {

rsmith wrote:
> Note this comment :)
Returned false for these types now. Not sure if these types should also be 
added to EmitFundamentalRTTIDescriptors since the OCL types do not appear under 
there.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-24 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148445.
leonardchan added a comment.

- Reverted changes involving name mangling since we will only support c++ for 
now. Will concurrently raise an issue on 
https://github.com/itanium-cxx-abi/cxx-abi/ to get characters for name mangling.
- Added a flag that needs to be provided to enable usage of fixed point types. 
Not including this flag and using fixed point types throws an error. Currently, 
this patch allows for these types to be used in all versions of C, but this can 
be narrowed down to specific versions of C.
- An error is thrown when using fixed point types in C++.
- Fixed point types are ignored during USRGeneration since the type only gets 
mangled in C++.
- Fixed point types their own width and alignment accessors/variables in 
TargetInfo.
- Updated debug info to use `DW_ATE_signed_fixed` and `DW_ATE_unsigned_fixed`.
- Added tests mixing _Accum with other type specifiers


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed _Accum s_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;// expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+  // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;   // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -enable-fixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-23 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added a comment.

After further discussion, we think the best approach for now would be only 
supporting fixed point types in C, then go back and support C++ once there is a 
standardized way for mangling the fixed point types under itanium.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-23 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: include/clang/Basic/DiagnosticCommonKinds.td:172
+def err_fixed_point_only_allowed_in_c : Error<
+  "Fixed point types are only allowed in C">;
 

leonardchan wrote:
> leonardchan wrote:
> > rsmith wrote:
> > > Diagnostics should not be capitalized. Also, we generally allow 
> > > conforming C extensions to be used in other languages unless there is a 
> > > really good reason not to.
> > We decided not to allow fixed point types in other languages because there 
> > is no specification provided in N1169 for addressing some features in other 
> > languages. Using C++ as an example, N1169 does not provide recommended 
> > characters when name mangling so we do not allow this in C++.
> Actually, scratch that. We will be enabling it since GCC does. Will update 
> this and other relevant C++ related code appropriately.
Actually, the main thing that was preventing us from allowing this in C++ was 
no standardized characters for name mangling. GCC seems to use the same 
characters as some integral types (`short _Accum` uses `s`, `_Accum` uses `i`, 
...) but this would mean that a function that takes a `short _Accum` as a sole 
argument would also be mangled the same as a similarly named function that 
takes a `short`.

Would copying GCC take priority over not having characters specific for these 
types? This standard also proposes 24 different types, of which only 6 are 
included in this patch.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-23 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: include/clang/Basic/DiagnosticCommonKinds.td:172
+def err_fixed_point_only_allowed_in_c : Error<
+  "Fixed point types are only allowed in C">;
 

leonardchan wrote:
> rsmith wrote:
> > Diagnostics should not be capitalized. Also, we generally allow conforming 
> > C extensions to be used in other languages unless there is a really good 
> > reason not to.
> We decided not to allow fixed point types in other languages because there is 
> no specification provided in N1169 for addressing some features in other 
> languages. Using C++ as an example, N1169 does not provide recommended 
> characters when name mangling so we do not allow this in C++.
Actually, scratch that. We will be enabling it since GCC does. Will update this 
and other relevant C++ related code appropriately.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-23 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added a subscriber: sammccall.
leonardchan added inline comments.



Comment at: include/clang/Basic/DiagnosticCommonKinds.td:172
+def err_fixed_point_only_allowed_in_c : Error<
+  "Fixed point types are only allowed in C">;
 

rsmith wrote:
> Diagnostics should not be capitalized. Also, we generally allow conforming C 
> extensions to be used in other languages unless there is a really good reason 
> not to.
We decided not to allow fixed point types in other languages because there is 
no specification provided in N1169 for addressing some features in other 
languages. Using C++ as an example, N1169 does not provide recommended 
characters when name mangling so we do not allow this in C++.



Comment at: lib/AST/ItaniumMangle.cpp:2552
+  case BuiltinType::ULongAccum:
+llvm_unreachable("Fixed point types are disabled for c++");
   case BuiltinType::Half:

rsmith wrote:
> Please check what GCC uses to mangle these, and follow suit; if GCC doesn't 
> have a mangling, you can use a vendor mangling (`u6_Accum`) or produce an 
> error for now, but please open an issue at 
> https://github.com/itanium-cxx-abi/cxx-abi/ to pick a real mangling.
It seems that GCC uses the characters for each fixed point type's corresponding 
integral type (https://github.com/gcc-mirror/gcc/blob/master/gcc/cp/mangle.c). 
Will follow up on this if we end up enabling fixed point types for C++.



Comment at: lib/CodeGen/CGDebugInfo.cpp:678-681
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
 Encoding = llvm::dwarf::DW_ATE_unsigned;

rsmith wrote:
> @echristo @dblaikie Is this appropriate?
My bad, this should be changed to `DW_ATE_signed_fixed` and 
`DW_ATE_unsigned_fixed`



Comment at: lib/Index/USRGeneration.cpp:691
+case BuiltinType::ULongAccum:
+  llvm_unreachable("No USR name mangling for fixed point types.");
 case BuiltinType::Float16:

rsmith wrote:
> leonardchan wrote:
> > phosek wrote:
> > > We need some solution for fixed point types.
> > Added character ~ to indicate fixed point type followed by string detailing 
> > the type. I have not added a test to it because logically, I do not think 
> > we will ever reach that point. This logic is implemented in the VisitType 
> > method, which mostly gets called by visitors to c++ nodes like 
> > VisitTemplateParameterList, but we have disabled the use of fixed point 
> > types in c++. VisitType does get called in VisitFunctionDecl but the 
> > function exits early since we are not reading c++ (line 
> > lib/Index/USRGeneration.cpp:238).
> @rjmccall Is this an acceptable USR encoding? (Is our USR encoding scheme 
> documented anywhere?)
I chatted with @sammccall about this who said it was ok to add these types if 
no one opposed this. I posted this on cfe-dev also and it seemed that no one 
spoke up about it, so I thought this was ok.

I also couldn't find any standard or documentation about reserving characters 
for USR. It doesn't seem that USR is also parsed in any way, so I don't think 
I'm breaking anything (running ninja check-all passes).

And unless we also do enable this for C++, this code actually may not be run 
since this method will not be visited if limited to C.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148148.
leonardchan added a comment.

pulled changes from source tree


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -546,6 +552,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6818,6 +6818,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148121.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = Context.LongAccumTy;
+  break;
+case PREDEF_TYPE_USHORT_ACCUM_ID:

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148117.
leonardchan marked an inline comment as done.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = Context.LongAccumTy;
+  

[PATCH] D46986: [Fixed Point Arithmetic] Validation Test for Fixed Point Binary Operations and Saturated Addition

2018-05-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148116.
leonardchan added a comment.

- formatting
- Running `lli` threw a segfault in the test, though this was probably because 
it was using whatever hist jit was available to optimize the code instead of 
just interpreting it. Forcing it just interpret fixes this.


Repository:
  rC Clang

https://reviews.llvm.org/D46986

Files:
  include/clang/AST/Type.h
  include/clang/Basic/FixedPoint.h.in
  lib/AST/Type.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_all_builtin_operations.c
  test/Frontend/fixed_point_builtin_macros.c

Index: test/Frontend/fixed_point_builtin_macros.c
===
--- test/Frontend/fixed_point_builtin_macros.c
+++ test/Frontend/fixed_point_builtin_macros.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli -force-interpreter=true
 
 #define assert(b) if (!(b)) { return 1; }
 
Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- test/Frontend/fixed_point_all_builtin_operations.c
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Werror %s
+// RUN: %clang_cc1 -Werror -S -emit-llvm %s -o - | lli -force-interpreter=true
 
 // Check that we can use all supported binary and unary operations according to
 // clause 4.1.6 in N1169.
@@ -66,3 +66,60 @@
 ALL_OPERATIONS(short _Accum, ShortAccum);
 ALL_OPERATIONS(_Accum, Accum);
 ALL_OPERATIONS(long _Accum, LongAccum);
+
+#define ASSERT(x) \
+  if (!(x)) return 1;
+
+#define BINARY_OPS_FOR_TYPE(TYPE, ID, SUFFIX) \
+  {   \
+TYPE a = 0.5##SUFFIX; \
+TYPE b = 0.25##SUFFIX;\
+ASSERT(add##ID(a, b) == 0.75##SUFFIX);\
+ASSERT(sub##ID(a, b) == 0.25##SUFFIX);\
+ASSERT(mul##ID(a, b) == 0.125##SUFFIX);   \
+ASSERT(div##ID(b, a) == 0.5##SUFFIX); \
+ASSERT(shl##ID(b, 1) == a);   \
+ASSERT(shr##ID(a, 1) == b);   \
+ASSERT(lt##ID(b, a)); \
+ASSERT(le##ID(b, a)); \
+ASSERT(gt##ID(a, b)); \
+ASSERT(ge##ID(a, b)); \
+ASSERT(eq##ID(a, b) == 0);\
+ASSERT(ne##ID(a, b)); \
+ASSERT(augmented_add##ID(a, b) == 0.75##SUFFIX);  \
+ASSERT(augmented_sub##ID(a, b) == 0.25##SUFFIX);  \
+ASSERT(augmented_mul##ID(a, b) == 0.125##SUFFIX); \
+ASSERT(augmented_div##ID(b, a) == 0.5##SUFFIX);   \
+ASSERT(augmented_shl##ID(b, 1) == a); \
+ASSERT(augmented_shr##ID(a, 1) == b); \
+  }
+
+#define BINARY_OPS(TYPE, ID, SUFFIX)\
+  BINARY_OPS_FOR_TYPE(TYPE, ID, SUFFIX);\
+  BINARY_OPS_FOR_TYPE(signed TYPE, Signed##ID, SUFFIX); \
+  BINARY_OPS_FOR_TYPE(unsigned TYPE, Unsigned##ID, u##SUFFIX);  \
+  BINARY_OPS_FOR_TYPE(_Sat TYPE, Sat##ID, SUFFIX);  \
+  BINARY_OPS_FOR_TYPE(_Sat signed TYPE, SatSigned##ID, SUFFIX); \
+  BINARY_OPS_FOR_TYPE(_Sat unsigned TYPE, SatUnsigned##ID, u##SUFFIX);
+
+#define FRACT_SAT_BINARY_OPS(TYPE, ID, SUFFIX) \
+  {\
+TYPE a = 0.7##SUFFIX;  \
+TYPE b = 0.9##SUFFIX;  \
+ASSERT(add##ID(a, b) == 1.0##SUFFIX);  \
+  }
+
+int main() {
+  BINARY_OPS(short _Fract, ShortFract, hr);
+  BINARY_OPS(_Fract, Fract, r);
+  BINARY_OPS(long _Fract, LongFract, lr);
+  BINARY_OPS(short _Accum, ShortAccum, hk);
+  BINARY_OPS(_Accum, Accum, k);
+  BINARY_OPS(long _Accum, LongAccum, lk);
+
+  FRACT_SAT_BINARY_OPS(_Sat short _Fract, SatShortFract, hr);
+  FRACT_SAT_BINARY_OPS(_Sat _Fract, SatFract, r);
+  FRACT_SAT_BINARY_OPS(_Sat long _Fract, SatLongFract, lr);
+
+  return 0;
+}
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -1258,8 +1258,12 @@
   return FixedPointTy;
 }
 
-/// \brief Handle arithmethic conversion with fixed point types.  Helper
-/// function of UsualArithmeticConversions().
+/// \brief Handle arithmethic conversion with fixed point types. The usual
+/// arithmetic conversions do not apply to fixed point type conversions between
+/// integers or other fixed point types due to potential loss of precision.
+/// For this case of fixed point types, the resulting type in a binary operation
+/// does not need to be exactly one of the 2 operand types.
+/// Implemented according to Clause 6.3.1.8 of ISO/IEC JTC1 SC22 WG14 N1169.
 static QualType handleFixedPointConversion(Sema , ExprResult ,

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan marked 2 inline comments as done.
leonardchan added inline comments.



Comment at: lib/Index/USRGeneration.cpp:731
+
+  if (c == '~') {
+switch (BT->getKind()) {

jakehehrlich wrote:
> You can make the 'c' a Twine instead. That will let you inline these in their 
> respective locations as `  c = "~UA" ` for instance.
So Twine also isn't assignable. If I still want to keep the pattern of 
assigning to a temporary variable, I could instead just make `c` a string.


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 148025.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = Context.LongAccumTy;
+  break;
+case PREDEF_TYPE_USHORT_ACCUM_ID:

[PATCH] D46979: [Fixed Point Arithmetic] Test for Conversion Between Valid Builtin Types

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147902.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46979

Files:
  include/clang/AST/OperationKinds.def
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_all_conversions.c

Index: test/Frontend/fixed_point_all_conversions.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_conversions.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Test for conversions between fixed point types and all other valid types.
+
+// Conversion from one type to another type
+#define CONVERT(FROM_TYPE, FROM_ID, TO_TYPE, TO_ID) \
+  TO_TYPE FROM_ID##_to_##TO_ID(FROM_TYPE x) { return x; }
+
+// Conversion between 2 types
+#define CONVERT_COMBINATION(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE1, ID1, TYPE2, ID2)   \
+  CONVERT(TYPE2, ID2, TYPE1, ID1)
+
+// Conversion between one type and floating point types
+#define CONVERT_BETWEEN_FLOATS(TYPE, ID)  \
+  CONVERT_COMBINATION(TYPE, ID, float, Float) \
+  CONVERT_COMBINATION(TYPE, ID, double, Double)
+
+// Conversion between one type and an integral type with differant signage
+#define CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, INT_TYPE, INT_ID)   \
+  CONVERT_COMBINATION(TYPE, ID, signed INT_TYPE, Signed##INT_ID)\
+  CONVERT_COMBINATION(TYPE, ID, unsigned INT_TYPE, Unsigned##INT_ID)
+
+// Conversion between one type and all integral types
+#define CONVERT_BETWEEN_INTEGRALS(TYPE, ID)   \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, char, Char)   \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, short, Short) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, int, Int) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long, Long)   \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long long, LongLong)
+
+// Conversion between one type and a fixed point type with different saturation
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, FIXED_TYPE, FIXED_ID)\
+  CONVERT_COMBINATION(TYPE, ID, _Sat FIXED_TYPE, Sat##FIXED_ID)
+
+// Conversion between one type and a fixed point type with different signage
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID)\
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, signed FIXED_TYPE,   \
+   Signed##FIXED_ID)  \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, unsigned FIXED_TYPE, \
+   Unsigned##FIXED_ID)
+
+// Convert between one type and all fixed point types.
+// Add "Type" to the end of the ID to avoid multiple definitions of a function
+// if the Type is a fixed point type.
+#define CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)\
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Fract, FractType) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Accum, AccumType)
+
+// Convert between one type and all other types
+#define CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_FLOATS(TYPE, ID)  \
+  CONVERT_BETWEEN_INTEGRALS(TYPE, ID)   \
+  CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)
+
+#define CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(TYPE, ID)   \
+  CONVERT_BETWEEN_ALL_TYPES(_Sat TYPE, Sat##ID)
+
+#define CONVERT_FIXED_POINT_TYPE(TYPE, ID)   \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID)\
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(signed TYPE, Signed##ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(unsigned TYPE, Unsigned##ID)
+
+CONVERT_FIXED_POINT_TYPE(short _Fract, ShortFract);
+CONVERT_FIXED_POINT_TYPE(_Fract, Fract);
+CONVERT_FIXED_POINT_TYPE(long _Fract, LongFract);
+
+CONVERT_FIXED_POINT_TYPE(short _Accum, ShortAccum);
+CONVERT_FIXED_POINT_TYPE(_Accum, Accum);
+CONVERT_FIXED_POINT_TYPE(long _Accum, LongAccum);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -323,6 +323,8 @@
 switch (CastE->getCastKind()) {
   case CK_FixedPointCast:
 llvm_unreachable("CK_FixedPointCast");  // TODO
+  case CK_FloatingToFixedPoint:
+llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_IntegralToFixedPoint:
 llvm_unreachable(
 "ExprEngine::VisitCast CK_IntegralToFixedPoint");  // TODO
Index: 

[PATCH] D46963: [Fixed Point Arithmetic] Test for All Builtin Operations

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147888.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46963

Files:
  lib/AST/ASTContext.cpp
  lib/CodeGen/CGExprScalar.cpp
  test/Frontend/fixed_point_all_builtin_operations.c

Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Check that we can use all supported binary and unary operations according to
+// clause 4.1.6 in N1169.
+
+#define ALL_OPERATIONS_FOR_TYPE(TYPE, ID) \
+  TYPE unary_add##ID(TYPE a) { return +a; }   \
+  TYPE unary_sub##ID(TYPE a) { return -a; }   \
+  int logical_not##ID(TYPE a) { return !a; }  \
+  TYPE add##ID(TYPE a, TYPE b) { return a + b; }  \
+  TYPE sub##ID(TYPE a, TYPE b) { return a - b; }  \
+  TYPE mul##ID(TYPE a, TYPE b) { return a * b; }  \
+  TYPE div##ID(TYPE a, TYPE b) { return a / b; }  \
+  TYPE shl##ID(TYPE a, int b) { return a << b; }  \
+  TYPE shr##ID(TYPE a, int b) { return a >> b; }  \
+  TYPE augmented_add##ID(TYPE a, TYPE b) {\
+a += b;   \
+return a; \
+  }   \
+  TYPE augmented_sub##ID(TYPE a, TYPE b) {\
+a -= b;   \
+return a; \
+  }   \
+  TYPE augmented_mul##ID(TYPE a, TYPE b) {\
+a *= b;   \
+return a; \
+  }   \
+  TYPE augmented_div##ID(TYPE a, TYPE b) {\
+a /= b;   \
+return a; \
+  }   \
+  TYPE augmented_shl##ID(TYPE a, int b) { \
+a <<= b;  \
+return a; \
+  }   \
+  TYPE augmented_shr##ID(TYPE a, int b) { \
+a >>= b;  \
+return a; \
+  }   \
+  int eq##ID(TYPE a, TYPE b) { return a == b; }   \
+  int ne##ID(TYPE a, TYPE b) { return a != b; }   \
+  int lt##ID(TYPE a, TYPE b) { return a < b; }\
+  int le##ID(TYPE a, TYPE b) { return a <= b; }   \
+  int ge##ID(TYPE a, TYPE b) { return a >= b; }   \
+  int gt##ID(TYPE a, TYPE b) { return a > b; }\
+  TYPE pre_inc##ID(TYPE a) { return ++a; }\
+  TYPE pre_dec##ID(TYPE a) { return --a; }\
+  TYPE post_inc##ID(TYPE a) { return a++; }   \
+  TYPE post_dec##ID(TYPE a) { return a--; }   \
+  TYPE deref_pre_inc##ID(TYPE *a) { return ++(*a); }  \
+  TYPE deref_pre_dec##ID(TYPE *a) { return --(*a); }  \
+  TYPE deref_post_inc##ID(TYPE *a) { return (*a)++; } \
+  TYPE deref_post_dec##ID(TYPE *a) { return (*a)--; }
+
+#define ALL_OPERATIONS(TYPE, ID)   \
+  ALL_OPERATIONS_FOR_TYPE(TYPE, ID)\
+  ALL_OPERATIONS_FOR_TYPE(signed TYPE, Signed##ID) \
+  ALL_OPERATIONS_FOR_TYPE(unsigned TYPE, Unsigned##ID) \
+  ALL_OPERATIONS_FOR_TYPE(_Sat TYPE, Sat##ID)  \
+  ALL_OPERATIONS_FOR_TYPE(_Sat signed TYPE, SatSigned##ID) \
+  ALL_OPERATIONS_FOR_TYPE(_Sat unsigned TYPE, SatUnsigned##ID)
+
+ALL_OPERATIONS(short _Fract, ShortFract);
+ALL_OPERATIONS(_Fract, Fract);
+ALL_OPERATIONS(long _Fract, LongFract);
+ALL_OPERATIONS(short _Accum, ShortAccum);
+ALL_OPERATIONS(_Accum, Accum);
+ALL_OPERATIONS(long _Accum, LongAccum);
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -2214,39 +2214,51 @@
 switch (BT->getKind()) {
   default:
 llvm_unreachable("Not a fixed point type!");
+  case BuiltinType::SatShortAccum:
   case BuiltinType::ShortAccum:
 fbits = BUILTIN_SACCUM_FBIT;
 break;
+  case BuiltinType::SatAccum:
   case BuiltinType::Accum:
 fbits = BUILTIN_ACCUM_FBIT;
 break;
+  case BuiltinType::SatLongAccum:
   case BuiltinType::LongAccum:
 fbits = BUILTIN_LACCUM_FBIT;
 break;
+  case BuiltinType::SatUShortAccum:
   case BuiltinType::UShortAccum:
 fbits = BUILTIN_USACCUM_FBIT;
 break;
+  case BuiltinType::SatUAccum:
   case BuiltinType::UAccum:
 fbits = BUILTIN_UACCUM_FBIT;
 break;
+  case BuiltinType::SatULongAccum:

[PATCH] D46960: [Fixed Point Arithmetic] Predefined Precision Macros

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147883.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46960

Files:
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPMacroExpansion.cpp
  test/Frontend/fixed_point_builtin_macros.c

Index: test/Frontend/fixed_point_builtin_macros.c
===
--- /dev/null
+++ test/Frontend/fixed_point_builtin_macros.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+
+#define assert(b) if (!(b)) { return 1; }
+
+int main() {
+  // Test using the recommended values for a typical desktop processor (Annex
+  // A.3). These are also the default values when building clang.
+  // Fractional bits of _Accum types
+  assert(__SACCUM_FBIT__  == 7);
+  assert(__ACCUM_FBIT__   == 15);
+  assert(__LACCUM_FBIT__  == 31);
+  assert(__USACCUM_FBIT__ == 8);
+  assert(__UACCUM_FBIT__  == 16);
+  assert(__ULACCUM_FBIT__ == 32);
+
+  // Fractional bits of _Fract types
+  assert(__SFRACT_FBIT__  == 7);
+  assert(__FRACT_FBIT__   == 15);
+  assert(__LFRACT_FBIT__  == 31);
+  assert(__USFRACT_FBIT__ == 8);
+  assert(__UFRACT_FBIT__  == 16);
+  assert(__ULFRACT_FBIT__ == 32);
+
+  // Integral bits of _Accum types
+  assert(__SACCUM_IBIT__  == 8);
+  assert(__ACCUM_IBIT__   == 16);
+  assert(__LACCUM_IBIT__  == 32);
+  assert(__USACCUM_IBIT__ == 8);
+  assert(__UACCUM_IBIT__  == 16);
+  assert(__ULACCUM_IBIT__ == 32);
+}
Index: lib/Lex/PPMacroExpansion.cpp
===
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -14,6 +14,7 @@
 
 #include "clang/Basic/Attributes.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -355,6 +356,31 @@
   Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
   Ident__TIMESTAMP__ = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
 
+  // Fixed point macros (ISO/IEC JTC1 SC22 WG14 N1169)
+  // Fractional bits of _Accum types
+  Ident__SACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__SACCUM_FBIT__");
+  Ident__ACCUM_FBIT__= RegisterBuiltinMacro(*this, "__ACCUM_FBIT__");
+  Ident__LACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__LACCUM_FBIT__");
+  Ident__USACCUM_FBIT__  = RegisterBuiltinMacro(*this, "__USACCUM_FBIT__");
+  Ident__UACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__UACCUM_FBIT__");
+  Ident__ULACCUM_FBIT__  = RegisterBuiltinMacro(*this, "__ULACCUM_FBIT__");
+
+  // Fractional bits of _Fract types
+  Ident__SFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__SFRACT_FBIT__");
+  Ident__FRACT_FBIT__= RegisterBuiltinMacro(*this, "__FRACT_FBIT__");
+  Ident__LFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__LFRACT_FBIT__");
+  Ident__USFRACT_FBIT__  = RegisterBuiltinMacro(*this, "__USFRACT_FBIT__");
+  Ident__UFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__UFRACT_FBIT__");
+  Ident__ULFRACT_FBIT__  = RegisterBuiltinMacro(*this, "__ULFRACT_FBIT__");
+
+  // Integral bits of _Accum types
+  Ident__SACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__SACCUM_IBIT__");
+  Ident__ACCUM_IBIT__= RegisterBuiltinMacro(*this, "__ACCUM_IBIT__");
+  Ident__LACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__LACCUM_IBIT__");
+  Ident__USACCUM_IBIT__  = RegisterBuiltinMacro(*this, "__USACCUM_IBIT__");
+  Ident__UACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__UACCUM_IBIT__");
+  Ident__ULACCUM_IBIT__  = RegisterBuiltinMacro(*this, "__ULACCUM_IBIT__");
+
   // Microsoft Extensions.
   if (LangOpts.MicrosoftExt) {
 Ident__identifier = RegisterBuiltinMacro(*this, "__identifier");
@@ -1696,6 +1722,68 @@
 // __LINE__ expands to a simple numeric value.
 OS << (PLoc.isValid()? PLoc.getLine() : 1);
 Tok.setKind(tok::numeric_constant);
+
+  // Fixed point macros
+  // Fractional bits of _Accum types
+  } else if (II == Ident__SACCUM_FBIT__) {
+OS << BUILTIN_SACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ACCUM_FBIT__) {
+OS << BUILTIN_ACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__LACCUM_FBIT__) {
+OS << BUILTIN_LACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__USACCUM_FBIT__) {
+OS << BUILTIN_USACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__UACCUM_FBIT__) {
+OS << BUILTIN_UACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ULACCUM_FBIT__) {
+OS << BUILTIN_ULACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+
+  // Fractional bits of _Fract types
+  } else if (II == Ident__SFRACT_FBIT__) {
+OS << BUILTIN_SFRACT_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__FRACT_FBIT__) {
+OS << BUILTIN_FRACT_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__LFRACT_FBIT__) {
+OS << 

[PATCH] D46927: [Fixed Point Arithmetic] Augmented Assignment for Fixed Point Types

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147882.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46927

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -1,5 +1,5 @@
-// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
 // RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
 
 // The first test checks the emitted llvm IR.
 // The second test checks the output.
@@ -279,4 +279,35 @@
   float laccum_diff = abs(base - 2.333lk);
   assert(accum_diff < saccum_diff);
   assert(laccum_diff < accum_diff);
+
+  / Auxillary assignments ***/
+
+  s_accum = 7.5hk;
+  s_accum2 = 2.0hk;
+  s_accum += s_accum2;
+  assert(s_accum == 9.5hk);
+  s_accum += 2.5k;
+  assert(s_accum == 12);
+
+  s_accum -= s_accum2;
+  assert(s_accum == 10);
+  s_accum -= 2.5lk;
+  assert(s_accum == 7.5k);
+
+  s_accum2 = 3.0k;
+  s_accum *= s_accum2;
+  assert(s_accum == 22.5k);
+  s_accum *= 0.5r;
+  assert(s_accum == 11.25hk);
+
+  s_accum /= s_accum2;
+  assert(s_accum == 3.75k);
+  s_accum /= 0.5hr;
+  assert(s_accum == 7.5k);
+
+  s_accum <<= 3;
+  assert(s_accum == 60);
+
+  s_accum >>= 3;
+  assert(s_accum == 7.5k);
 }
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -6076,8 +6076,7 @@
   case Type::STK_Floating:
 return CK_FixedPointToFloating;
   case Type::STK_FixedPoint:
-llvm_unreachable(
-"Unimplemented scalar cast from fixed point to fixed point");  // TODO
+return CK_FixedPointCast;
 }
   }
 
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -308,6 +308,17 @@
   Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
   SourceLocation Loc, bool TreatBooleanAsSigned);
 
+  /// Emit a conversion between fixed point types by moving the radix point.
+  /// This does not take into account resizing of the underlying llvm type
+  /// which should be handled either before or after calling this function.
+  ///
+  /// If the type is being scaled up, this method should be called after
+  /// performing an intcast. If the type is scaled down, this method should be
+  /// called before performing an intcast. This is necessary such that the
+  /// shift operations retain as much of the original data as possible before
+  /// truncation or after extension.
+  Value *EmitFixedPointRadixShift(Value *Src, QualType SrcTy, QualType DstTy);
+
   /// Emit a conversion from the specified complex type to the specified
   /// destination type, where the destination type is an LLVM scalar type.
   Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
@@ -961,6 +972,49 @@
 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
 }
 
+/// Emit a conversion between fixed point types by moving the radix point.
+/// This does not take into account resizing of the underlying llvm type
+/// which should be handled either before or after calling this function.
+///
+/// If the type is being scaled up, this method should be called after
+/// performing an intcast. If the type is scaled down, this method should be
+/// called before performing an intcast. This is necessary such that the
+/// shift operations retain as much of the original data as possible before
+/// truncation or after extension.
+Value *ScalarExprEmitter::EmitFixedPointRadixShift(Value *Src, QualType SrcTy,
+   QualType DstTy) {
+  assert(DstTy->isFixedPointType());
+  assert(SrcTy->isFixedPointType());
+
+  Value *Res = Src;
+
+  // Casting between fixed point types involves separating the integral and
+  // fractional bits, potentially shifting them, then joining back together.
+  unsigned dest_fbits = getFixedPointFBits(DstTy);
+  unsigned src_fbits = getFixedPointFBits(SrcTy);
+  unsigned dest_ibits = getFixedPointIBits(DstTy);
+  unsigned src_ibits = getFixedPointIBits(SrcTy);
+
+  // If the number of integral bits is decreasing, trim off any extra bits while
+  // retaining the sign.
+  if (dest_ibits < src_ibits) {
+Res = Builder.CreateShl(Res, src_ibits - dest_ibits);
+Res = Builder.CreateAShr(Res, src_ibits - dest_ibits);
+  }
+
+  // Move the radix. For irrational numbers, there will be loss of precision
+  // using this method when the number of fbits increases since we will be right
+  // padding zeros. Precision can still be retained if we temporarily convert to

[PATCH] D46926: [Fixed Point Arithmetic] Conversion between Fixed Point and Floating Point Numbers

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147881.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46926

Files:
  include/clang/AST/OperationKinds.def
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaCast.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -30,6 +30,7 @@
 // Run simple validation tests
 
 #define assert(b) if (!(b)) { return 1; }
+#define abs(x) x < 0 ? -x : x
 
 int main(){
   short _Accum s_accum = 0.0hk;
@@ -264,4 +265,18 @@
   assert(5.0hk >> 2 == 1.25hk);
   assert(-5.0hk >> 2 == -1.25k);
   assert(0.0hr >> 2 == 0);
+
+  / Float conversions ***/
+
+  float f = (float)2.5k;
+  assert(f > 2.4999 && f < 2.5001);  // High precision since the fractional
+ // value can be evenly represented.
+  assert((float)2.333hk != 2.333f);
+
+  float base = 2.333f;
+  float saccum_diff = abs(base - 2.333hk);
+  float accum_diff = abs(base - 2.333k);
+  float laccum_diff = abs(base - 2.333lk);
+  assert(accum_diff < saccum_diff);
+  assert(laccum_diff < accum_diff);
 }
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -326,6 +326,8 @@
   case CK_IntegralToFixedPoint:
 llvm_unreachable(
 "ExprEngine::VisitCast CK_IntegralToFixedPoint");  // TODO
+  case CK_FixedPointToFloating:
+llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
   case CK_LValueToRValue:
 llvm_unreachable("LValueToRValue casts handled earlier.");
   case CK_ToVoid:
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -1029,6 +1029,21 @@
   return result;
 }
 
+/// \brief Handle arithmetic conversion from fixed point to floating.  Helper
+/// function of UsualArithmeticConversions()
+static QualType handleFixedPointToFloatConversion(Sema ,
+  ExprResult ,
+  ExprResult ,
+  QualType FloatTy,
+  QualType FixedPointTy) {
+  assert(FloatTy->isFloatingType());
+  assert(FixedPointTy->isFixedPointType());
+
+  FixedPointExpr = S.ImpCastExprToType(FixedPointExpr.get(), FloatTy,
+   CK_FixedPointToFloating);
+  return FloatTy;
+}
+
 /// \brief Handle arithmethic conversion with floating point types.  Helper
 /// function of UsualArithmeticConversions()
 static QualType handleFloatConversion(Sema , ExprResult ,
@@ -1057,11 +1072,20 @@
 if (LHSType->isHalfType() && !S.getLangOpts().NativeHalfType)
   LHSType = S.Context.FloatTy;
 
+if (RHSType->isFixedPointType()) {
+  return handleFixedPointToFloatConversion(S, LHS, RHS, LHSType, RHSType);
+}
+
 return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType,
   /*convertFloat=*/!IsCompAssign,
   /*convertInt=*/ true);
   }
   assert(RHSFloat);
+
+  if (LHSType->isFixedPointType()) {
+return handleFixedPointToFloatConversion(S, RHS, LHS, RHSType, LHSType);
+  }
+
   return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType,
 /*convertInt=*/ true,
 /*convertFloat=*/!IsCompAssign);
@@ -1218,6 +1242,7 @@
   CK_IntegralRealToComplex);
   return ComplexType;
 }
+
 /// \brief Handle arithmetic conversion from integer to fixed point.  Helper
 /// function of UsualArithmeticConversions()
 static QualType handleIntToFixedPointConversion(Sema ,
@@ -6041,9 +6066,20 @@
 }
 llvm_unreachable("Should have returned before this");
 
-  case Type::STK_FixedPoint:
-llvm_unreachable(
-"Sema::PrepareScalarCast from STK_FixedPoint to anything");  // TODO
+  case Type::STK_FixedPoint: {
+switch (DestTy->getScalarTypeKind()) {
+  default:
+llvm_unreachable("Unable to convert from fixed point type");
+  case Type::STK_Integral:
+llvm_unreachable(
+"Unimplemented scalar cast from fixed point to int");  // TODO
+  case Type::STK_Floating:
+return CK_FixedPointToFloating;
+  case 

[PATCH] D46925: [Fixed Point Arithmetic] Remaining Binary Operations on Primary Fixed Point Types

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147880.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46925

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/OperationKinds.def
  include/clang/AST/Type.h
  lib/AST/ASTContext.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -74,6 +74,9 @@
   assert(2 == s_accum);
   // CHECK:  {{.*}} = icmp eq i16 256, {{.*}}
 
+  assert(2 == 2.0hk);
+  assert(2 != 2.01hk);
+
   int x = 2;
   assert(s_accum == x);
   // CHECK:  {{.*}} = load i32, i32* %x, align 4
@@ -128,6 +131,46 @@
   // numbers.
   assert(2 == 2.001hk);  // This is valid if SACCUM_FBITS == 7
 
+  // Comparisons between fixed-point types
+  // Signed _Accum to signed _Accum types.
+  assert(2.5hk == 2.5k);
+  assert(2.5k == 2.5lk);
+  assert(-2.5hk == -2.5k);
+  assert(-2.5k == -2.5lk);
+
+  // Unsigned _Accum to unigned _Accum
+  assert(2.5uhk == 2.5uk);
+  assert(2.5uk == 2.5ulk);
+
+  // Signed _Fract to signed _Fract types.
+  assert(0.333hr != 0.333r);  // Loss of precision since different fractional widths
+  assert(0.333r != 0.333lr);
+  assert(-0.333hr != -0.333r);
+  assert(-0.333r != -0.333lr);
+
+  // Unsigned _Fract to unsigned _Fract types.
+  assert(0.333uhr != 0.333ur);
+  assert(0.333ur != 0.333ulr);
+
+  // Signed _Accum to signed _Fract
+  assert(0.333hk == 0.333hr);
+  assert(0.333k == 0.333r);
+  assert(0.333lk == 0.333lr);
+  assert(0.333hk == 0.333r);  // Although _Fract has higher precision, it gets casted up to
+  // short _Accum which (using default precisions)
+  // has fewer fractional bits.
+
+  // Signed _Accum to unsigned _Fract
+  assert(0.333hk == 0.333uhr);
+  assert(0.333k == 0.333ur);
+  assert(0.333lk == 0.333ulr);
+
+  // Signed _Accum to unsigned _Accum
+  assert(2.5hk == 2.5uhk);
+  assert(2.5k == 2.5uk);
+  assert(2.5lk == 2.5ulk);
+
+
   / Unary operations ***/
 
   s_accum = 0.0hk;
@@ -167,4 +210,58 @@
   assert(+s_fract == s_fract);
   assert(+s_fract2 == s_fract2);  // s_fract2 is negative
   assert(-s_fract == s_fract2);
+
+  / Binary operations ***/
+
+  // Addition
+  s_accum = 3.0hk;
+  short _Accum s_accum_sum = s_accum + s_accum2;
+  assert(s_accum_sum == 5);
+  assert(s_fract + s_fract2 == 0);
+
+  // Subtraction
+  short _Accum s_accum_diff = s_accum - s_accum2;
+  assert(s_accum_diff == 1);
+  assert(s_accum2 - s_accum == -1);
+
+  // Multiplication
+  short _Accum s_accum_mul = s_accum * s_accum2;
+  assert(s_accum_mul == 6);
+  assert(2.0hk * 3.0hk == 6);
+  assert(2.0hk * 3 == 6);
+  assert(2.5hk * 3 == 7.5k);
+  assert(-2.5hk * 3 == -7.5lk);
+  assert(3 * -2.5hk == -7.5hk);
+  assert(-2.5hk * 0 == 0);
+
+  // Division
+  const short _Accum s_accum3 = 2.5hk;
+  short _Accum s_accum_div = s_accum3 / s_accum2;
+  assert(s_accum_div == 1.25hk);
+  assert(5.0hk / s_accum3 == 2);
+  assert(-5.0hk / s_accum3 == -2);
+  assert(9.9k / 3.3k == 3);
+  assert(9.9hk / 3.3k != 3);  // We lose precision when converting between types of different
+  // fractional width.
+  assert(6.75hk / 2.25k == 3);  // Unless the fractional part can be evenly represented with
+// sums of powers of 2.
+  assert(0 / 2.0hk == 0);
+
+  // Left shift
+  short _Accum s_accum_shl = s_accum2 << 3;
+  assert(s_accum_shl == 16);
+  assert(1.0hk << 3 == 8);
+  assert(-1.0hk << 3 == -8);
+  assert(1.5k << 1 == 3);  // LShift is equivalent to multiplying by 2
+  assert(-1.25hk << 2 == -5);
+
+  // Right shift
+  const signed short _Accum s_accum4 = 16.0hk;
+  short _Accum s_accum_shr = s_accum4 >> 3;
+  assert(s_accum_shr == 2);
+  assert(s_accum_shr >> 1 == 1);
+  assert(s_accum_shr >> 2 == 0.5hr);  // RShift is equivalent to dividing by 2
+  assert(5.0hk >> 2 == 1.25hk);
+  assert(-5.0hk >> 2 == -1.25k);
+  assert(0.0hr >> 2 == 0);
 }
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -321,6 +321,8 @@
 const LocationContext *LCtx = Pred->getLocationContext();
 
 switch (CastE->getCastKind()) {
+  case CK_FixedPointCast:
+llvm_unreachable("CK_FixedPointCast");  // TODO
   case CK_IntegralToFixedPoint:
 llvm_unreachable(
 "ExprEngine::VisitCast 

[PATCH] D46917: [Fixed Point Arithmetic] Comparison and Unary Operations for Fixed Point Types

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147631.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46917

Files:
  lib/CodeGen/CGExprScalar.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_declarations.c
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -1,19 +1,170 @@
+// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
 // RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
 
+// The first test checks the emitted llvm IR.
+// The second test checks the output.
+// Both these test require that the default bit widths for the fixed point types
+// are used since we check for bit shifted literals that were converted from
+// ints and floats.
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// CHECK-DAG: @s_short_accum =  common dso_local global i16 0, align 2
+signed _Accum s_accum;// CHECK-DAG: @s_accum =common dso_local global i32 0, align 4
+signed long _Accum s_long_accum;  // CHECK-DAG: @s_long_accum =   common dso_local global i64 0, align 8
+unsigned short _Accum u_short_accum;  // CHECK-DAG: @u_short_accum =  common dso_local global i16 0, align 2
+unsigned _Accum u_accum;  // CHECK-DAG: @u_accum =common dso_local global i32 0, align 4
+unsigned long _Accum u_long_accum;// CHECK-DAG: @u_long_accum =   common dso_local global i64 0, align 8
+signed short _Fract s_short_fract;// CHECK-DAG: @s_short_fract =  common dso_local global i16 0, align 2
+signed _Fract s_fract;// CHECK-DAG: @s_fract =common dso_local global i32 0, align 4
+signed long _Fract s_long_fract;  // CHECK-DAG: @s_long_fract =   common dso_local global i64 0, align 8
+unsigned short _Fract u_short_fract;  // CHECK-DAG: @u_short_fract =  common dso_local global i16 0, align 2
+unsigned _Fract u_fract;  // CHECK-DAG: @u_fract =common dso_local global i32 0, align 4
+unsigned long _Fract u_long_fract;// CHECK-DAG: @u_long_fract =   common dso_local global i64 0, align 8
+
+// There are 7 bits allocated to the fractional part and 8
+// bits allocated to the integral part of a short _Accum by default.
+
+signed short _Accum s_short_accum2 = 2.5hk;  // CHECK-DAG: @s_short_accum2 = dso_local global i16 320, align 2
+short _Fract short_fract = 0.333hr;  // CHECK-DAG: @short_fract = dso_local global i16 42, align 2
+
 // Run simple validation tests
 
 #define assert(b) if (!(b)) { return 1; }
 
 int main(){
-  short _Accum s_accum;
+  short _Accum s_accum = 0.0hk;
   short _Accum s_accum2 = 2.0hk;
   short _Fract s_fract = 0.999hr;
   short _Fract s_fract2 = -0.999hr;
+  const _Fract fract_zero = 0.0r;
+  // CHECK:  %s_accum = alloca i16, align 2
+  // CHECK:  %s_accum2 = alloca i16, align 2
+  // CHECK:  %s_fract = alloca i16, align 2
+  // CHECK:  %s_fract2 = alloca i16, align 2
+  // CHECK:  %fract_zero = alloca i32, align 4
+  // CHECK:  store i16 0, i16* %s_accum, align 2
+  // CHECK:  store i16 256, i16* %s_accum2, align 2
+  // CHECK:  store i16 127, i16* %s_fract, align 2
+  // CHECK:  store i16 -127, i16* %s_fract2, align 2
+  // CHECK:  store i32 0, i32* %fract_zero, align 4
+
+  / Simple Comparisons ***/
 
   assert(s_accum == 0);
+  // CHECK:  {{.*}} = load i16, i16* %s_accum, align 2
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, 0
 
   s_accum = s_accum2;
+  // CHECK:  {{.*}} = load i16, i16* %s_accum2, align 2
+  // CHECK-NEXT: store i16 %1, i16* %s_accum, align 2
 
   assert(s_accum == s_accum2);
+  // CHECK:  {{.*}} = load i16, i16* %s_accum, align 2
+  // CHECK-NEXT: {{.*}} = load i16, i16* %s_accum2, align 2
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, {{.*}}
+
+  assert(s_accum2 == s_accum);
+  // CHECK:  {{.*}} = load i16, i16* %s_accum2, align 2
+  // CHECK-NEXT: {{.*}} = load i16, i16* %s_accum, align 2
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, {{.*}}
+
   assert(s_accum == 2);
+  // CHECK:  {{.*}} = icmp eq i16 {{.*}}, 256
+
+  assert(2 == s_accum);
+  // CHECK:  {{.*}} = icmp eq i16 256, {{.*}}
+
+  int x = 2;
+  assert(s_accum == x);
+  // CHECK:  {{.*}} = load i32, i32* %x, align 4
+  // CHECK-NEXT: {{.*}} = trunc i32 {{.*}} to i16
+  // CHECK-NEXT: {{.*}} = shl i16 {{.*}}, 7
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, {{.*}}
+
+  assert(x == s_accum);
+
+  assert(s_accum != -2);
+  // CHECK:  {{.*}} = icmp ne i16 {{.*}}, -256
+
+  assert(-2 != s_accum);
+  // CHECK:  {{.*}} = icmp ne i16 -256, {{.*}}
+
+  assert(s_accum != -x);
+  assert(-x != s_accum);
+
+  assert(s_fract != 1);
+  // CHECK:  {{.*}} = load i16, i16* %s_fract, align 2
+  // CHECK_NEXT: {{.*}} = icmp ne i16 {{.*}}, 128
+
+  assert(s_fract2 != -1);
+  // CHECK:  

[PATCH] D46915: [Fixed Point Arithmetic] Set Fixed Point Precision Bits and Create Fixed Point Literals

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147595.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46915

Files:
  CMakeLists.txt
  cmake/modules/InitFixedPointBits.cmake
  include/clang/AST/Expr.h
  include/clang/AST/OperationKinds.def
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/FixedPoint.h.in
  include/clang/Basic/StmtNodes.td
  include/clang/Lex/LiteralSupport.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Lex/LiteralSupport.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_declarations.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_validation.c
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -305,6 +305,10 @@
 K = CXCursor_IntegerLiteral;
 break;
 
+  case Stmt::FixedPointLiteralClass:
+llvm_unreachable("No cursor for FixedPointLiteralClass");
+break;
+
   case Stmt::FloatingLiteralClass:
 K = CXCursor_FloatingLiteral;
 break;
Index: test/Frontend/fixed_point_validation.c
===
--- /dev/null
+++ test/Frontend/fixed_point_validation.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+
+// Run simple validation tests
+
+#define assert(b) if (!(b)) { return 1; }
+
+int main(){
+  short _Accum s_accum;
+  short _Accum s_accum2 = 2.0hk;
+  short _Fract s_fract = 0.999hr;
+  short _Fract s_fract2 = -0.999hr;
+
+  assert(s_accum == 0);
+
+  s_accum = s_accum2;
+
+  assert(s_accum == s_accum2);
+  assert(s_accum == 2);
+}
Index: test/Frontend/fixed_point_errors.c
===
--- test/Frontend/fixed_point_errors.c
+++ test/Frontend/fixed_point_errors.c
@@ -1,14 +1,23 @@
 // RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
 
-long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
-unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
-long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
-unsigned long long _Fract u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;   // expected-error{{'long long _Fract' is invalid}}
 
 _Sat int i;  // expected-error{{'int' cannot be saturated. Only _Fract and _Accum can.}}
 _Sat _Sat _Fract fract;  // expected-warning{{duplicate '_Sat' declaration specifier}}
 
-_Sat long long _Accum sat_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Accum sat_longlong_accum; // expected-error{{'long long _Accum' is invalid}}
 _Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
-_Sat long long _Fract sat_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+_Sat long long _Fract sat_longlong_fract; // expected-error{{'long long _Fract' is invalid}}
 _Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
+short _Fract fract2 = 1.2hr;  // expected-error{{a _Fract type cannot have an integral part}}
+
+signed short _Accum s_short_accum = 129.0hk;  // expected-error{{the integral part of this literal is too large for this signed _Accum type}}
+unsigned short _Accum u_short_accum = 256.0uhk;   // expected-error{{the integral part of this literal is too large for this unsigned _Accum type}}
+signed _Accum s_accum = 32770.0k; // expected-error{{the integral part of this literal is too large for this signed _Accum type}}
+unsigned _Accum u_accum = 65536.0uk;  // expected-error{{the integral part of this literal is too large for this unsigned _Accum type}}
+short _Accum short_accum = 129.0hk;   // expected-error{{the 

[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147568.

Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp

Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum; // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/fixed_point_errors.c
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
+_Sat int i;  // expected-error{{'int' cannot be saturated. Only _Fract and _Accum can.}}
+_Sat _Sat _Fract fract;  // expected-warning{{duplicate '_Sat' declaration specifier}}
+
+_Sat long long _Accum sat_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
Index: test/Frontend/fixed_point.c
===
--- /dev/null
+++ test/Frontend/fixed_point.c
@@ -0,0 +1,82 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+signed short _Fract s_short_fract;
+signed _Fract s_fract;
+signed long _Fract s_long_fract;
+unsigned short _Fract u_short_fract;
+unsigned _Fract u_fract;
+unsigned long _Fract u_long_fract;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+short _Fract short_fract;
+_Fract fract;
+long _Fract long_fract;
+
+// Saturated fixed point types
+_Sat signed short _Accum sat_s_short_accum;
+_Sat signed _Accum sat_s_accum;
+_Sat signed long _Accum sat_s_long_accum;
+_Sat unsigned short _Accum sat_u_short_accum;
+_Sat unsigned _Accum sat_u_accum;
+_Sat unsigned long _Accum sat_u_long_accum;
+_Sat signed short _Fract sat_s_short_fract;
+_Sat signed _Fract sat_s_fract;
+_Sat signed long _Fract sat_s_long_fract;
+_Sat unsigned short _Fract sat_u_short_fract;
+_Sat unsigned _Fract sat_u_fract;
+_Sat unsigned long _Fract sat_u_long_fract;
+
+// Aliased saturated fixed point types
+_Sat short _Accum sat_short_accum;
+_Sat _Accum sat_accum;
+_Sat long _Accum sat_long_accum;
+_Sat short _Fract 

[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147566.

Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp

Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum; // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/fixed_point_errors.c
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
+_Sat int i;  // expected-error{{'int' cannot be saturated. Only _Fract and _Accum can.}}
+_Sat _Sat _Fract fract;  // expected-warning{{duplicate '_Sat' declaration specifier}}
+
+_Sat long long _Accum sat_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
Index: test/Frontend/fixed_point.c
===
--- /dev/null
+++ test/Frontend/fixed_point.c
@@ -0,0 +1,82 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+signed short _Fract s_short_fract;
+signed _Fract s_fract;
+signed long _Fract s_long_fract;
+unsigned short _Fract u_short_fract;
+unsigned _Fract u_fract;
+unsigned long _Fract u_long_fract;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+short _Fract short_fract;
+_Fract fract;
+long _Fract long_fract;
+
+// Saturated fixed point types
+_Sat signed short _Accum sat_s_short_accum;
+_Sat signed _Accum sat_s_accum;
+_Sat signed long _Accum sat_s_long_accum;
+_Sat unsigned short _Accum sat_u_short_accum;
+_Sat unsigned _Accum sat_u_accum;
+_Sat unsigned long _Accum sat_u_long_accum;
+_Sat signed short _Fract sat_s_short_fract;
+_Sat signed _Fract sat_s_fract;
+_Sat signed long _Fract sat_s_long_fract;
+_Sat unsigned short _Fract sat_u_short_fract;
+_Sat unsigned _Fract sat_u_fract;
+_Sat unsigned long _Fract sat_u_long_fract;
+
+// Aliased saturated fixed point types
+_Sat short _Accum sat_short_accum;
+_Sat _Accum sat_accum;
+_Sat long _Accum sat_long_accum;
+_Sat short _Fract 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147560.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = Context.LongAccumTy;
+  break;
+case PREDEF_TYPE_USHORT_ACCUM_ID:

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147549.

Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = Context.LongAccumTy;
+  break;
+case PREDEF_TYPE_USHORT_ACCUM_ID:

[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents

2018-05-18 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147541.
leonardchan added a comment.

Updated formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp

Index: test/Frontend/fixed_point_errors.cpp
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum; // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/fixed_point_errors.c
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
+_Sat int i;  // expected-error{{'int' cannot be saturated. Only _Fract and _Accum can.}}
+_Sat _Sat _Fract fract;  // expected-warning{{duplicate '_Sat' declaration specifier}}
+
+_Sat long long _Accum sat_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
Index: test/Frontend/fixed_point.c
===
--- /dev/null
+++ test/Frontend/fixed_point.c
@@ -0,0 +1,82 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+signed short _Fract s_short_fract;
+signed _Fract s_fract;
+signed long _Fract s_long_fract;
+unsigned short _Fract u_short_fract;
+unsigned _Fract u_fract;
+unsigned long _Fract u_long_fract;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+short _Fract short_fract;
+_Fract fract;
+long _Fract long_fract;
+
+// Saturated fixed point types
+_Sat signed short _Accum sat_s_short_accum;
+_Sat signed _Accum sat_s_accum;
+_Sat signed long _Accum sat_s_long_accum;
+_Sat unsigned short _Accum sat_u_short_accum;
+_Sat unsigned _Accum sat_u_accum;
+_Sat unsigned long _Accum sat_u_long_accum;
+_Sat signed short _Fract sat_s_short_fract;
+_Sat signed _Fract sat_s_fract;
+_Sat signed long _Fract sat_s_long_fract;
+_Sat unsigned short _Fract sat_u_short_fract;
+_Sat unsigned _Fract sat_u_fract;
+_Sat unsigned long _Fract sat_u_long_fract;
+
+// Aliased saturated fixed point types
+_Sat short _Accum sat_short_accum;
+_Sat _Accum sat_accum;
+_Sat 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147406.
leonardchan marked an inline comment as done.
leonardchan added a comment.

Undid git-clang-formatting on ASTBitcodes.h


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan marked 2 inline comments as done.
leonardchan added inline comments.



Comment at: lib/Index/USRGeneration.cpp:691
+case BuiltinType::ULongAccum:
+  llvm_unreachable("No USR name mangling for fixed point types.");
 case BuiltinType::Float16:

phosek wrote:
> We need some solution for fixed point types.
Added character ~ to indicate fixed point type followed by string detailing the 
type. I have not added a test to it because logically, I do not think we will 
ever reach that point. This logic is implemented in the VisitType method, which 
mostly gets called by visitors to c++ nodes like VisitTemplateParameterList, 
but we have disabled the use of fixed point types in c++. VisitType does get 
called in VisitFunctionDecl but the function exits early since we are not 
reading c++ (line lib/Index/USRGeneration.cpp:238).


Repository:
  rC Clang

https://reviews.llvm.org/D46084



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147400.
leonardchan added a comment.

Added break. We still assign `Result` since it cannot be null at the end of the 
switch stmt, though the value doesn't matter.

Added character `~` to indicate fixed point type followed by string detailing 
the type. I have not added a test to it because logically, I do not think we 
will ever reach that point. This logic is implemented in the `VisitType` 
method, which mostly gets called by visitors to c++ nodes like 
`VisitTemplateParameterList`, but we have disabled the use of fixed point types 
in c++. `VisitType` does get called in `VisitFunctionDecl` but the function 
exits early since we are not reading c++ (line lib/Index/USRGeneration.cpp:238).


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} 

[PATCH] D46084: [Fixed Point Arithmetic] Addition of the Fixed Point _Accum type

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147386.
leonardchan added a comment.

Ran git-clang-tidy on all affected files


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;  // expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum; // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum;  // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = 

[PATCH] D47030: [Fixed Point Arithmetic] Checks for Precision Macros

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.
Herald added a subscriber: mgorny.

This patch includes checks that the precision macros used for the fixed point 
fractional and integral bits meet the requirements for clause 6.2.6.3 in 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf.

Checks for any disagreements with the recommendations will throw warnings.

I also added my own warning that recommends the integral and fractional bits 
for _Accum types take up the width of the whole underlying integer to prevent 
having to mask out the padding bits when performing comparisons.


Repository:
  rC Clang

https://reviews.llvm.org/D47030

Files:
  cmake/modules/InitFixedPointBits.cmake

Index: cmake/modules/InitFixedPointBits.cmake
===
--- cmake/modules/InitFixedPointBits.cmake
+++ cmake/modules/InitFixedPointBits.cmake
@@ -60,26 +60,170 @@
   set(ULACCUM_IBIT 32)
 endif()
 
-# Checks for each bit size
+# Checks for each bit size defined in clause 6.2.6.3
+
+# Cannot go below the minimum number of fractional and integral bits for the
+# various types specified in clause 7.18a.3.
+function(assert_min_bits macro min_bits)
+  set("macro_name" ${macro})
+  set("macro_val" ${${macro}})
+  if(${macro_val} LESS ${min_bits})
+message(FATAL_ERROR "The minimum value allowed for ${macro_name} is ${min_bits}. "
+	"${macro_val} was provided.")
+  endif()
+endfunction()
+
+assert_min_bits(SFRACT_FBIT 7)
+assert_min_bits(FRACT_FBIT 15)
+assert_min_bits(LFRACT_FBIT 23)
+assert_min_bits(USFRACT_FBIT 7)
+assert_min_bits(UFRACT_FBIT 15)
+assert_min_bits(ULFRACT_FBIT 23)
+
+assert_min_bits(SACCUM_FBIT 7)
+assert_min_bits(ACCUM_FBIT 15)
+assert_min_bits(LACCUM_FBIT 23)
+assert_min_bits(USACCUM_FBIT 7)
+assert_min_bits(UACCUM_FBIT 15)
+assert_min_bits(ULACCUM_FBIT 23)
+
+assert_min_bits(SACCUM_IBIT 4)
+assert_min_bits(ACCUM_IBIT 4)
+assert_min_bits(LACCUM_IBIT 4)
+assert_min_bits(USACCUM_IBIT 4)
+assert_min_bits(UACCUM_IBIT 4)
+assert_min_bits(ULACCUM_IBIT 4)
+
 # Each unsigned fract type has either the same number of fractional bits as,
 # or one more fractional bit than, its corresponding signed fract type.
-# TODO: Implement remaining checks in clause 6.2.6.3.
-function(check_diff_at_most_1 sfract_fbits ufract_fbits)
-  if(sfract_fbits EQUAL ufract_fbits)
-return()
-  endif()
+function(assert_fract_diff sfract_fbits ufract_fbits)
   math(EXPR diff "${ufract_fbits} - ${sfract_fbits}")
-  if(diff EQUAL 1)
-return()
+  if(NOT((${diff} EQUAL 0) OR (${diff} EQUAL 1)))
+message(FATAL_ERROR "Each unsigned fract type must have either the same number of "
+  	"fractional bits as, or one more fractional bit than, its corresponding "
+  	"signed fract type.")
+  endif()
+endfunction()
+
+assert_fract_diff(${SFRACT_FBIT} ${USFRACT_FBIT})
+assert_fract_diff(${FRACT_FBIT} ${UFRACT_FBIT})
+assert_fract_diff(${LFRACT_FBIT} ${ULFRACT_FBIT})
+
+# When arranged in order of increasing rank (see 6.3.1.3a), the number of
+# fractional bits is nondecreasing for each of the following sets of
+# fixed-point types:
+# - signed fract types
+# - unsigned fract types
+# - signed accum types
+# - unsigned accum types.
+function(assert_non_decreasing short_type_bits middle_type_bits long_type_bits
+	 type_family bit_type)
+  if((${short_type_bits} GREATER ${middle_type_bits}) OR
+ (${middle_type_bits} GREATER ${long_type_bits}))
+message(FATAL_ERROR "The number of ${bit_type} bits in ${type_family} types must be "
+  	"non decreasing in order of increasing rank.")
+  endif()
+endfunction()
+
+assert_non_decreasing(${SFRACT_FBIT} ${FRACT_FBIT} ${LFRACT_FBIT} "signed _Fract" "fractional")
+assert_non_decreasing(${USFRACT_FBIT} ${UFRACT_FBIT} ${ULFRACT_FBIT} "unsigned _Fract" "fractional")
+assert_non_decreasing(${SACCUM_FBIT} ${ACCUM_FBIT} ${LACCUM_FBIT} "signed _Accum" "fractional")
+assert_non_decreasing(${USACCUM_FBIT} ${UACCUM_FBIT} ${ULACCUM_FBIT} "unsigned _Accum" "fractional")
+
+# When arranged in order of increasing rank (see 6.3.1.3a), the number of
+# integral bits is nondecreasing for each of the following sets of
+# fixed-point types:
+# - signed accum types
+# - unsigned accum types.
+assert_non_decreasing(${SACCUM_IBIT} ${ACCUM_IBIT} ${LACCUM_IBIT} "signed _Accum" "integral")
+assert_non_decreasing(${USACCUM_IBIT} ${UACCUM_IBIT} ${ULACCUM_IBIT} "unsigned _Accum" "integral")
+
+# Each signed accum type has at least as many integral bits as its
+# corresponding unsigned accum type.
+function(assert_integral_diff saccum_ibits uaccum_ibits)
+  if(${saccum_ibits} LESS ${uaccum_ibits})
+message(FATAL_ERROR "Each signed accum type must have at least as many integral bits as its "
+	"corresponding unsigned accum type.")
+  endif()
+endfunction()
+
+assert_integral_diff(${SACCUM_IBIT} ${USACCUM_IBIT})
+assert_integral_diff(${ACCUM_IBIT} 

[PATCH] D47017: [Fixed Point Arithmetic] Validation Test for Saturated Shift Left, Saturated Unsigned _Fract Types, and Fix for Saturated Unsigned Addition

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch includes changes for the shift left operator involving saturated 
fixed point types.

For unsigned shifting, overflow occurs if the number of bits we shift exceeds 
the number of leading zeros in the number. This number is found using the 
intrinsic llvm function `ctlz`.

For signed shifting, if the number is positive, we cap at the max value for 
that type if the number of bits we shift exceeds the number of leading zeros. 
If the number is negative, we cap at the min value for that type if the number 
of bits we shift exceeds the number of leading ones. `ctlz` can be used in this 
case after flipping the bits in the number.

- Saturation tests were also added for saturated unsigned _Fract types.
- Added a fix to unsigned addition for saturated fixed point types where we 
would not be able to get the overflow if the number of data bits was equal to 
the underlying integer width. In this case, we need to use the intrinsic 
function `uadd.with.overflow` to detect overflow on this carry bit.

This is a child of https://reviews.llvm.org/D47016


Repository:
  rC Clang

https://reviews.llvm.org/D47017

Files:
  include/clang/AST/Type.h
  lib/CodeGen/CGExprScalar.cpp
  test/Frontend/fixed_point_all_builtin_operations.c

Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- test/Frontend/fixed_point_all_builtin_operations.c
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -105,6 +105,20 @@
 a = -0.8 ## SUFFIX; \
 b = 0.5 ## SUFFIX; \
 ASSERT(a / b == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
+a = 0.1 ## SUFFIX; \
+ASSERT(a << 4 == 1.0 ## SUFFIX); \
+a = -0.8 ## SUFFIX; \
+ASSERT(a << 4 == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
+  }
+
+#define FRACT_SATU_BINARY_OPS(TYPE, ID, SUFFIX) \
+  { \
+TYPE a = 0.7 ## SUFFIX; \
+TYPE b = 0.9 ## SUFFIX; \
+ASSERT(a + b == 1.0 ## SUFFIX); \
+ASSERT(a - b == 0.0 ## SUFFIX); \
+ASSERT(b / a == 1.0 ## SUFFIX); \
+ASSERT(a << 1 == 1.0 ## SUFFIX); \
   }
 
 int main(){
@@ -119,5 +133,9 @@
   FRACT_SAT_BINARY_OPS(_Sat _Fract, SatFract, r);
   FRACT_SAT_BINARY_OPS(_Sat long _Fract, SatLongFract, lr);
 
+  FRACT_SATU_BINARY_OPS(_Sat unsigned short _Fract, SatUnsignedShortFract, uhr);
+  FRACT_SATU_BINARY_OPS(_Sat unsigned _Fract, SatUnsignedFract, ur);
+  FRACT_SATU_BINARY_OPS(_Sat unsigned long _Fract, SatUnsignedLongFract, ulr);
+
   return 0;
 }
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -1144,7 +1144,9 @@
   }
 
   // Ignore conversions like int -> uint.
-  if (SrcTy == DstTy)
+  // Except for fixed point types which may need radix transformations.
+  bool WorkingOnFixedPoints = DstType->isFixedPointType() && SrcType->isFixedPointType();
+  if (SrcTy == DstTy && !WorkingOnFixedPoints)
 return Src;
 
   // Handle pointer conversions next: pointers can only be converted to/from
@@ -1248,7 +1250,6 @@
 DstTy = CGF.FloatTy;
   }
 
-  bool WorkingOnFixedPoints = DstType->isFixedPointType() && SrcType->isFixedPointType();
   int order = WorkingOnFixedPoints ? CGF.getContext().getFixedPointTypeOrder(DstType, SrcType) : 0;
 
   if (WorkingOnFixedPoints && order < 0) {
@@ -2876,7 +2877,7 @@
 
   // Number of data + sign bits used in division
   unsigned DividendBits = FixedPointBits + fbits;
-  unsigned BitMask = (1 << DividendBits) - 1;
+  uint64_t BitMask = (static_cast<__int128_t>(1ULL) << DividendBits) - 1;
   llvm::Value *MaskedDivResult = Builder.CreateAnd(DivResult, BitMask);
 
   if (Ops.Ty->isSignedFixedPointType()) {
@@ -3310,19 +3311,19 @@
 llvm::Value *SatMinVal = llvm::ConstantInt::get(
 opTy, getFixedPointMinVal(op.Ty));
 
-unsigned MSBBitShift;
 if (op.Ty->isSignedFixedPointType()) {
-  MSBBitShift = getFixedPointIBits(op.Ty) + getFixedPointFBits(op.Ty);
-} else {
-  MSBBitShift = getFixedPointIBits(op.Ty) + getFixedPointFBits(op.Ty) - 1;
-}
+  unsigned MSBBitShift;
+  if (op.Ty->isSignedFixedPointType()) {
+MSBBitShift = getFixedPointIBits(op.Ty) + getFixedPointFBits(op.Ty);
+  } else {
+MSBBitShift = getFixedPointIBits(op.Ty) + getFixedPointFBits(op.Ty) - 1;
+  }
 
-llvm::Value *Sum = Builder.CreateAdd(op.LHS, op.RHS);
-llvm::Value *LHSMSB = Builder.CreateLShr(op.LHS, MSBBitShift);
-llvm::Value *RHSMSB = Builder.CreateLShr(op.RHS, MSBBitShift);
-llvm::Value *ResultMSB = Builder.CreateLShr(Sum, MSBBitShift);
+  llvm::Value *Sum = Builder.CreateAdd(op.LHS, op.RHS);
+  llvm::Value *LHSMSB = Builder.CreateLShr(op.LHS, MSBBitShift);
+  llvm::Value *RHSMSB = Builder.CreateLShr(op.RHS, MSBBitShift);
+  llvm::Value *ResultMSB = Builder.CreateLShr(Sum, 

[PATCH] D47016: [Fixed Point Arithmetic] Validation Test for Saturated Division and Comparison Fix

2018-05-17 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch includes changes for division on saturated fixed point types. 
Overflow occurs when the resulting value cannot fit into the number of data 
bits for the resulting type.

For signed division, we cap at the max value of the type when the dividend sign 
is positive, divisor sign is negative, but the quotient is still positive. 
Reciprocally, we cap at the min value if the dividend is negative, divisor is 
positive, and quotient is negative.

For unsigned division, overflow occurs if the resulting value exceeds the max 
possible value that this type can hold.

The logic for comparisons between fixed point types was also fixed to account 
for padding bits. Since the padding bits contains values we do not care about, 
we mask the fixed point data bits in the underlying integral that we do care 
about and compare them.

This is a child of https://reviews.llvm.org/D46990


Repository:
  rC Clang

https://reviews.llvm.org/D47016

Files:
  include/clang/AST/Type.h
  include/clang/Basic/FixedPoint.h.in
  lib/AST/Type.cpp
  lib/CodeGen/CGExprScalar.cpp
  test/Frontend/fixed_point_all_builtin_operations.c
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -57,7 +57,7 @@
 
   s_accum = s_accum2;
   // CHECK:  {{.*}} = load i16, i16* %s_accum2, align 2
-  // CHECK-NEXT: store i16 %1, i16* %s_accum, align 2
+  // CHECK-NEXT: store i16 {{.*}}, i16* %s_accum, align 2
 
   assert(s_accum == s_accum2);
   // CHECK:  {{.*}} = load i16, i16* %s_accum, align 2
@@ -114,9 +114,13 @@
   // CHECK:  {{.*}} = icmp sgt i16 {{.*}}, {{.*}}
 
   assert(s_fract2 < s_fract);
-  // CHECK:  {{.*}} = load i16, i16* %s_fract2, align 2
-  // CHECK-NEXT: {{.*}} = load i16, i16* %s_fract, align 2
-  // CHECK-NEXT: {{.*}} = icmp slt i16 {{.*}}, {{.*}}
+  // CHECK:  [[VAL:%.+]] = load i16, i16* %s_fract2, align 2
+  // CHECK-NEXT: [[VAL2:%.+]] = load i16, i16* %s_fract, align 2
+  // CHECK-NEXT: [[SHIFTED_VAL:%.+]] = shl i16 [[VAL]], 8
+  // CHECK-NEXT: [[CORRECTED_VAL:%.+]] = ashr i16 [[SHIFTED_VAL]], 8
+  // CHECK-NEXT: [[SHIFTED_VAL2:%.+]] = shl i16 [[VAL2]], 8
+  // CHECK-NEXT: [[CORRECTED_VAL2:%.+]] = ashr i16 [[SHIFTED_VAL2]], 8
+  // CHECK-NEXT: {{.*}} = icmp slt i16 [[CORRECTED_VAL]], [[CORRECTED_VAL2]]
 
   assert(s_fract >= s_fract);
   // CHECK:  {{.*}} = icmp sge i16 {{.*}}, {{.*}}
Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- test/Frontend/fixed_point_all_builtin_operations.c
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -99,6 +99,12 @@
 ASSERT(sub ## ID(a, b) == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
 a = -0.5 ## SUFFIX - 0.5 ## SUFFIX; \
 ASSERT(mul ## ID(a, a) == 1.0 ## SUFFIX); \
+a = 0.8 ## SUFFIX; \
+b = 0.5 ## SUFFIX; \
+ASSERT(a / b == 1.0 ## SUFFIX); \
+a = -0.8 ## SUFFIX; \
+b = 0.5 ## SUFFIX; \
+ASSERT(a / b == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
   }
 
 int main(){
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -2837,6 +2837,14 @@
 assert(LHSTy == RHSTy);
 
 bool isSignedResult = LHSTy->isSignedFixedPointType() || RHSTy->isSignedFixedPointType();
+unsigned fbits = getFixedPointFBits(Ops.Ty);
+unsigned ibits = getFixedPointIBits(Ops.Ty);
+unsigned FixedPointBits;
+if (isSignedResult) {
+  FixedPointBits = fbits + ibits + 1;
+} else {
+  FixedPointBits = fbits + ibits;
+}
 
 // Round up the bit widths to allocate enough space for calculating the
 // result.
@@ -2848,9 +2856,85 @@
 
 LHSVal = Builder.CreateIntCast(LHSVal, Builder.getIntNTy(bufferWidth), isSignedResult);
 RHSVal = Builder.CreateIntCast(RHSVal, Builder.getIntNTy(bufferWidth), isSignedResult);
-LHSVal = Builder.CreateShl(LHSVal, getFixedPointFBits(LHSTy));
 
+LHSVal = Builder.CreateShl(LHSVal, fbits);
 llvm::Value* DivResult = Builder.CreateSDiv(LHSVal, RHSVal);
+
+if (Ops.Ty->isSaturatedFixedPointType()) {
+  llvm::Value *SatMaxVal = llvm::ConstantInt::get(
+  DivResult->getType(), getFixedPointMaxVal(Ops.Ty));
+  llvm::Value *SatMinVal = llvm::ConstantInt::get(
+  DivResult->getType(), getFixedPointMinVal(Ops.Ty));
+
+  unsigned FixedPointBits;
+  if (Ops.Ty->isSignedFixedPointType()) {
+FixedPointBits = getFixedPointIBits(Ops.Ty) + getFixedPointFBits(Ops.Ty) + 1;
+  } else {
+FixedPointBits = getFixedPointIBits(Ops.Ty) + getFixedPointFBits(Ops.Ty);
+  }
+  unsigned MSBBitShift = FixedPointBits - 1;
+
+  // Number of data + 

[PATCH] D46990: [Fixed Point Arithmetic] Validation Test for Saturated Multiplication

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains changes for multiplication on saturated _Fract types.

Since we already upcast the underlying integer for the fixed point type, we can 
do a simple check to see if the resulting value is larger or smaller than the 
max or min for the fixed point types.

This is a child of https://reviews.llvm.org/D46987


Repository:
  rC Clang

https://reviews.llvm.org/D46990

Files:
  lib/CodeGen/CGExprScalar.cpp
  test/Frontend/fixed_point_all_builtin_operations.c

Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- test/Frontend/fixed_point_all_builtin_operations.c
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -97,6 +97,8 @@
 a = -0.7 ## SUFFIX; \
 b = 0.9 ## SUFFIX; \
 ASSERT(sub ## ID(a, b) == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
+a = -0.5 ## SUFFIX - 0.5 ## SUFFIX; \
+ASSERT(mul ## ID(a, a) == 1.0 ## SUFFIX); \
   }
 
 int main(){
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -690,11 +690,84 @@
 bufferWidth = 128;
   }
 
-  LHSVal = Builder.CreateIntCast(LHSVal, Builder.getIntNTy(bufferWidth), isSignedResult);
-  RHSVal = Builder.CreateIntCast(RHSVal, Builder.getIntNTy(bufferWidth), isSignedResult);
+  llvm::Type *ResultTy = Builder.getIntNTy(bufferWidth);
+  LHSVal = Builder.CreateIntCast(LHSVal, ResultTy, isSignedResult);
+  RHSVal = Builder.CreateIntCast(RHSVal, ResultTy, isSignedResult);
 
   llvm::Value* MulResult = Builder.CreateMul(LHSVal, RHSVal);
   MulResult = Builder.CreateAShr(MulResult, getFixedPointFBits(Ops.Ty));
+
+  // At this point, MulResult has not been truncated yet and still has extra
+  // assigned bits we can use to check for magnitude overflows.
+  if (Ops.Ty->isSaturatedFixedPointType()) {
+llvm::Value *SatMaxVal = llvm::ConstantInt::get(
+ResultTy, getFixedPointMaxVal(Ops.Ty));
+llvm::Value *SatMinVal = llvm::ConstantInt::get(
+ResultTy, getFixedPointMinVal(Ops.Ty));
+
+unsigned FixedPointBits;
+if (Ops.Ty->isSignedFixedPointType()) {
+  FixedPointBits = getFixedPointIBits(Ops.Ty) + getFixedPointFBits(Ops.Ty) + 1;
+} else {
+  FixedPointBits = getFixedPointIBits(Ops.Ty) + getFixedPointFBits(Ops.Ty);
+}
+unsigned MSBBitShift = FixedPointBits - 1;
+
+// Number of data + sign bits used in multiplication result after
+// shifting but before truncation.
+unsigned UntruncatedBitWidth = FixedPointBits * 2;
+unsigned BitMask = (1 << UntruncatedBitWidth) - 1;
+llvm::Value *MaskedMulResult = Builder.CreateAnd(MulResult, BitMask);
+
+if (Ops.Ty->isSignedFixedPointType()) {
+  if (Ops.Ty->isAccumFixedPointType()) {
+llvm::Type *Int1Ty = llvm::Type::getInt1Ty(Ops.LHS->getContext());
+llvm::Value *LHSMSB = Builder.CreateIntCast(Builder.CreateLShr(Ops.LHS, MSBBitShift),
+Int1Ty, /*isSigned=*/true);
+llvm::Value *RHSMSB = Builder.CreateIntCast(Builder.CreateLShr(Ops.RHS, MSBBitShift),
+Int1Ty, /*isSigned=*/true);
+
+// Cap at max if both operand signs were the same and the result is greater than the
+// max possible value.
+llvm::Value *UseSatMax = Builder.CreateAnd(
+Builder.CreateICmpEQ(LHSMSB, RHSMSB),
+Builder.CreateICmpUGT(MaskedMulResult, SatMaxVal));
+
+// Cap at min if the operands were different, and the unsigned
+// respresentation of the result is greater than the maximum possible
+// unsigned value that can be represented with the resulting fixed
+// point bits. Don't use SatMaxVal here since it represents the max
+// for an signed value.
+llvm::Value *UseSatMin = Builder.CreateAnd(
+Builder.CreateXor(LHSMSB, RHSMSB),
+Builder.CreateICmpUGT(MaskedMulResult, llvm::ConstantInt::get(ResultTy, BitMask)));
+
+MulResult = Builder.CreateSelect(
+UseSatMax, SatMaxVal, Builder.CreateSelect(UseSatMin, SatMinVal, MulResult));
+  } else {
+// The only situation a _Fract overflows is if both are signed and
+// equal to -1. Signed multiplication would yield a result of -1 when
+// the result should be 1. Instead return the max possible value.
+assert(Ops.Ty->isFractFixedPointType());
+
+unsigned FractMask = (1ULL << FixedPointBits) - 1;
+llvm::Value *MaskedLHSVal = Builder.CreateAnd(LHSVal, FractMask, 

[PATCH] D46987: [Fixed Point Arithmetic] Validation Test for Saturated Subtraction on Signed _Fracts

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch includes the logic for subtraction on saturated _Fract types and a 
test for thm.

- Also fixed incorrect minimum value for each _Fract type
- Getters for each fixed point min and max value for a given type
- Correction when casting from a fixed point to a float. If the fixed point 
data and sign bits do not take up the whole width of the integer (ie. has 
padding), we will need to either zero out the padding or extend the sign into 
the padding if it is negative to ensure the correct floating point value is 
produced after casting.

This is a child of https://reviews.llvm.org/D46986


Repository:
  rC Clang

https://reviews.llvm.org/D46987

Files:
  include/clang/AST/Type.h
  include/clang/Basic/FixedPoint.h.in
  lib/AST/Type.cpp
  lib/CodeGen/CGExprScalar.cpp
  test/Frontend/fixed_point_all_builtin_operations.c

Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- test/Frontend/fixed_point_all_builtin_operations.c
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -88,6 +88,15 @@
 TYPE a = 0.7 ## SUFFIX; \
 TYPE b = 0.9 ## SUFFIX; \
 ASSERT(add ## ID(a, b) == 1.0 ## SUFFIX); \
+a = -0.7 ## SUFFIX; \
+b = -0.9 ## SUFFIX; \
+ASSERT(add ## ID(a, b) == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
+a = 0.7 ## SUFFIX; \
+b = -0.9 ## SUFFIX; \
+ASSERT(sub ## ID(a, b) == 1.0 ## SUFFIX); \
+a = -0.7 ## SUFFIX; \
+b = 0.9 ## SUFFIX; \
+ASSERT(sub ## ID(a, b) == -0.5 ## SUFFIX - 0.5 ## SUFFIX); \
   }
 
 int main(){
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -806,6 +806,11 @@
   }
   Value *VisitAsTypeExpr(AsTypeExpr *CE);
   Value *VisitAtomicExpr(AtomicExpr *AE);
+
+  // For all fixed point values, we usually do not care about the padding bits,
+  // but if we convert to another type dependent on the whole value of the
+  // underlying type, we will need to either zero extend or sign extend.
+  llvm::Value* FixedPointExtendSignToPadding(const QualType& Ty, llvm::Value* Val);
 };
 }  // end anonymous namespace.
 
@@ -1675,6 +1680,41 @@
   return true;
 }
 
+// For all fixed point values, we usually do not care about the padding bits,
+// but if we convert to another type dependent on the whole value of the
+// underlying type, we will need to either zero extend or sign extend.
+llvm::Value* ScalarExprEmitter::FixedPointExtendSignToPadding(const QualType& Ty,
+  llvm::Value* Val) {
+  assert(Ty->isFixedPointType());
+
+  llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ty);
+  unsigned BitWidth = opTy->getIntegerBitWidth();
+  unsigned fbits = getFixedPointFBits(Ty);
+  unsigned ibits = getFixedPointIBits(Ty);
+
+  if (Ty->isSignedFixedPointType()) {
+assert((BitWidth >= fbits + ibits + 1) &&
+   "Cannot fit signed fixed point bits into integral type");
+
+unsigned ShiftBits = BitWidth - (fbits + ibits + 1);
+if (!ShiftBits) {
+  return Val;
+}
+
+return Builder.CreateAShr(Builder.CreateShl(Val, ShiftBits), ShiftBits);
+  } else {
+assert((BitWidth >= fbits + ibits) &&
+   "Cannot fit unsigned fixed point bits into integral type");
+
+unsigned ShiftBits = BitWidth - (fbits + ibits);
+if (!ShiftBits) {
+  return Val;
+}
+
+return Builder.CreateLShr(Builder.CreateShl(Val, ShiftBits), ShiftBits);
+  }
+}
+
 // VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
 // have to handle a more broad range of conversions than explicit casts, as they
 // handle things like function to ptr-to-function decay etc.
@@ -1894,8 +1934,12 @@
 assert(DestTy->isFloatingType());
 assert(E->getType()->isFixedPointType());
 unsigned fbits = getFixedPointFBits(E->getType());
-return Builder.CreateFDiv(EmitScalarConversion(Visit(E), E->getType(), DestTy, CE->getExprLoc()),
-  llvm::ConstantFP::get(CGF.CGM.FloatTy, (1ULL << fbits) * 1.0));
+
+llvm::Value *Val = FixedPointExtendSignToPadding(E->getType(), Visit(E));
+Val = EmitScalarConversion(Val, E->getType(), DestTy, CE->getExprLoc());
+
+return Builder.CreateFDiv(
+Val, llvm::ConstantFP::get(CGF.CGM.FloatTy, (1ULL << fbits) * 1.0));
   }
 
   case CK_IntegralCast:
@@ -3104,61 +3148,10 @@
 assert(op.LHS->getType() == op.RHS->getType());
 assert(op.LHS->getType() == opTy);
 
-llvm::Value *SatMaxVal;
-llvm::Value *SatMinVal;
-
-const auto  = op.Ty->getAs();
-switch (BT->getKind()) {
-  default: llvm_unreachable("Unhandled saturated signed fixed point type");
-  case BuiltinType::SatShortAccum:
- SatMaxVal = llvm::ConstantInt::get(opTy, SACCUM_MAX_AS_INT);

[PATCH] D46986: [Fixed Point Arithmetic] Validation Test for Fixed Point Binary Operations and Saturated Addition

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains tests for validating the logic behind each builtin 
operation on fixed point types and tests on addition between saturated _Fract 
types.

- More macros wer added to the FixedPoint.h header on the min and max values 
for each type which will be required for operations on saturated types.
- Updated the logic when converting between fixed point types to take into 
account saturation. Fixed point type conversions do not fall under the "usual 
arithmetic conversions" where the resulting type on a binary operation 
resulting in a fixed point type does not need to be the type of either operands.
- Rounded down _Fract literals of 1 (1.0hr, 1.0r, 1.0lr) to the respective 
maximum values for each _Fract type.

This is a child of https://reviews.llvm.org/D46979


Repository:
  rC Clang

https://reviews.llvm.org/D46986

Files:
  include/clang/AST/Type.h
  include/clang/Basic/FixedPoint.h.in
  lib/AST/Type.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_all_builtin_operations.c

Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- test/Frontend/fixed_point_all_builtin_operations.c
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Werror %s
+// RUN: %clang_cc1 -Werror  -S -emit-llvm %s -o - | lli
 
 // Check that we can use all supported binary and unary operations according to
 // clause 4.1.6 in N1169.
@@ -48,3 +48,59 @@
 ALL_OPERATIONS(short _Accum, ShortAccum);
 ALL_OPERATIONS(_Accum, Accum);
 ALL_OPERATIONS(long _Accum, LongAccum);
+
+#define ASSERT(x) if (!(x)) return 1;
+
+#define BINARY_OPS_FOR_TYPE(TYPE, ID, SUFFIX) \
+  { \
+TYPE a = 0.5 ## SUFFIX; \
+TYPE b = 0.25 ## SUFFIX; \
+ASSERT(add ## ID(a, b) == 0.75 ## SUFFIX); \
+ASSERT(sub ## ID(a, b) == 0.25 ## SUFFIX); \
+ASSERT(mul ## ID(a, b) == 0.125 ## SUFFIX); \
+ASSERT(div ## ID(b, a) == 0.5 ## SUFFIX); \
+ASSERT(shl ## ID(b, 1) == a); \
+ASSERT(shr ## ID(a, 1) == b); \
+ASSERT(lt  ## ID(b, a)); \
+ASSERT(le  ## ID(b, a)); \
+ASSERT(gt  ## ID(a, b)); \
+ASSERT(ge  ## ID(a, b)); \
+ASSERT(eq  ## ID(a, b) == 0); \
+ASSERT(ne  ## ID(a, b)); \
+ASSERT(augmented_add ## ID(a, b) == 0.75 ## SUFFIX); \
+ASSERT(augmented_sub ## ID(a, b) == 0.25 ## SUFFIX); \
+ASSERT(augmented_mul ## ID(a, b) == 0.125 ## SUFFIX); \
+ASSERT(augmented_div ## ID(b, a) == 0.5 ## SUFFIX); \
+ASSERT(augmented_shl ## ID(b, 1) == a); \
+ASSERT(augmented_shr ## ID(a, 1) == b); \
+  }
+
+#define BINARY_OPS(TYPE, ID, SUFFIX) \
+  BINARY_OPS_FOR_TYPE(TYPE, ID, SUFFIX); \
+  BINARY_OPS_FOR_TYPE(signed TYPE, Signed ## ID, SUFFIX); \
+  BINARY_OPS_FOR_TYPE(unsigned TYPE, Unsigned ## ID, u ## SUFFIX); \
+  BINARY_OPS_FOR_TYPE(_Sat TYPE, Sat ## ID, SUFFIX); \
+  BINARY_OPS_FOR_TYPE(_Sat signed TYPE, SatSigned ## ID, SUFFIX); \
+  BINARY_OPS_FOR_TYPE(_Sat unsigned TYPE, SatUnsigned ## ID, u ## SUFFIX);
+
+#define FRACT_SAT_BINARY_OPS(TYPE, ID, SUFFIX) \
+  { \
+TYPE a = 0.7 ## SUFFIX; \
+TYPE b = 0.9 ## SUFFIX; \
+ASSERT(add ## ID(a, b) == 1.0 ## SUFFIX); \
+  }
+
+int main(){
+  BINARY_OPS(short _Fract, ShortFract, hr);
+  BINARY_OPS(_Fract, Fract, r);
+  BINARY_OPS(long _Fract, LongFract, lr);
+  BINARY_OPS(short _Accum, ShortAccum, hk);
+  BINARY_OPS(_Accum, Accum, k);
+  BINARY_OPS(long _Accum, LongAccum, lk);
+
+  FRACT_SAT_BINARY_OPS(_Sat short _Fract, SatShortFract, hr);
+  FRACT_SAT_BINARY_OPS(_Sat _Fract, SatFract, r);
+  FRACT_SAT_BINARY_OPS(_Sat long _Fract, SatLongFract, lr);
+
+  return 0;
+}
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -1254,8 +1254,12 @@
   return FixedPointTy;
 }
 
-/// \brief Handle arithmethic conversion with fixed point types.  Helper
-/// function of UsualArithmeticConversions().
+/// \brief Handle arithmethic conversion with fixed point types. The usual
+/// arithmetic conversions do not apply to fixed point type conversions between
+/// integers or other fixed point types due to potential loss of precision.
+/// For this case of fixed point types, the resulting type in a binary operation
+/// does not need to be exactly one of the 2 operand types.
+/// Implemented according to Clause 6.3.1.8 of ISO/IEC JTC1 SC22 WG14 N1169.
 static QualType handleFixedPointConversion(Sema , ExprResult ,
ExprResult , QualType LHSType,
QualType RHSType,
@@ -1267,30 +1271,25 @@
   bool RHSFixed = RHSType->isFixedPointType();
 
   if (LHSFixed && RHSFixed) {
-// Cast up the smaller operand to the bigger
+bool LHSSigned = LHSType->isSignedFixedPointType();
+bool RHSSigned = 

[PATCH] D46979: [Fixed Point Arithmetic] Test for Conversion Between Valid Builtin Types

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains changes and a test for checking that fixed point types can 
be converted between all other valid types. Fixed point types can be converted 
between floating point types, integral types, and other fixed point types.

This is a child of https://reviews.llvm.org/D46963


Repository:
  rC Clang

https://reviews.llvm.org/D46979

Files:
  include/clang/AST/OperationKinds.def
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_all_conversions.c

Index: test/Frontend/fixed_point_all_conversions.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_conversions.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Test for conversions between fixed point types and all other valid types.
+
+// Conversion from one type to another type
+#define CONVERT(FROM_TYPE, FROM_ID, TO_TYPE, TO_ID) \
+  TO_TYPE FROM_ID ## _to_ ## TO_ID (FROM_TYPE x) { return x; }
+
+// Conversion between 2 types
+#define CONVERT_COMBINATION(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE2, ID2, TYPE1, ID1)
+
+// Conversion between one type and floating point types
+#define CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+  CONVERT_COMBINATION(TYPE, ID, float, Float) \
+  CONVERT_COMBINATION(TYPE, ID, double, Double)
+
+// Conversion between one type and an integral type with differant signage
+#define CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, signed INT_TYPE, Signed ## INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, unsigned INT_TYPE, Unsigned ## INT_ID)
+
+// Conversion between one type and all integral types
+#define CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, char, Char) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, short, Short) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, int, Int) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long, Long) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long long, LongLong)
+
+// Conversion between one type and a fixed point type with different saturation
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, _Sat FIXED_TYPE, Sat ## FIXED_ID)
+
+// Conversion between one type and a fixed point type with different signage
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, signed FIXED_TYPE, Signed ## FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, unsigned FIXED_TYPE, Unsigned ## FIXED_ID)
+
+// Convert between one type and all fixed point types.
+// Add "Type" to the end of the ID to avoid multiple definitions of a function
+// if the Type is a fixed point type.
+#define CONVERT_BETWEEN_FIXED_POINT(TYPE, ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Fract, FractType) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Accum, AccumType)
+
+// Convert between one type and all other types
+#define CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+  CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+  CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)
+
+#define CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(_Sat TYPE, Sat ## ID)
+
+#define CONVERT_FIXED_POINT_TYPE(TYPE, ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(signed TYPE, Signed ## ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(unsigned TYPE, Unsigned ## ID)
+
+CONVERT_FIXED_POINT_TYPE(short _Fract, ShortFract);
+CONVERT_FIXED_POINT_TYPE(_Fract, Fract);
+CONVERT_FIXED_POINT_TYPE(long _Fract, LongFract);
+
+CONVERT_FIXED_POINT_TYPE(short _Accum, ShortAccum);
+CONVERT_FIXED_POINT_TYPE(_Accum, Accum);
+CONVERT_FIXED_POINT_TYPE(long _Accum, LongAccum);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -321,6 +321,7 @@
 const LocationContext *LCtx = Pred->getLocationContext();
 
 switch (CastE->getCastKind()) {
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
   case 

[PATCH] D46963: [Fixed Point Arithmetic] Test for All Builtin Operations

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch includes a test for checking that all supported builtin operations 
can be syntactically declared with fixed point types. Tests for asserting the 
correctness behind each operation will be added in future patches.

This is a child of https://reviews.llvm.org/D46960


Repository:
  rC Clang

https://reviews.llvm.org/D46963

Files:
  lib/AST/ASTContext.cpp
  lib/CodeGen/CGExprScalar.cpp
  test/Frontend/fixed_point_all_builtin_operations.c

Index: test/Frontend/fixed_point_all_builtin_operations.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_builtin_operations.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Check that we can use all supported binary and unary operations according to
+// clause 4.1.6 in N1169.
+
+#define ALL_OPERATIONS_FOR_TYPE(TYPE, ID) \
+  TYPE unary_add ## ID (TYPE a)  { return +a; } \
+  TYPE unary_sub ## ID (TYPE a)  { return -a; } \
+  int logical_not ## ID (TYPE a)  { return !a; } \
+  TYPE add ## ID (TYPE a, TYPE b) { return a + b; } \
+  TYPE sub ## ID (TYPE a, TYPE b) { return a - b; } \
+  TYPE mul ## ID (TYPE a, TYPE b) { return a * b; } \
+  TYPE div ## ID (TYPE a, TYPE b) { return a / b; } \
+  TYPE shl ## ID (TYPE a, int b) { return a << b; } \
+  TYPE shr ## ID (TYPE a, int b) { return a >> b; } \
+  TYPE augmented_add ## ID (TYPE a, TYPE b) { a += b; return a; } \
+  TYPE augmented_sub ## ID (TYPE a, TYPE b) { a -= b; return a; } \
+  TYPE augmented_mul ## ID (TYPE a, TYPE b) { a *= b; return a; } \
+  TYPE augmented_div ## ID (TYPE a, TYPE b) { a /= b; return a; } \
+  TYPE augmented_shl ## ID (TYPE a, int b) { a <<= b; return a; } \
+  TYPE augmented_shr ## ID (TYPE a, int b) { a >>= b; return a; } \
+  int eq ## ID (TYPE a, TYPE b) { return a == b; } \
+  int ne ## ID (TYPE a, TYPE b) { return a != b; } \
+  int lt ## ID (TYPE a, TYPE b) { return a < b; } \
+  int le ## ID (TYPE a, TYPE b) { return a <= b; } \
+  int ge ## ID (TYPE a, TYPE b) { return a >= b; } \
+  int gt ## ID (TYPE a, TYPE b) { return a > b; } \
+  TYPE pre_inc ## ID (TYPE a) { return ++a; } \
+  TYPE pre_dec ## ID (TYPE a) { return --a; } \
+  TYPE post_inc ## ID (TYPE a) { return a++; } \
+  TYPE post_dec ## ID (TYPE a) { return a--; } \
+  TYPE deref_pre_inc ## ID (TYPE *a) { return ++(*a); } \
+  TYPE deref_pre_dec ## ID (TYPE *a) { return --(*a); } \
+  TYPE deref_post_inc ## ID (TYPE *a) { return (*a)++; } \
+  TYPE deref_post_dec ## ID (TYPE *a) { return (*a)--; }
+
+#define ALL_OPERATIONS(TYPE, ID) \
+  ALL_OPERATIONS_FOR_TYPE(TYPE, ID) \
+  ALL_OPERATIONS_FOR_TYPE(signed TYPE, Signed ## ID) \
+  ALL_OPERATIONS_FOR_TYPE(unsigned TYPE, Unsigned ## ID) \
+  ALL_OPERATIONS_FOR_TYPE(_Sat TYPE, Sat ## ID) \
+  ALL_OPERATIONS_FOR_TYPE(_Sat signed TYPE, SatSigned ## ID) \
+  ALL_OPERATIONS_FOR_TYPE(_Sat unsigned TYPE, SatUnsigned ## ID)
+
+ALL_OPERATIONS(short _Fract, sf);
+ALL_OPERATIONS(_Fract, f);
+ALL_OPERATIONS(long _Fract, lf);
+ALL_OPERATIONS(short _Accum, sa);
+ALL_OPERATIONS(_Accum, a);
+ALL_OPERATIONS(long _Accum, la);
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -2204,17 +2204,29 @@
 const auto *BT = type->getAs();
 switch (BT->getKind()) {
   default: llvm_unreachable("Not a fixed point type!");
+  case BuiltinType::SatShortAccum:
   case BuiltinType::ShortAccum:   fbits = BUILTIN_SACCUM_FBIT; break;
+  case BuiltinType::SatAccum:
   case BuiltinType::Accum:fbits = BUILTIN_ACCUM_FBIT; break;
+  case BuiltinType::SatLongAccum:
   case BuiltinType::LongAccum:fbits = BUILTIN_LACCUM_FBIT; break;
+  case BuiltinType::SatUShortAccum:
   case BuiltinType::UShortAccum:  fbits = BUILTIN_USACCUM_FBIT; break;
+  case BuiltinType::SatUAccum:
   case BuiltinType::UAccum:   fbits = BUILTIN_UACCUM_FBIT; break;
+  case BuiltinType::SatULongAccum:
   case BuiltinType::ULongAccum:   fbits = BUILTIN_ULACCUM_FBIT; break;
+  case BuiltinType::SatShortFract:
   case BuiltinType::ShortFract:   fbits = BUILTIN_SFRACT_FBIT; break;
+  case BuiltinType::SatFract:
   case BuiltinType::Fract:fbits = BUILTIN_FRACT_FBIT; break;
+  case BuiltinType::SatLongFract:
   case BuiltinType::LongFract:fbits = BUILTIN_LFRACT_FBIT; break;
+  case BuiltinType::SatUShortFract:
   case BuiltinType::UShortFract:  fbits = BUILTIN_USFRACT_FBIT; break;
+  case BuiltinType::SatUFract:
   case BuiltinType::UFract:   fbits = BUILTIN_UFRACT_FBIT; break;
+  case BuiltinType::SatULongFract:
   case BuiltinType::ULongFract:   fbits = BUILTIN_ULFRACT_FBIT; break;
 }
 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), 1ULL << fbits,
Index: 

[PATCH] D46960: [Fixed Point Arithmetic] Predefined Precision Macros

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains the addition of the precision macros for integral and 
fractional bits according to clause 7.18a.3 of 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf. The macros are 
integer constants and added as predefined macros.

  // Fractional bits of _Accum types
  __SACCUM_FBIT__
  __ACCUM_FBIT__
  __LACCUM_FBIT__
  __USACCUM_FBIT__
  __UACCUM_FBIT__
  __ULACCUM_FBIT__
  
  // Fractional bits of _Fract types
  __SFRACT_FBIT__
  __FRACT_FBIT__
  __LFRACT_FBIT__
  __USFRACT_FBIT__
  __UFRACT_FBIT__
  __ULFRACT_FBIT__
  
  // Integral bits of _Accum types
  __SACCUM_IBIT__
  __ACCUM_IBIT__
  __LACCUM_IBIT__
  __USACCUM_IBIT__
  __UACCUM_IBIT__
  __ULACCUM_IBIT__

This is a child of https://reviews.llvm.org/D46927


Repository:
  rC Clang

https://reviews.llvm.org/D46960

Files:
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPMacroExpansion.cpp
  test/Frontend/fixed_point_builtin_macros.c

Index: test/Frontend/fixed_point_builtin_macros.c
===
--- /dev/null
+++ test/Frontend/fixed_point_builtin_macros.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+
+#define assert(b) if (!(b)) { return 1; }
+
+int main() {
+  // Test using the recommended values for a typical desktop processor (Annex
+  // A.3). These are also the default values when building clang.
+  // Fractional bits of _Accum types
+  assert(__SACCUM_FBIT__  == 7);
+  assert(__ACCUM_FBIT__   == 15);
+  assert(__LACCUM_FBIT__  == 31);
+  assert(__USACCUM_FBIT__ == 8);
+  assert(__UACCUM_FBIT__  == 16);
+  assert(__ULACCUM_FBIT__ == 32);
+
+  // Fractional bits of _Fract types
+  assert(__SFRACT_FBIT__  == 7);
+  assert(__FRACT_FBIT__   == 15);
+  assert(__LFRACT_FBIT__  == 31);
+  assert(__USFRACT_FBIT__ == 8);
+  assert(__UFRACT_FBIT__  == 16);
+  assert(__ULFRACT_FBIT__ == 32);
+
+  // Integral bits of _Accum types
+  assert(__SACCUM_IBIT__  == 8);
+  assert(__ACCUM_IBIT__   == 16);
+  assert(__LACCUM_IBIT__  == 32);
+  assert(__USACCUM_IBIT__ == 8);
+  assert(__UACCUM_IBIT__  == 16);
+  assert(__ULACCUM_IBIT__ == 32);
+}
Index: lib/Lex/PPMacroExpansion.cpp
===
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -14,6 +14,7 @@
 
 #include "clang/Basic/Attributes.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -355,6 +356,31 @@
   Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
   Ident__TIMESTAMP__ = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
 
+  // Fixed point macros (ISO/IEC JTC1 SC22 WG14 N1169)
+  // Fractional bits of _Accum types
+  Ident__SACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__SACCUM_FBIT__");
+  Ident__ACCUM_FBIT__= RegisterBuiltinMacro(*this, "__ACCUM_FBIT__");
+  Ident__LACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__LACCUM_FBIT__");
+  Ident__USACCUM_FBIT__  = RegisterBuiltinMacro(*this, "__USACCUM_FBIT__");
+  Ident__UACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__UACCUM_FBIT__");
+  Ident__ULACCUM_FBIT__  = RegisterBuiltinMacro(*this, "__ULACCUM_FBIT__");
+
+  // Fractional bits of _Fract types
+  Ident__SFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__SFRACT_FBIT__");
+  Ident__FRACT_FBIT__= RegisterBuiltinMacro(*this, "__FRACT_FBIT__");
+  Ident__LFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__LFRACT_FBIT__");
+  Ident__USFRACT_FBIT__  = RegisterBuiltinMacro(*this, "__USFRACT_FBIT__");
+  Ident__UFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__UFRACT_FBIT__");
+  Ident__ULFRACT_FBIT__  = RegisterBuiltinMacro(*this, "__ULFRACT_FBIT__");
+
+  // Integral bits of _Accum types
+  Ident__SACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__SACCUM_IBIT__");
+  Ident__ACCUM_IBIT__= RegisterBuiltinMacro(*this, "__ACCUM_IBIT__");
+  Ident__LACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__LACCUM_IBIT__");
+  Ident__USACCUM_IBIT__  = RegisterBuiltinMacro(*this, "__USACCUM_IBIT__");
+  Ident__UACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__UACCUM_IBIT__");
+  Ident__ULACCUM_IBIT__  = RegisterBuiltinMacro(*this, "__ULACCUM_IBIT__");
+
   // Microsoft Extensions.
   if (LangOpts.MicrosoftExt) {
 Ident__identifier = RegisterBuiltinMacro(*this, "__identifier");
@@ -1696,6 +1722,68 @@
 // __LINE__ expands to a simple numeric value.
 OS << (PLoc.isValid()? PLoc.getLine() : 1);
 Tok.setKind(tok::numeric_constant);
+
+  // Fixed point macros
+  // Fractional bits of _Accum types
+  } else if (II == Ident__SACCUM_FBIT__) {
+OS << BUILTIN_SACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ACCUM_FBIT__) {
+OS << BUILTIN_ACCUM_FBIT;
+Tok.setKind(tok::numeric_constant);
+  } else if (II == 

[PATCH] D46927: Augmented Assignment for Fixed Point Types

2018-05-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains the changes and tests for augmented assignments for primary 
fixed point types.

  s_accum = 7.5hk;
  s_accum2 = 2.0hk;
  s_accum += s_accum2;
  assert(s_accum == 9.5hk);
  s_accum += 2.5k;
  assert(s_accum == 12);

This is a parent of https://reviews.llvm.org/D46926


Repository:
  rC Clang

https://reviews.llvm.org/D46927

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -279,4 +279,35 @@
   float laccum_diff = abs(base - 2.333lk);
   assert(accum_diff < saccum_diff);
   assert(laccum_diff < accum_diff);
+
+  / Auxillary assignments ***/
+
+  s_accum = 7.5hk;
+  s_accum2 = 2.0hk;
+  s_accum += s_accum2;
+  assert(s_accum == 9.5hk);
+  s_accum += 2.5k;
+  assert(s_accum == 12);
+
+  s_accum -= s_accum2;
+  assert(s_accum == 10);
+  s_accum -= 2.5lk;
+  assert(s_accum == 7.5k);
+
+  s_accum2 = 3.0k;
+  s_accum *= s_accum2;
+  assert(s_accum == 22.5k);
+  s_accum *= 0.5r;
+  assert(s_accum == 11.25hk);
+
+  s_accum /= s_accum2;
+  assert(s_accum == 3.75k);
+  s_accum /= 0.5hr;
+  assert(s_accum == 7.5k);
+
+  s_accum <<= 3;
+  assert(s_accum == 60);
+
+  s_accum >>= 3;
+  assert(s_accum == 7.5k);
 }
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -6057,7 +6057,7 @@
   default: llvm_unreachable("Unable to convert from fixed point type");
   case Type::STK_Integral: llvm_unreachable("Unimplemented scalar cast from fixed point to int");  // TODO
   case Type::STK_Floating: return CK_FixedPointToFloating;
-  case Type::STK_FixedPoint: llvm_unreachable("Unimplemented scalar cast from fixed point to fixed point");  // TODO
+  case Type::STK_FixedPoint: return CK_FixedPointCast;
 }
   }
 
Index: lib/CodeGen/CGExprScalar.cpp
===
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -308,6 +308,17 @@
   Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
   SourceLocation Loc, bool TreatBooleanAsSigned);
 
+  /// Emit a conversion between fixed point types by moving the radix point.
+  /// This does not take into account resizing of the underlying llvm type
+  /// which should be handled either before or after calling this function.
+  /// 
+  /// If the type is being scaled up, this method should be called after
+  /// performing an intcast. If the type is scaled down, this method should be
+  /// called before performing an intcast. This is necessary such that the
+  /// shift operations retain as much of the original data as possible before
+  /// truncation or after extension.
+  Value *EmitFixedPointRadixShift(Value *Src, QualType SrcTy, QualType DstTy);
+
   /// Emit a conversion from the specified complex type to the specified
   /// destination type, where the destination type is an LLVM scalar type.
   Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
@@ -957,6 +968,50 @@
 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
 }
 
+
+/// Emit a conversion between fixed point types by moving the radix point.
+/// This does not take into account resizing of the underlying llvm type
+/// which should be handled either before or after calling this function.
+/// 
+/// If the type is being scaled up, this method should be called after
+/// performing an intcast. If the type is scaled down, this method should be
+/// called before performing an intcast. This is necessary such that the
+/// shift operations retain as much of the original data as possible before
+/// truncation or after extension.
+Value *ScalarExprEmitter::EmitFixedPointRadixShift(Value *Src, QualType SrcTy,
+   QualType DstTy) {
+  assert(DstTy->isFixedPointType());
+  assert(SrcTy->isFixedPointType());
+
+  Value* Res = Src;
+
+  // Casting between fixed point types involves separating the integral and
+  // fractional bits, potentially shifting them, then joining back together.
+  unsigned dest_fbits = getFixedPointFBits(DstTy);
+  unsigned src_fbits = getFixedPointFBits(SrcTy);
+  unsigned dest_ibits = getFixedPointIBits(DstTy);
+  unsigned src_ibits = getFixedPointIBits(SrcTy);
+
+  // If the number of integral bits is decreasing, trim off any extra bits while
+  // retaining the sign.
+  if (dest_ibits < src_ibits) {
+Res = Builder.CreateShl(Res, src_ibits - dest_ibits);
+Res = Builder.CreateAShr(Res, src_ibits - 

[PATCH] D46926: Conversion between Fixed Point and Floating Point Numbers

2018-05-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch has the implementation and tests for converting between fixed point 
and floating point numbers.

The conversion process is simply dividing the fixed point value, as an integer, 
by 2^(# of fractional bits) as a float.

This is a parent of https://reviews.llvm.org/D46925


Repository:
  rC Clang

https://reviews.llvm.org/D46926

Files:
  include/clang/AST/OperationKinds.def
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaCast.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -30,6 +30,7 @@
 // Run simple validation tests
 
 #define assert(b) if (!(b)) { return 1; }
+#define abs(x) x < 0 ? -x : x
 
 int main(){
   short _Accum s_accum = 0.0hk;
@@ -264,4 +265,18 @@
   assert(5.0hk >> 2 == 1.25hk);
   assert(-5.0hk >> 2 == -1.25k);
   assert(0.0hr >> 2 == 0);
+
+  / Float conversions ***/
+
+  float f = (float)2.5k;
+  assert(f > 2.4999 && f < 2.5001);  // High precision since the fractional value can be evenly
+ // represented.
+  assert((float)2.333hk != 2.333f);
+
+  float base = 2.333f;
+  float saccum_diff = abs(base - 2.333hk);
+  float accum_diff = abs(base - 2.333k);
+  float laccum_diff = abs(base - 2.333lk);
+  assert(accum_diff < saccum_diff);
+  assert(laccum_diff < accum_diff);
 }
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -321,6 +321,7 @@
 const LocationContext *LCtx = Pred->getLocationContext();
 
 switch (CastE->getCastKind()) {
+  case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
   case CK_IntegralToFixedPoint: llvm_unreachable("ExprEngine::VisitCast CK_IntegralToFixedPoint"); // TODO
   case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
   case CK_LValueToRValue:
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -1029,6 +1029,18 @@
   return result;
 }
 
+/// \brief Handle arithmetic conversion from fixed point to floating.  Helper function
+/// of UsualArithmeticConversions()
+static QualType handleFixedPointToFloatConversion(Sema , ExprResult ,
+  ExprResult ,
+  QualType FloatTy, QualType FixedPointTy) {
+  assert(FloatTy->isFloatingType());
+  assert(FixedPointTy->isFixedPointType());
+
+  FixedPointExpr = S.ImpCastExprToType(FixedPointExpr.get(), FloatTy, CK_FixedPointToFloating);
+  return FloatTy;
+}
+
 /// \brief Handle arithmethic conversion with floating point types.  Helper
 /// function of UsualArithmeticConversions()
 static QualType handleFloatConversion(Sema , ExprResult ,
@@ -1057,11 +1069,22 @@
 if (LHSType->isHalfType() && !S.getLangOpts().NativeHalfType)
   LHSType = S.Context.FloatTy;
 
+if (RHSType->isFixedPointType()) {
+  return handleFixedPointToFloatConversion(S, LHS, RHS, LHSType,
+   RHSType);
+}
+
 return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType,
   /*convertFloat=*/!IsCompAssign,
   /*convertInt=*/ true);
   }
   assert(RHSFloat);
+
+  if (LHSType->isFixedPointType()) {
+return handleFixedPointToFloatConversion(S, RHS, LHS, RHSType,
+ LHSType);
+  }
+
   return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType,
 /*convertInt=*/ true,
 /*convertFloat=*/!IsCompAssign);
@@ -1218,6 +1241,7 @@
   CK_IntegralRealToComplex);
   return ComplexType;
 }
+
 /// \brief Handle arithmetic conversion from integer to fixed point.  Helper function
 /// of UsualArithmeticConversions()
 static QualType handleIntToFixedPointConversion(Sema , ExprResult ,
@@ -6028,7 +6052,14 @@
 }
 llvm_unreachable("Should have returned before this");
 
-  case Type::STK_FixedPoint: llvm_unreachable("Sema::PrepareScalarCast from STK_FixedPoint to anything");  // TODO
+  case Type::STK_FixedPoint: {
+switch 

[PATCH] D46925: Remaining Binary Operations on Primary Fixed Point Types

2018-05-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch implements the remaining arithmetic and logical operations on the 
primary fixed point types.

The operations are `+`, `-`, `*`, `/`, `<<`, and `>>`.

  // Addition
   s_accum = 3.0hk;
   short _Accum s_accum_sum = s_accum + s_accum2;
   assert(s_accum_sum == 5);
   assert(s_fract + s_fract2 == 0);
  
   // Subtraction
   short _Accum s_accum_diff = s_accum - s_accum2;
   assert(s_accum_diff == 1);
   assert(s_accum2 - s_accum == -1);
  
   // Multiplication
   short _Accum s_accum_mul = s_accum * s_accum2;
   assert(s_accum_mul == 6);
   assert(2.0hk * 3.0hk == 6);
   assert(2.0hk * 3 == 6);
   assert(2.5hk * 3 == 7.5k);
   assert(-2.5hk * 3 == -7.5lk);
   assert(3 * -2.5hk == -7.5hk);
   assert(-2.5hk * 0 == 0);
  
   // Division
   const short _Accum s_accum3 = 2.5hk;
   short _Accum s_accum_div = s_accum3 / s_accum2;
   assert(s_accum_div == 1.25hk);
   assert(5.0hk / s_accum3 == 2);
   assert(-5.0hk / s_accum3 == -2);
   assert(9.9k / 3.3k == 3);
   assert(9.9hk / 3.3k != 3);  // We lose precision when converting between 
types of different
   // fractional width.
   assert(6.75hk / 2.25k == 3);  // Unless the fractional part can be evenly 
represented with
 // sums of powers of 2.
   assert(0 / 2.0hk == 0);

`%` is not a valod operation on fixed point types.

This is the parent of https://reviews.llvm.org/D46917


Repository:
  rC Clang

https://reviews.llvm.org/D46925

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/OperationKinds.def
  include/clang/AST/Type.h
  lib/AST/ASTContext.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -1,5 +1,5 @@
-// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
 // RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
 
 // The first test checks the emitted llvm IR.
 // The second test checks the output.
@@ -74,6 +74,9 @@
   assert(2 == s_accum);
   // CHECK:  {{.*}} = icmp eq i16 256, {{.*}}
 
+  assert(2 == 2.0hk);
+  assert(2 != 2.01hk);
+
   int x = 2;
   assert(s_accum == x);
   // CHECK:  {{.*}} = load i32, i32* %x, align 4
@@ -128,6 +131,46 @@
   // numbers.
   assert(2 == 2.001hk);  // This is valid if SACCUM_FBITS == 7
 
+  // Comparisons between fixed-point types
+  // Signed _Accum to signed _Accum types.
+  assert(2.5hk == 2.5k);
+  assert(2.5k == 2.5lk);
+  assert(-2.5hk == -2.5k);
+  assert(-2.5k == -2.5lk);
+
+  // Unsigned _Accum to unigned _Accum
+  assert(2.5uhk == 2.5uk);
+  assert(2.5uk == 2.5ulk);
+
+  // Signed _Fract to signed _Fract types.
+  assert(0.333hr != 0.333r);  // Loss of precision since different fractional widths
+  assert(0.333r != 0.333lr);
+  assert(-0.333hr != -0.333r);
+  assert(-0.333r != -0.333lr);
+
+  // Unsigned _Fract to unsigned _Fract types.
+  assert(0.333uhr != 0.333ur);
+  assert(0.333ur != 0.333ulr);
+
+  // Signed _Accum to signed _Fract
+  assert(0.333hk == 0.333hr);
+  assert(0.333k == 0.333r);
+  assert(0.333lk == 0.333lr);
+  assert(0.333hk == 0.333r);  // Although _Fract has higher precision, it gets casted up to
+  // short _Accum which (using default precisions)
+  // has fewer fractional bits.
+
+  // Signed _Accum to unsigned _Fract
+  assert(0.333hk == 0.333uhr);
+  assert(0.333k == 0.333ur);
+  assert(0.333lk == 0.333ulr);
+
+  // Signed _Accum to unsigned _Accum
+  assert(2.5hk == 2.5uhk);
+  assert(2.5k == 2.5uk);
+  assert(2.5lk == 2.5ulk);
+
+
   / Unary operations ***/
 
   s_accum = 0.0hk;
@@ -167,4 +210,58 @@
   assert(+s_fract == s_fract);
   assert(+s_fract2 == s_fract2);  // s_fract2 is negative
   assert(-s_fract == s_fract2);
+
+  / Binary operations ***/
+
+  // Addition
+  s_accum = 3.0hk;
+  short _Accum s_accum_sum = s_accum + s_accum2;
+  assert(s_accum_sum == 5);
+  assert(s_fract + s_fract2 == 0);
+
+  // Subtraction
+  short _Accum s_accum_diff = s_accum - s_accum2;
+  assert(s_accum_diff == 1);
+  assert(s_accum2 - s_accum == -1);
+
+  // Multiplication
+  short _Accum s_accum_mul = s_accum * s_accum2;
+  assert(s_accum_mul == 6);
+  assert(2.0hk * 3.0hk == 6);
+  assert(2.0hk * 3 == 6);
+  assert(2.5hk * 3 == 7.5k);
+  assert(-2.5hk * 3 == -7.5lk);
+  assert(3 * -2.5hk == -7.5hk);
+  assert(-2.5hk * 

[PATCH] D46917: Comparison and Unary Operations for Fixed Point Types

2018-05-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr.
leonardchan added a project: clang.

This patch contains logic and tests for different unary and comparison 
operations on fixed point types, and casting between integers and fixed point 
types.

The operations are `==`, `!=`, `>`, `<`, `>=`, `<=`, `!`, `+`, `-`, `++`, and 
`--`.

`~` is not a supported operation on fixed point types.

This is a parent of https://reviews.llvm.org/D46915


Repository:
  rC Clang

https://reviews.llvm.org/D46917

Files:
  lib/CodeGen/CGExprScalar.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_declarations.c
  test/Frontend/fixed_point_validation.c

Index: test/Frontend/fixed_point_validation.c
===
--- test/Frontend/fixed_point_validation.c
+++ test/Frontend/fixed_point_validation.c
@@ -1,19 +1,170 @@
+// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
 // RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
 
+// The first test checks the emitted llvm IR.
+// The second test checks the output.
+// Both these test require that the default bit widths for the fixed point types
+// are used since we check for bit shifted literals that were converted from
+// ints and floats.
+
+// Primary fixed point types
+signed short _Accum s_short_accum;// CHECK-DAG: @s_short_accum =  common dso_local global i16 0, align 2
+signed _Accum s_accum;// CHECK-DAG: @s_accum =common dso_local global i32 0, align 4
+signed long _Accum s_long_accum;  // CHECK-DAG: @s_long_accum =   common dso_local global i64 0, align 8
+unsigned short _Accum u_short_accum;  // CHECK-DAG: @u_short_accum =  common dso_local global i16 0, align 2
+unsigned _Accum u_accum;  // CHECK-DAG: @u_accum =common dso_local global i32 0, align 4
+unsigned long _Accum u_long_accum;// CHECK-DAG: @u_long_accum =   common dso_local global i64 0, align 8
+signed short _Fract s_short_fract;// CHECK-DAG: @s_short_fract =  common dso_local global i16 0, align 2
+signed _Fract s_fract;// CHECK-DAG: @s_fract =common dso_local global i32 0, align 4
+signed long _Fract s_long_fract;  // CHECK-DAG: @s_long_fract =   common dso_local global i64 0, align 8
+unsigned short _Fract u_short_fract;  // CHECK-DAG: @u_short_fract =  common dso_local global i16 0, align 2
+unsigned _Fract u_fract;  // CHECK-DAG: @u_fract =common dso_local global i32 0, align 4
+unsigned long _Fract u_long_fract;// CHECK-DAG: @u_long_fract =   common dso_local global i64 0, align 8
+
+// There are 7 bits allocated to the fractional part and 8
+// bits allocated to the integral part of a short _Accum by default.
+
+signed short _Accum s_short_accum2 = 2.5hk;  // CHECK-DAG: @s_short_accum2 = dso_local global i16 320, align 2
+short _Fract short_fract = 0.333hr;  // CHECK-DAG: @short_fract = dso_local global i16 42, align 2
+
 // Run simple validation tests
 
 #define assert(b) if (!(b)) { return 1; }
 
 int main(){
-  short _Accum s_accum;
+  short _Accum s_accum = 0.0hk;
   short _Accum s_accum2 = 2.0hk;
   short _Fract s_fract = 0.999hr;
   short _Fract s_fract2 = -0.999hr;
+  const _Fract fract_zero = 0.0r;
+  // CHECK:  %s_accum = alloca i16, align 2
+  // CHECK:  %s_accum2 = alloca i16, align 2
+  // CHECK:  %s_fract = alloca i16, align 2
+  // CHECK:  %s_fract2 = alloca i16, align 2
+  // CHECK:  %fract_zero = alloca i32, align 4
+  // CHECK:  store i16 0, i16* %s_accum, align 2
+  // CHECK:  store i16 256, i16* %s_accum2, align 2
+  // CHECK:  store i16 127, i16* %s_fract, align 2
+  // CHECK:  store i16 -127, i16* %s_fract2, align 2
+  // CHECK:  store i32 0, i32* %fract_zero, align 4
+
+  / Simple Comparisons ***/
 
   assert(s_accum == 0);
+  // CHECK:  {{.*}} = load i16, i16* %s_accum, align 2
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, 0
 
   s_accum = s_accum2;
+  // CHECK:  {{.*}} = load i16, i16* %s_accum2, align 2
+  // CHECK-NEXT: store i16 %1, i16* %s_accum, align 2
 
   assert(s_accum == s_accum2);
+  // CHECK:  {{.*}} = load i16, i16* %s_accum, align 2
+  // CHECK-NEXT: {{.*}} = load i16, i16* %s_accum2, align 2
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, {{.*}}
+
+  assert(s_accum2 == s_accum);
+  // CHECK:  {{.*}} = load i16, i16* %s_accum2, align 2
+  // CHECK-NEXT: {{.*}} = load i16, i16* %s_accum, align 2
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, {{.*}}
+
   assert(s_accum == 2);
+  // CHECK:  {{.*}} = icmp eq i16 {{.*}}, 256
+
+  assert(2 == s_accum);
+  // CHECK:  {{.*}} = icmp eq i16 256, {{.*}}
+
+  int x = 2;
+  assert(s_accum == x);
+  // CHECK:  {{.*}} = load i32, i32* %x, align 4
+  // CHECK-NEXT: {{.*}} = trunc i32 {{.*}} to i16
+  // CHECK-NEXT: {{.*}} = shl i16 {{.*}}, 7
+  // CHECK-NEXT: {{.*}} = icmp eq i16 {{.*}}, {{.*}}
+
+  assert(x == s_accum);
+
+  

[PATCH] D46915: Set Fixed Point Precision Bits and Create Fixed Point Literals

2018-05-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.
Herald added a subscriber: mgorny.

This diff includes the logic for setting the precision bits for each primary 
fixed point type when building clang and logic for initializing a fixed point 
literal.

The precision bits are set when building cmake via the flags

  SACCUM_FBIT
  ACCUM_FBIT
  LACCUM_FBIT
  ...

More checks to ensure the bit values used are valid will be added in future 
patches.

Fixed point literals are declared using the suffixes

  hr: short _Fract
  uhr: unsigned short _Fract
  r: _Fract
  ur: unsigned _Fract
  lr: long _Fract
  ulr: unsigned long _Fract
  hk: short _Accum
  uhk: unsigned short _Accum
  k: _Accum
  uk: unsigned _Accum

Errors are also thrown for literal values that exceed the range of the type 
corresponding to the suffix

  unsigned short _Accum u_short_accum = 256.0uhk;   // expected-error{{the 
integral part of this literal is too large for this unsigned _Accum type}}

This is a parent of https://reviews.llvm.org/D46911


Repository:
  rC Clang

https://reviews.llvm.org/D46915

Files:
  CMakeLists.txt
  cmake/modules/InitFixedPointBits.cmake
  include/clang/AST/Expr.h
  include/clang/AST/OperationKinds.def
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/FixedPoint.h.in
  include/clang/Basic/StmtNodes.td
  include/clang/Lex/LiteralSupport.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Lex/LiteralSupport.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_declarations.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_validation.c
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -305,6 +305,10 @@
 K = CXCursor_IntegerLiteral;
 break;
 
+  case Stmt::FixedPointLiteralClass:
+llvm_unreachable("No cursor for FixedPointLiteralClass");
+break;
+
   case Stmt::FloatingLiteralClass:
 K = CXCursor_FloatingLiteral;
 break;
Index: test/Frontend/fixed_point_validation.c
===
--- /dev/null
+++ test/Frontend/fixed_point_validation.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+
+// Run simple validation tests
+
+#define assert(b) if (!(b)) { return 1; }
+
+int main(){
+  short _Accum s_accum;
+  short _Accum s_accum2 = 2.0hk;
+  short _Fract s_fract = 0.999hr;
+  short _Fract s_fract2 = -0.999hr;
+
+  assert(s_accum == 0);
+
+  s_accum = s_accum2;
+
+  assert(s_accum == s_accum2);
+  assert(s_accum == 2);
+}
Index: test/Frontend/fixed_point_errors.c
===
--- test/Frontend/fixed_point_errors.c
+++ test/Frontend/fixed_point_errors.c
@@ -1,14 +1,23 @@
 // RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
 
-long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
-unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
-long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
-unsigned long long _Fract u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;   // expected-error{{'long long _Fract' is invalid}}
 
 _Sat int i;  // expected-error{{'int' cannot be saturated. Only _Fract and _Accum can.}}
 _Sat _Sat _Fract fract;  // expected-warning{{duplicate '_Sat' declaration specifier}}
 
-_Sat long long _Accum sat_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Accum sat_longlong_accum; // expected-error{{'long long _Accum' is invalid}}
 _Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
-_Sat long long _Fract sat_longlong_fract;  // 

[PATCH] D46911: Addition of the remaining fixed point types and their saturated equivalents

2018-05-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added a project: clang.

This diff includes changes for the remaining _Fract and _Sat fixed point types.

  signed short _Fract s_short_fract;
  signed _Fract s_fract;
  signed long _Fract s_long_fract;
  unsigned short _Fract u_short_fract;
  unsigned _Fract u_fract;
  unsigned long _Fract u_long_fract;
  
  // Aliased fixed point types
  short _Accum short_accum;
  _Accum accum;
  long _Accum long_accum;
  short _Fract short_fract;
  _Fract fract;
  long _Fract long_fract;
  
  // Saturated fixed point types
  _Sat signed short _Accum sat_s_short_accum;
  _Sat signed _Accum sat_s_accum;
  _Sat signed long _Accum sat_s_long_accum;
  _Sat unsigned short _Accum sat_u_short_accum;
  _Sat unsigned _Accum sat_u_accum;
  _Sat unsigned long _Accum sat_u_long_accum;
  _Sat signed short _Fract sat_s_short_fract;
  _Sat signed _Fract sat_s_fract;
  _Sat signed long _Fract sat_s_long_fract;
  _Sat unsigned short _Fract sat_u_short_fract;
  _Sat unsigned _Fract sat_u_fract;
  _Sat unsigned long _Fract sat_u_long_fract;
  
  // Aliased saturated fixed point types
  _Sat short _Accum sat_short_accum;
  _Sat _Accum sat_accum;
  _Sat long _Accum sat_long_accum;
  _Sat short _Fract sat_short_fract;
  _Sat _Fract sat_fract;
  _Sat long _Fract sat_long_fract;

This diff only allows for declaration of these fixed point types. Assignment 
and other operations done on fixed point types according to 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf will be added in 
future patches.

This is a parent of https://reviews.llvm.org/D46084


Repository:
  rC Clang

https://reviews.llvm.org/D46911

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp

Index: test/Frontend/fixed_point_errors.c
===
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+long long _Fract longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+unsigned long long _Fract u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+
+_Sat int i;  // expected-error{{'int' cannot be saturated. Only _Fract and _Accum can.}}
+_Sat _Sat _Fract fract;  // expected-warning{{duplicate '_Sat' declaration specifier}}
+
+_Sat long long _Accum sat_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+_Sat long long _Fract sat_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
+_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
Index: test/Frontend/fixed_point.c
===
--- /dev/null
+++ test/Frontend/fixed_point.c
@@ -0,0 +1,82 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+signed short _Fract s_short_fract;
+signed _Fract s_fract;
+signed long _Fract s_long_fract;
+unsigned short _Fract u_short_fract;
+unsigned _Fract u_fract;
+unsigned long _Fract u_long_fract;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+short _Fract short_fract;
+_Fract fract;
+long _Fract long_fract;
+
+// Saturated fixed point types
+_Sat signed short _Accum sat_s_short_accum;
+_Sat signed _Accum sat_s_accum;
+_Sat signed long _Accum sat_s_long_accum;
+_Sat unsigned short _Accum sat_u_short_accum;
+_Sat unsigned _Accum sat_u_accum;
+_Sat unsigned long _Accum sat_u_long_accum;
+_Sat signed short _Fract sat_s_short_fract;
+_Sat signed _Fract 

[PATCH] D46084: Addition of the Fixed Point _Accum type

2018-05-09 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 145993.
leonardchan added a comment.

- Restrict usage of fixed point types only to C


https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.c
  test/Frontend/accum_errors.c
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++ %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed _Accum s_accum;  // expected-error{{Fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned _Accum u_accum;// expected-error{{Fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;  // expected-error{{Fixed point types are only allowed in C}}
+
+short _Accum short_accum;   // expected-error{{Fixed point types are only allowed in C}}
+_Accum accum;   // expected-error{{Fixed point types are only allowed in C}}
+long _Accum long_accum; // expected-error{{Fixed point types are only allowed in C}}
Index: test/Frontend/accum_errors.c
===
--- /dev/null
+++ test/Frontend/accum_errors.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.c
===
--- /dev/null
+++ test/Frontend/accum.c
@@ -0,0 +1,26 @@
+// RUN: %clang -cc1 -x c -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+//CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+//CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = 

[PATCH] D46084: Addition of the Fixed Point _Accum type

2018-04-25 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr.
leonardchan added a project: clang.

This diff includes changes for supporting the following types.

  // Primary fixed point types
  signed short _Accum s_short_accum;
  signed _Accum s_accum;
  signed long _Accum s_long_accum;
  unsigned short _Accum u_short_accum;
  unsigned _Accum u_accum;
  unsigned long _Accum u_long_accum;
  
  // Aliased fixed point types
  short _Accum short_accum;
  _Accum accum;
  long _Accum long_accum;

This diff only allows for declaration of the fixed point types. Assignment and 
other operations done on fixed point types according to 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf will be added in 
future patches. The saturated versions of these types and the equivalent 
`_Fract` types will also be added in future patches.

The tests included are for asserting that we can declare these types.


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/accum.cpp
  test/Frontend/accum_errors.cpp
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
 BTCASE(Float);
 BTCASE(Double);
 BTCASE(LongDouble);
+BTCASE(ShortAccum);
+BTCASE(Accum);
+BTCASE(LongAccum);
+BTCASE(UShortAccum);
+BTCASE(UAccum);
+BTCASE(ULongAccum);
 BTCASE(Float16);
 BTCASE(Float128);
 BTCASE(NullPtr);
@@ -542,6 +548,12 @@
 TKIND(Float);
 TKIND(Double);
 TKIND(LongDouble);
+TKIND(ShortAccum);
+TKIND(Accum);
+TKIND(LongAccum);
+TKIND(UShortAccum);
+TKIND(UAccum);
+TKIND(ULongAccum);
 TKIND(Float16);
 TKIND(Float128);
 TKIND(NullPtr);
Index: test/Frontend/accum_errors.cpp
===
--- /dev/null
+++ test/Frontend/accum_errors.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+long long _Accum longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
Index: test/Frontend/accum.cpp
===
--- /dev/null
+++ test/Frontend/accum.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+//CHECK:  |-VarDecl {{.*}} s_short_accum 'short _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+//CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+//CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum'
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6816,6 +6816,24 @@
 case PREDEF_TYPE_LONGDOUBLE_ID:
   T = Context.LongDoubleTy;
   break;
+case PREDEF_TYPE_SHORT_ACCUM_ID:
+  T = Context.ShortAccumTy;
+  break;
+case PREDEF_TYPE_ACCUM_ID:
+  T = Context.AccumTy;
+  break;
+case PREDEF_TYPE_LONG_ACCUM_ID:
+  T = Context.LongAccumTy;
+  break;
+case PREDEF_TYPE_USHORT_ACCUM_ID:
+  T = Context.UnsignedShortAccumTy;
+  break;
+case PREDEF_TYPE_UACCUM_ID:
+  T = Context.UnsignedAccumTy;
+  break;
+case PREDEF_TYPE_ULONG_ACCUM_ID:
+  T = Context.UnsignedLongAccumTy;
+  break;
 case PREDEF_TYPE_FLOAT16_ID:
   T = Context.Float16Ty;
   

<    4   5   6   7   8   9