[PATCH] D46911: [Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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;