[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

2023-05-23 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D151087#4362059 , @aaron.ballman 
wrote:

> Based on all this, I think we should go with `__addrspace_cast` as a named 
> cast and not allow the conversion through `reinterpret_cast` unless going 
> to/from a `[u]intptr_t`.

I think this sounds good. Most of the building blocks for it should already be 
in place in the form of OpenCL's addrspace_cast. It would remove 
reinterpret_cast's ability to perform safe conversions, though. Could that 
affect something else inadvertently? ICS or SCS?

There are other C++ casts that deal with address spaces today. static_cast can 
also do it when converting from a void pointer, for example. Should it also 
lose the ability?

In D151087#4362135 , @arsenm wrote:

> In D151087#4361237 , @ebevhan wrote:
>
>> What is now a reinterpret_cast? An address space conversion, or a bitcast? 
>> It's not as straightforward as it might seem.
>
> This is the most straightforward part. It's a bitcast.

And because of that, it wouldn't be possible to perform address space 
conversions between such pointers using reinterpret_cast.

In D151087#4362216 , @jhuber6 wrote:

> I'm not sure if casting away an address space is always legal, it's generally 
> what we do in LLVM-IR.

The TR says this:

  There is no requirement that named address spaces (intrinsic or otherwise) be 
subsets of the
  generic address space.

but also what Aaron pasted in his earlier comment:

  A non-null pointer into an address space A can be cast to a pointer into 
another address space B,
  but such a cast is undefined if the source pointer does not point to a 
location in B.

So, according to the report, converting to the generic address space would 
always be valid, but might be undefined. I've never understood why the TR did 
it this way; there's no reason to allow such conversions if we know they are 
undefined at compile time. Conversions that are undecidable (from superset to 
subset) are one thing, but the report makes no validity restrictions on 
converting between disjoint spaces.

Undefined could technically mean "emit an error", but this isn't what Clang 
does today, and lots of tests and probably code depends on it working like that 
now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087

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


[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

2023-05-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D151087#4361263 , @jhuber6 wrote:

> I'd rather have an operation whose semantics are a little dangerous than 
> something that doesn't work at all. As it stands we need to use C-style casts 
> for this and I don't think there's a good reason to forbid this at least from 
> the C++ standard point of view. For OpenCL where we have the concept of 
> address spaces it makes sense, but not for C++.

I don't think the standard argument really holds. It doesn't mention 
restrictions on address spaces because it doesn't have to, since they don't 
exist in C++. If they did, I'm pretty sure that reinterpret_cast would disallow 
arbitrary address space-modifying casts, since they wouldn't necessarily be 
bitcasts.

Like @arsenm said, any behaviors that you're using or observing regarding 
conversion of target address spaces in both C and C++ are purely coincidental. 
I don't think it's a great idea to add more such coincidental behaviors. The 
result will be that future code will become dependent on these arbitrary, less 
restrictive behaviors, and it will be much harder to properly define sensible 
semantics later on.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087

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


[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

2023-05-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D151087#4360859 , @jhuber6 wrote:

> You can have address spaced in freestanding C++, they just need to be 
> assigned according to the backens, e.g. https://godbolt.org/z/ahazae6Ta. And 
> I don't think that's a desirable solution because it would require a language 
> extension to cover a use-case that isn't disallowed by the C++ standard 
> anyway. I don't see a reason why we shouldn't be able to do this directly.

The problem with reinterpret_cast is that it isn't sufficient for arbitrary 
address space configurations. The first issue is that reinterpret_cast 
inherently performs a bitcast, which is not allowed if the pointers to address 
spaces being casted between are of different sizes. Then, the reinterpret_cast 
would suddenly have different semantics than a bitcast.

Another (contrived, but possible) case is if you have address spaces on a 
target where the spaces overlap, but with different semantics between them, and 
the pointers have the same size. What is now a reinterpret_cast? An address 
space conversion, or a bitcast? It's not as straightforward as it might seem.

Clang hasn't needed to formalize all of the address space behavior because it's 
managed to piggyback off of the language semantics provided by OpenCL, and no 
targets really have had a need for it. Once you start looking at the target AS 
stuff on its own, you realize it's not really that well defined, and making it 
even less defined by allowing arbitrary conversions isn't the solution.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087

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


[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

2023-05-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D151087#4360743 , @jhuber6 wrote:

> The problem is we don't have `addrspace_cast` in freestanding C++, so as it 
> stands we currently have no way to perform this operation in C++ which is 
> preventing me from implementing things in the LLVM LibC port for GPUs I'm 
> working on.

By "freestanding C++" I assume you mean "C++ without the OpenCL C++ extension" 
and not "C++ without extensions at all", because in the latter case, you don't 
have address spaces either.

This is what I meant in D58346  by "There's 
many places in the codebase where OpenCL flags restrict generic address space 
behavior." Isn't the solution here to allow addrspace_cast even when OpenCL C++ 
isn't turned on, as a more generic extension?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087

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


[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

2023-05-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D151087#4360606 , @jhuber6 wrote:

> In D151087#4360577 , @ebevhan wrote:
>
>> What would be the semantics of such an operation if the address spaces are 
>> disjoint? Or, if the underlying pointer widths aren't the same?
>
> It would most likely invalid, but I'm not asserting that `clang` should be 
> responsible for diagnosing misuse in these cases. Especially because in 
> generic freestanding C++ we don't have any language options to suggest the 
> actual semantics.

That's fair. I would like clang to improve and formalize the semantics for 
generic address space behavior a bit, which was part of the point with D62574 
.  But there don't seem to be enough people 
who need something like it to make it happen.

Honestly, looking at the patch again does suggest to me that your use case 
would be covered. It just wouldn't be done with a reinterpret_cast, but an 
addrspace_cast. Since every target by default would permit explicit casts with 
isExplicitAddrSpaceConversionLegal, your desired behavior should work.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087

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


[PATCH] D151087: [Clang] Permit address space casts with 'reinterpret_cast' in C++

2023-05-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

What would be the semantics of such an operation if the address spaces are 
disjoint? Or, if the underlying pointer widths aren't the same?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151087/new/

https://reviews.llvm.org/D151087

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


[PATCH] D58346: [Sema] Change addr space diagnostics in casts to follow C++ style

2023-05-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D58346#4359291 , @jhuber6 wrote:

> should C++ really be limited by OpenCL here?

It probably shouldn't. There's many places in the codebase where OpenCL flags 
restrict generic address space behavior. I have a patch at D62574 
 that attempts to formalize the address space 
rules a bit more (which I think also gets rid of the OpenCL restrictions you 
mention) but there's never been any huge interest and I don't have the time to 
push for it.

Whether that patch actually solves your problem or not, I don't know.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58346/new/

https://reviews.llvm.org/D58346

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


[PATCH] D130510: Missing tautological compare warnings due to unary operators

2022-09-27 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Hi! A bit of late feedback on this patch. We found a failure in our downstream 
testing likely originating from here.

The failing case is:

  void f(int a)
  {
  (0 != (a | !0LL));
  }

built with `clang -cc1 -emit-llvm-bc -O2 -v -o foo.bc -x c foo.c`




Comment at: clang/lib/Analysis/CFG.cpp:1044
+case UO_LNot:
+  return llvm::APInt(Value.getBitWidth(), !Value);
+default:

This isn't returning an APInt of the right width. It will construct an APInt 
with a width of the input value, but that isn't the same as the required width 
of what a logical not produces; that should have a width of 'int'.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130510/new/

https://reviews.llvm.org/D130510

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


[PATCH] D62574: Add support for target-configurable address spaces.

2022-07-14 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Sorry for the delay! I rebased the patch onto latest and it mostly worked, with 
a few hitches.




Comment at: clang/lib/Sema/SemaCast.cpp:2617-2619
+  (Self.getLangOpts().OpenCL &&
+   (DestPPointee->isFunctionType() ||
+SrcPPointee->isFunctionType() {

Without this, `SemaOpenCL/func.cl` fails since `foo((void*)foo)` is no longer 
an error. Since the function pointer is Default-qualified, 
`isExplicitAddrSpaceConversionLegal` delegates the check to the target, which 
will always return true.

To be honest, the clause in that method for letting targets allow conversions 
where `LangAS::Default` is involved only works so long as every type in OpenCL 
has the "right" semantic AS. When any of them are Default, things like this 
happen.

Maybe we should only ask the target about explicit conversions if both ASes are 
Default or a target AS?



Comment at: clang/lib/Sema/SemaOverload.cpp:5289
 
+  // FIXME: hasAddressSpace is wrong; this check will be skipped if FromType is
+  // not qualified with an address space, but if there's no implicit conversion

Anastasia wrote:
> ebevhan wrote:
> > Anastasia wrote:
> > > Do you have a failing test case, if so feel free to create a bug?
> > Unsure how I'd make one. I suspect this can't be triggered in OpenCL++, 
> > because you can't really have LangAS::Default on FromType there, can you? 
> > It would always be some AS.
> > 
> > Doing it in another way would require a target that has configurable ASes, 
> > which doesn't exist yet. Also, it would require methods qualified with 
> > target ASes, and that doesn't work yet either.
> Ok, that's right in OpenCL almost every type gets an address space early in 
> parsing.
> 
> But if we already know it's a bug and the fix for it we could change this 
> code? Although I think the bug fix should better be done on a separate review.
I made the fix here just to try, and it caused a difference in 
address-space-lambda.clcpp.

I'm not sure why that lambda would be valid just because `mutable` is added... 
So this seems like the correct behavior to me?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

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


[PATCH] D62574: Add support for target-configurable address spaces.

2022-07-14 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 444638.
ebevhan added a comment.
Herald added a subscriber: steakhal.

Rebased and addressed some comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

Files:
  clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp
  clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/CanonicalType.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/Analysis/addrspace-null.c
  clang/test/CodeGenCXX/address-space-cast.cpp
  clang/test/Sema/address_space_print_macro.c
  clang/test/Sema/address_spaces.c
  clang/test/SemaOpenCLCXX/address-space-lambda.clcpp

Index: clang/test/SemaOpenCLCXX/address-space-lambda.clcpp
===
--- clang/test/SemaOpenCLCXX/address-space-lambda.clcpp
+++ clang/test/SemaOpenCLCXX/address-space-lambda.clcpp
@@ -66,7 +66,7 @@
 // expected-warning@-2{{lambda without a parameter clause is a C++2b extension}}
 #endif
 
-  [&] () mutable __private {} ();
+  [&] () mutable __private {} (); // expected-error{{no matching function for call to object of type '(lambda at}} expected-note{{candidate function not viable: 'this' object is in default address space, but method expects object in address space '__private'}}
   [&] () __private mutable {} (); //expected-error{{expected body of lambda expression}}
 }
 
Index: clang/test/Sema/address_spaces.c
===
--- clang/test/Sema/address_spaces.c
+++ clang/test/Sema/address_spaces.c
@@ -71,7 +71,8 @@
 
 // Clang extension doesn't forbid operations on pointers to different address spaces.
 char* cmp(_AS1 char *x,  _AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}} \
+// expected-error{{comparison between  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
 }
 
 char *sub(_AS1 char *x, _AS2 char *y) {
Index: clang/test/Sema/address_space_print_macro.c
===
--- clang/test/Sema/address_space_print_macro.c
+++ clang/test/Sema/address_space_print_macro.c
@@ -14,7 +14,8 @@
 }
 
 char *cmp(AS1 char *x, AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}} \
+// expected-error{{comparison between  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
 }
 
 __attribute__((address_space(1))) char test_array[10];
Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -37,8 +37,9 @@
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
   priv_void_ptr = (__private__ void *)gen_void_ptr;
 
-  // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
-  // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = addrspacecast i8* %[[cast]] to i8 addrspace(5)*
+  // CHECK-NEXT: store i8 addrspace(5)* %[[cast2]]
   priv_void_ptr = (__private__ void *)gen_int_ptr;
 
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
@@ -65,8 +66,9 @@
   // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* noundef %[[cast]])
   func_pvoid((__private__ void *)gen_void_ptr);
 
-  // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
-  // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* noundef %[[cast]])
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = 

[PATCH] D125862: [clang][driver] Add gcc-toolset/devtoolset 12 to prefixes

2022-06-09 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Hi! This test is failing in some of our downstream builds.




Comment at: clang/unittests/Driver/ToolChainTest.cpp:647
+std::unique_ptr C(
+TheDriver.BuildCompilation({"--gcc-toolchain="}));
+ASSERT_TRUE(C);

There's a binary name missing here:

```
{"clang", "--gcc-toolchain="}
```

Driver strips the first argument, so the behavior of this test becomes 
dependent on GCC_INSTALL_PREFIX which can cause it to fail in some cases.



Comment at: clang/unittests/Driver/ToolChainTest.cpp:687
+std::unique_ptr C(
+TheDriver.BuildCompilation({"--gcc-toolchain="}));
+ASSERT_TRUE(C);

Here too.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125862/new/

https://reviews.llvm.org/D125862

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


[PATCH] D62574: Add support for target-configurable address spaces.

2022-06-01 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

I've been away from LLVM development for a while, and sadly this patch has 
languished a bit.

I don't think there were any strong objections to its inclusion, though. If 
there is still interest in reviewing this, I could try to rebase the patch (or 
something resembling it) onto the latest main and see if it still works.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

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


[PATCH] D86447: [AST] Change return type of getTypeInfoInChars to a proper struct instead of std::pair.

2020-10-13 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG101309fe048e: [AST] Change return type of getTypeInfoInChars 
to a proper struct instead of… (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86447/new/

https://reviews.llvm.org/D86447

Files:
  clang/include/clang/AST/ASTContext.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/CodeGen/CGAtomic.cpp
  clang/lib/CodeGen/CGBlocks.cpp
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/CodeGen/CGObjC.cpp
  clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp

Index: clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -248,8 +248,9 @@
   FieldInfo RetVal;
   RetVal.Field = FD;
   auto  = FD->getASTContext();
-  std::tie(RetVal.Size, RetVal.Align) =
-  Ctx.getTypeInfoInChars(FD->getType());
+  auto Info = Ctx.getTypeInfoInChars(FD->getType());
+  RetVal.Size = Info.Width;
+  RetVal.Align = Info.Align;
   assert(llvm::isPowerOf2_64(RetVal.Align.getQuantity()));
   if (auto Max = FD->getMaxAlignment())
 RetVal.Align = std::max(Ctx.toCharUnitsFromBits(Max), RetVal.Align);
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -359,7 +359,7 @@
 ///   leaving one or more empty slots behind as padding.
 static Address emitVoidPtrVAArg(CodeGenFunction , Address VAListAddr,
 QualType ValueTy, bool IsIndirect,
-std::pair ValueInfo,
+TypeInfoChars ValueInfo,
 CharUnits SlotSizeAndAlign,
 bool AllowHigherAlign) {
   // The size and alignment of the value that was passed directly.
@@ -368,8 +368,8 @@
 DirectSize = CGF.getPointerSize();
 DirectAlign = CGF.getPointerAlign();
   } else {
-DirectSize = ValueInfo.first;
-DirectAlign = ValueInfo.second;
+DirectSize = ValueInfo.Width;
+DirectAlign = ValueInfo.Align;
   }
 
   // Cast the address we've calculated to the right type.
@@ -383,7 +383,7 @@
 AllowHigherAlign);
 
   if (IsIndirect) {
-Addr = Address(CGF.Builder.CreateLoad(Addr), ValueInfo.second);
+Addr = Address(CGF.Builder.CreateLoad(Addr), ValueInfo.Align);
   }
 
   return Addr;
@@ -656,7 +656,7 @@
 "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!");
 
 auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty);
-CharUnits TyAlignForABI = TyInfo.second;
+CharUnits TyAlignForABI = TyInfo.Align;
 
 llvm::Type *BaseTy =
 llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
@@ -2062,8 +2062,8 @@
   //
   // Just messing with TypeInfo like this works because we never pass
   // anything indirectly.
-  TypeInfo.second = CharUnits::fromQuantity(
-getTypeStackAlignInBytes(Ty, TypeInfo.second.getQuantity()));
+  TypeInfo.Align = CharUnits::fromQuantity(
+getTypeStackAlignInBytes(Ty, TypeInfo.Align.getQuantity()));
 
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false,
   TypeInfo, CharUnits::fromQuantity(4),
@@ -4067,10 +4067,9 @@
 RegAddr = CGF.Builder.CreateElementBitCast(RegAddr, LTy);
 
 // Copy to a temporary if necessary to ensure the appropriate alignment.
-std::pair SizeAlign =
-getContext().getTypeInfoInChars(Ty);
-uint64_t TySize = SizeAlign.first.getQuantity();
-CharUnits TyAlign = SizeAlign.second;
+auto TInfo = getContext().getTypeInfoInChars(Ty);
+uint64_t TySize = TInfo.Width.getQuantity();
+CharUnits TyAlign = TInfo.Align;
 
 // Copy into a temporary if the type is more aligned than the
 // register save area.
@@ -4573,7 +4572,7 @@
 llvm::report_fatal_error("vector type is not supported on AIX yet");
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
-  TypeInfo.second = getParamTypeAlignment(Ty);
+  TypeInfo.Align = getParamTypeAlignment(Ty);
 
   CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize);
 
@@ -4692,7 +4691,7 @@
   QualType Ty) const {
   if (getTarget().getTriple().isOSDarwin()) {
 auto TI = getContext().getTypeInfoInChars(Ty);
-TI.second = getParamTypeAlignment(Ty);
+TI.Align = getParamTypeAlignment(Ty);
 
 CharUnits SlotSize 

[PATCH] D86631: [Fixed Point] Add fixed-point to floating point cast types and consteval.

2020-10-13 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9fa7f4845976: [Fixed Point] Add fixed-point to floating 
point cast types and consteval. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86631/new/

https://reviews.llvm.org/D86631

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

Index: clang/test/Frontend/fixed_point_unknown_conversions.c
===
--- clang/test/Frontend/fixed_point_unknown_conversions.c
+++ clang/test/Frontend/fixed_point_unknown_conversions.c
@@ -22,16 +22,12 @@
   _Fract fract = accum; // ok
   _Accum *accum_ptr;
 
-  accum = f;   // expected-error{{conversion between fixed point and 'float' is not yet supported}}
-  accum = d;   // expected-error{{conversion between fixed point and 'double' is not yet supported}}
   accum = dc;  // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
   accum = ic;  // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
   accum = s;   // expected-error{{assigning to '_Accum' from incompatible type 'struct S'}}
   accum = ptr; // expected-error{{assigning to '_Accum' from incompatible type 'int *'}}
   accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}}
 
-  f = accum;   // expected-error{{conversion between fixed point and 'float' is not yet supported}}
-  d = accum;   // expected-error{{conversion between fixed point and 'double' is not yet supported}}
   dc = accum;  // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
   ic = accum;  // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
   s = accum;   // expected-error{{assigning to 'struct S' from incompatible type '_Accum'}}
Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -286,8 +286,3 @@
 
 // Division by zero
 short _Accum div_zero = 4.5k / 0.0lr;  // expected-error {{initializer element is not a compile-time constant}}
-
-void foo(void) {
-  _Accum x = 0.5k;
-  if (x == 0.5) {} // expected-error{{invalid operands to binary expression ('_Accum' and 'double')}}
-}
Index: clang/test/Frontend/fixed_point_conversions_const.c
===
--- clang/test/Frontend/fixed_point_conversions_const.c
+++ clang/test/Frontend/fixed_point_conversions_const.c
@@ -43,6 +43,37 @@
 short _Accum sa_const7 = -256;
 // CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
 
+// Fixed point to floating point
+float fl_const = 1.0hk;
+// CHECK-DAG: @fl_const = {{.*}}global float 1.00e+00, align 4
+float fl_const2 = -128.0k;
+// CHECK-DAG: @fl_const2 = {{.*}}global float -1.28e+02, align 4
+float fl_const3 = 0.0872802734375k;
+// CHECK-DAG: @fl_const3 = {{.*}}global float 0x3FB65800, align 4
+float fl_const4 = 192.5k;
+// CHECK-DAG: @fl_const4 = {{.*}}global float 1.925000e+02, align 4
+float fl_const5 = -192.5k;
+// CHECK-DAG: @fl_const5 = {{.*}}global float -1.925000e+02, align 4
+
+// Floating point to fixed point
+_Accum a_fl_const = 1.0f;
+// CHECK-DAG: @a_fl_const = {{.*}}global i32 32768, align 4
+_Accum a_fl_const2 = -128.0f;
+// CHECK-DAG: @a_fl_const2 = {{.*}}global i32 -4194304, align 4
+_Accum a_fl_const3 = 0.0872802734375f;
+// CHECK-DAG: @a_fl_const3 = {{.*}}global i32 2860, align 4
+_Accum a_fl_const4 = 0.0872802734375;
+// CHECK-DAG: @a_fl_const4 = {{.*}}global i32 2860, align 4
+_Accum a_fl_const5 = -0.0872802734375f;
+// CHECK-DAG: @a_fl_const5 = {{.*}}global i32 -2860, align 4
+_Fract f_fl_const = 0.5f;
+// CHECK-DAG: @f_fl_const = {{.*}}global i16 16384, align 2
+_Fract f_fl_const2 = -0.75;
+// CHECK-DAG: @f_fl_const2 = {{.*}}global i16 -24576, align 2
+unsigned short _Accum usa_fl_const = 48.75f;
+// SIGNED-DAG: @usa_fl_const = {{.*}}global i16 12480, align 2
+// UNSIGNED-DAG: @usa_fl_const = {{.*}}global i16 6240, align 2
+
 // Signedness
 unsigned short _Accum usa_const2 = 2.5hk;
 // SIGNED-DAG: @usa_const2  = {{.*}}global i16 640, align 2
Index: 

[PATCH] D88648: Refactor fixed point conversion test.

2020-10-09 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9c26eb8b915e: Refactor fixed point conversion test. 
(authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88648/new/

https://reviews.llvm.org/D88648

Files:
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_const.c

Index: clang/test/Frontend/fixed_point_conversions_const.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_const.c
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+// Between different fixed point types
+short _Accum sa_const = 2.5hk;
+// CHECK-DAG: @sa_const  = {{.*}}global i16 320, align 2
+_Accum a_const = 2.5hk;
+// CHECK-DAG: @a_const   = {{.*}}global i32 81920, align 4
+short _Accum sa_const2 = 2.5k;
+// CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
+
+short _Accum sa_from_f_const = 0.5r;
+// CHECK-DAG: sa_from_f_const = {{.*}}global i16 64, align 2
+_Fract f_from_sa_const = 0.5hk;
+// CHECK-DAG: f_from_sa_const = {{.*}}global i16 16384, align 2
+
+unsigned short _Accum usa_const = 2.5uk;
+unsigned _Accum ua_const = 2.5uhk;
+// SIGNED-DAG: @usa_const  = {{.*}}global i16 640, align 2
+// SIGNED-DAG: @ua_const   = {{.*}}global i32 163840, align 4
+// UNSIGNED-DAG:@usa_const  = {{.*}}global i16 320, align 2
+// UNSIGNED-DAG:@ua_const   = {{.*}}global i32 81920, align 4
+
+// FixedPoint to integer
+int i_const = -128.0hk;
+// CHECK-DAG: @i_const  = {{.*}}global i32 -128, align 4
+int i_const2 = 128.0hk;
+// CHECK-DAG: @i_const2 = {{.*}}global i32 128, align 4
+int i_const3 = -128.0k;
+// CHECK-DAG: @i_const3 = {{.*}}global i32 -128, align 4
+int i_const4 = 128.0k;
+// CHECK-DAG: @i_const4 = {{.*}}global i32 128, align 4
+short s_const = -128.0k;
+// CHECK-DAG: @s_const  = {{.*}}global i16 -128, align 2
+short s_const2 = 128.0k;
+// CHECK-DAG: @s_const2 = {{.*}}global i16 128, align 2
+
+// Integer to fixed point
+short _Accum sa_const5 = 2;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 256, align 2
+short _Accum sa_const6 = -2;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -256, align 2
+short _Accum sa_const7 = -256;
+// CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
+
+// Signedness
+unsigned short _Accum usa_const2 = 2.5hk;
+// SIGNED-DAG: @usa_const2  = {{.*}}global i16 640, align 2
+// UNSIGNED-DAG:@usa_const2  = {{.*}}global i16 320, align 2
+short _Accum sa_const3 = 2.5hk;
+// CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
+
+int i_const5 = 128.0uhk;
+unsigned int ui_const = 128.0hk;
+// CHECK-DAG: @i_const5  = {{.*}}global i32 128, align 4
+// CHECK-DAG: @ui_const  = {{.*}}global i32 128, align 4
+
+short _Accum sa_const9 = 2u;
+// CHECK-DAG: @sa_const9 = {{.*}}global i16 256, align 2
+unsigned short _Accum usa_const3 = 2;
+// SIGNED-DAG: @usa_const3 = {{.*}}global i16 512, align 2
+// UNSIGNED-DAG:@usa_const3 = {{.*}}global i16 256, align 2
+
+// Overflow (this is undefined but allowed)
+short _Accum sa_const4 = 256.0k;
+unsigned int ui_const2 = -2.5hk;
+short _Accum sa_const8 = 256;
+unsigned short _Accum usa_const4 = -2;
+
+// Saturation
+_Sat short _Accum sat_sa_const = 2.5hk;
+// CHECK-DAG: @sat_sa_const  = {{.*}}global i16 320, align 2
+_Sat short _Accum sat_sa_const2 = 256.0k;
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = -1.0hk;
+// CHECK-DAG: @sat_usa_const = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const2 = 256.0k;
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG:@sat_usa_const2 = {{.*}}global i16 32767, align 2
+
+_Sat short _Accum sat_sa_const3 = 256;
+// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const4 = -257;
+// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
+_Sat unsigned short _Accum sat_usa_const3 = -1;
+// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const4 = 256;
+// SIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG:@sat_usa_const4 = {{.*}}global i16 32767, align 2
Index: clang/test/Frontend/fixed_point_conversions.c
===
--- clang/test/Frontend/fixed_point_conversions.c
+++ clang/test/Frontend/fixed_point_conversions.c
@@ -1,485 +1,697 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu 

[PATCH] D88648: Refactor fixed point conversion test.

2020-10-01 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
Herald added subscribers: cfe-commits, bjope.
Herald added a project: clang.
ebevhan requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88648

Files:
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_const.c

Index: clang/test/Frontend/fixed_point_conversions_const.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_const.c
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+// Between different fixed point types
+short _Accum sa_const = 2.5hk;
+// CHECK-DAG: @sa_const  = {{.*}}global i16 320, align 2
+_Accum a_const = 2.5hk;
+// CHECK-DAG: @a_const   = {{.*}}global i32 81920, align 4
+short _Accum sa_const2 = 2.5k;
+// CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
+
+short _Accum sa_from_f_const = 0.5r;
+// CHECK-DAG: sa_from_f_const = {{.*}}global i16 64, align 2
+_Fract f_from_sa_const = 0.5hk;
+// CHECK-DAG: f_from_sa_const = {{.*}}global i16 16384, align 2
+
+unsigned short _Accum usa_const = 2.5uk;
+unsigned _Accum ua_const = 2.5uhk;
+// SIGNED-DAG: @usa_const  = {{.*}}global i16 640, align 2
+// SIGNED-DAG: @ua_const   = {{.*}}global i32 163840, align 4
+// UNSIGNED-DAG:@usa_const  = {{.*}}global i16 320, align 2
+// UNSIGNED-DAG:@ua_const   = {{.*}}global i32 81920, align 4
+
+// FixedPoint to integer
+int i_const = -128.0hk;
+// CHECK-DAG: @i_const  = {{.*}}global i32 -128, align 4
+int i_const2 = 128.0hk;
+// CHECK-DAG: @i_const2 = {{.*}}global i32 128, align 4
+int i_const3 = -128.0k;
+// CHECK-DAG: @i_const3 = {{.*}}global i32 -128, align 4
+int i_const4 = 128.0k;
+// CHECK-DAG: @i_const4 = {{.*}}global i32 128, align 4
+short s_const = -128.0k;
+// CHECK-DAG: @s_const  = {{.*}}global i16 -128, align 2
+short s_const2 = 128.0k;
+// CHECK-DAG: @s_const2 = {{.*}}global i16 128, align 2
+
+// Integer to fixed point
+short _Accum sa_const5 = 2;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 256, align 2
+short _Accum sa_const6 = -2;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -256, align 2
+short _Accum sa_const7 = -256;
+// CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
+
+// Signedness
+unsigned short _Accum usa_const2 = 2.5hk;
+// SIGNED-DAG: @usa_const2  = {{.*}}global i16 640, align 2
+// UNSIGNED-DAG:@usa_const2  = {{.*}}global i16 320, align 2
+short _Accum sa_const3 = 2.5hk;
+// CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
+
+int i_const5 = 128.0uhk;
+unsigned int ui_const = 128.0hk;
+// CHECK-DAG: @i_const5  = {{.*}}global i32 128, align 4
+// CHECK-DAG: @ui_const  = {{.*}}global i32 128, align 4
+
+short _Accum sa_const9 = 2u;
+// CHECK-DAG: @sa_const9 = {{.*}}global i16 256, align 2
+unsigned short _Accum usa_const3 = 2;
+// SIGNED-DAG: @usa_const3 = {{.*}}global i16 512, align 2
+// UNSIGNED-DAG:@usa_const3 = {{.*}}global i16 256, align 2
+
+// Overflow (this is undefined but allowed)
+short _Accum sa_const4 = 256.0k;
+unsigned int ui_const2 = -2.5hk;
+short _Accum sa_const8 = 256;
+unsigned short _Accum usa_const4 = -2;
+
+// Saturation
+_Sat short _Accum sat_sa_const = 2.5hk;
+// CHECK-DAG: @sat_sa_const  = {{.*}}global i16 320, align 2
+_Sat short _Accum sat_sa_const2 = 256.0k;
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = -1.0hk;
+// CHECK-DAG: @sat_usa_const = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const2 = 256.0k;
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG:@sat_usa_const2 = {{.*}}global i16 32767, align 2
+
+_Sat short _Accum sat_sa_const3 = 256;
+// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const4 = -257;
+// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
+_Sat unsigned short _Accum sat_usa_const3 = -1;
+// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const4 = 256;
+// SIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG:@sat_usa_const4 = {{.*}}global i16 32767, align 2
Index: clang/test/Frontend/fixed_point_conversions.c
===
--- clang/test/Frontend/fixed_point_conversions.c
+++ clang/test/Frontend/fixed_point_conversions.c
@@ -1,485 +1,697 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - 

[PATCH] D88174: [Sema] Address-space sensitive check for unbounded arrays (v2)

2020-09-29 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan accepted this revision.
ebevhan added a comment.
This revision is now accepted and ready to land.

LGTM, but @aaron.ballman should probably give his two cents as well for 
completion's sake.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88174/new/

https://reviews.llvm.org/D88174

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


[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-21 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Ping. Any further comments?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

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


[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-11 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 291211.
ebevhan added a comment.

Fix typo.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_half.c
  llvm/include/llvm/IR/FixedPointBuilder.h

Index: llvm/include/llvm/IR/FixedPointBuilder.h
===
--- llvm/include/llvm/IR/FixedPointBuilder.h
+++ llvm/include/llvm/IR/FixedPointBuilder.h
@@ -120,6 +120,16 @@
 C.isSigned(), C.isSaturated(), BothPadded);
   }
 
+  /// Given a floating point type and a fixed-point semantic, return a floating
+  /// point type which can accommodate the fixed-point semantic. This is either
+  /// \p Ty, or a floating point type with a larger exponent than Ty.
+  Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics ) {
+const fltSemantics *FloatSema = >getFltSemantics();
+while (!Sema.fitsInFloatSemantics(*FloatSema))
+  FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
+return Type::getFloatingPointTy(Ty->getContext(), *FloatSema);
+  }
+
 public:
   FixedPointBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -159,6 +169,55 @@
DstSema, false);
   }
 
+  Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics ,
+   Type *DstTy) {
+Value *Result;
+Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
+// Convert the raw fixed-point value directly to floating point. If the
+// value is too large to fit, it will be rounded, not truncated.
+Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
+: B.CreateUIToFP(Src, OpTy);
+// Rescale the integral-in-floating point by the scaling factor. This is
+// lossless, except for overflow to infinity which is unlikely.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale(;
+if (OpTy != DstTy)
+  Result = B.CreateFPTrunc(Result, DstTy);
+return Result;
+  }
+
+  Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics ) {
+bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+Value *Result = Src;
+Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
+if (OpTy != Src->getType())
+  Result = B.CreateFPExt(Result, OpTy);
+// Rescale the floating point value so that its significant bits (for the
+// purposes of the conversion) are in the integral range.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, DstSema.getScale(;
+
+Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+if (DstSema.isSaturated()) {
+  Intrinsic::ID IID =
+  UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+  Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
+} else {
+  Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+}
+
+// When saturating unsigned-with-padding using signed operations, we may
+// get negative values. Emit an extra clamp to zero.
+if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+  Constant *Zero = Constant::getNullValue(Result->getType());
+  Result =
+  B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+}
+
+return Result;
+  }
+
   /// Add two fixed-point values and return the result in their common semantic.
   /// \p LHS - The left hand side
   /// \p LHSSema - The semantic of the left hand side
Index: clang/test/Frontend/fixed_point_conversions_half.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_half.c
@@ -0,0 +1,309 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Fract sf;
+long _Fract lf;
+
+short _Accum sa;
+long _Accum la;
+
+unsigned short _Accum usa;
+unsigned long _Accum ula;
+
+_Sat short _Fract sf_sat;
+_Sat long _Fract lf_sat;
+
+_Sat short _Accum sa_sat;
+_Sat long _Accum la_sat;
+
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned long _Accum ula_sat;
+
+_Float16 h;
+
+
+// CHECK-LABEL: @half_fix1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load half, half* @h, align 2
+// CHECK-NEXT:[[TMP1:%.*]] = fmul half [[TMP0]], 0xH5800
+// CHECK-NEXT:[[TMP2:%.*]] = fptosi half [[TMP1]] to i8
+// CHECK-NEXT:store i8 

[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-11 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: llvm/include/llvm/IR/FixedPointBuilder.h:126
+  /// \p Ty, or a floating point type with a larger exponent than Ty.
+  Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics ) {
+const fltSemantics *FloatSema = >getFltSemantics();

rjmccall wrote:
> I like this method name.  Does this have the same problem as I asked about in 
> the other patch about really needing to be about whether the *unscaled* 
> fixed-point type fits in the given type?
It should be the same case here, yes. Both the integral range and the scale 
matter when determining this.



Comment at: llvm/include/llvm/IR/FixedPointBuilder.h:131
+// There's seemingly no way to convert fltSemantics to Type.
+return ConstantFP::get(Ty->getContext(), APFloat(*FloatSema))->getType();
+  }

rjmccall wrote:
> Could you just extract that code out of `llvm::ConstantFP::get` and put it on 
> `llvm::Type`?  Might be better as a separate patch.
> 
> While you're at it, there's also a `TypeToFloatSemantics` function in 
> Constants.cpp that's completely redundant with `llvm::Type::getFltSemantics`.
Done in D87512.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

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


[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-11 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 291203.
ebevhan added a comment.

Using Type::getFloatingPointTy now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_half.c
  llvm/include/llvm/IR/FixedPointBuilder.h

Index: llvm/include/llvm/IR/FixedPointBuilder.h
===
--- llvm/include/llvm/IR/FixedPointBuilder.h
+++ llvm/include/llvm/IR/FixedPointBuilder.h
@@ -120,6 +120,16 @@
 C.isSigned(), C.isSaturated(), BothPadded);
   }
 
+  /// Given a floating point type and a fixed-point semantic, return a floating
+  /// point type which can accommodate the fixed-point semantic. This is either
+  /// \p Ty, or a floating point type with a larger exponent than Ty.
+  Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics ) {
+const fltSemantics *FloatSema = >getFltSemantics();
+while (!Sema.fitsInFloatSemantics(*FloatSema))
+  FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
+return Type::getFloatingPointTy(Ty->getContext(), *FloatSema);
+  }
+
 public:
   FixedPointBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -159,6 +169,55 @@
DstSema, false);
   }
 
+  Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics ,
+   Type *DstTy) {
+Value *Result;
+Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
+// Convert the raw fixed-point value directly to floating point. If the
+// value is too large to fit, it will be rounded, not truncated.
+Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
+: B.CreateUIToFP(Src, OpTy);
+// Rescale the integral-in-floating point by the scaling factor. This is
+// lossless, except for overflow to infinity which is unlikely.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale(;
+if (OpTy != DstTy)
+  Result = B.CreateFPTrunc(Result, DstTy);
+return Result;
+  }
+
+  Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics ) {
+bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+Value *Result = Src;
+Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
+if (OpTy != Src->getType())
+  Result = B.CreateFPExt(Result, OpTy);
+// Rescale the floating point value so that its significant bits (for the
+// purposes of the conversion) are in the integral range.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, DstSema.getScale(;
+
+Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+if (DstSema.isSaturated()) {
+  Intrinsic::ID IID =
+  UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+  Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
+} else {
+  Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+}
+
+// When saturating unsigned-with-padding using signed operations, we may
+// get negative values. Emit an extra clamp to zero.
+if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+  Constant *Zero = Constant::getNullValue(Result->getType());
+  Result =
+  B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+}
+
+return Result;
+  }
+
   /// Add two fixed-point values and return the result in their common semantic.
   /// \p LHS - The left hand side
   /// \p LHSSema - The semantic of the left hand side
Index: clang/test/Frontend/fixed_point_conversions_half.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_half.c
@@ -0,0 +1,309 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Fract sf;
+long _Fract lf;
+
+short _Accum sa;
+long _Accum la;
+
+unsigned short _Accum usa;
+unsigned long _Accum ula;
+
+_Sat short _Fract sf_sat;
+_Sat long _Fract lf_sat;
+
+_Sat short _Accum sa_sat;
+_Sat long _Accum la_sat;
+
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned long _Accum ula_sat;
+
+_Float16 h;
+
+
+// CHECK-LABEL: @half_fix1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load half, half* @h, align 2
+// CHECK-NEXT:[[TMP1:%.*]] = fmul half [[TMP0]], 0xH5800
+// CHECK-NEXT:[[TMP2:%.*]] = fptosi half [[TMP1]] to i8
+// 

[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-08 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 290502.
ebevhan added a comment.

Updated method name.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_half.c
  llvm/include/llvm/IR/FixedPointBuilder.h

Index: llvm/include/llvm/IR/FixedPointBuilder.h
===
--- llvm/include/llvm/IR/FixedPointBuilder.h
+++ llvm/include/llvm/IR/FixedPointBuilder.h
@@ -120,6 +120,17 @@
 C.isSigned(), C.isSaturated(), BothPadded);
   }
 
+  /// Given a floating point type and a fixed-point semantic, return a floating
+  /// point type which can accommodate the fixed-point semantic. This is either
+  /// \p Ty, or a floating point type with a larger exponent than Ty.
+  Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics ) {
+const fltSemantics *FloatSema = >getFltSemantics();
+while (!Sema.fitsInFloatSemantics(*FloatSema))
+  FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
+// There's seemingly no way to convert fltSemantics to Type.
+return ConstantFP::get(Ty->getContext(), APFloat(*FloatSema))->getType();
+  }
+
 public:
   FixedPointBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -159,6 +170,55 @@
DstSema, false);
   }
 
+  Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics ,
+   Type *DstTy) {
+Value *Result;
+Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
+// Convert the raw fixed-point value directly to floating point. If the
+// value is too large to fit, it will be rounded, not truncated.
+Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
+: B.CreateUIToFP(Src, OpTy);
+// Rescale the integral-in-floating point by the scaling factor. This is
+// lossless, except for overflow to infinity which is unlikely.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale(;
+if (OpTy != DstTy)
+  Result = B.CreateFPTrunc(Result, DstTy);
+return Result;
+  }
+
+  Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics ) {
+bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+Value *Result = Src;
+Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
+if (OpTy != Src->getType())
+  Result = B.CreateFPExt(Result, OpTy);
+// Rescale the floating point value so that its significant bits (for the
+// purposes of the conversion) are in the integral range.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, DstSema.getScale(;
+
+Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+if (DstSema.isSaturated()) {
+  Intrinsic::ID IID =
+  UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+  Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
+} else {
+  Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+}
+
+// When saturating unsigned-with-padding using signed operations, we may
+// get negative values. Emit an extra clamp to zero.
+if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+  Constant *Zero = Constant::getNullValue(Result->getType());
+  Result =
+  B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+}
+
+return Result;
+  }
+
   /// Add two fixed-point values and return the result in their common semantic.
   /// \p LHS - The left hand side
   /// \p LHSSema - The semantic of the left hand side
Index: clang/test/Frontend/fixed_point_conversions_half.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_half.c
@@ -0,0 +1,309 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Fract sf;
+long _Fract lf;
+
+short _Accum sa;
+long _Accum la;
+
+unsigned short _Accum usa;
+unsigned long _Accum ula;
+
+_Sat short _Fract sf_sat;
+_Sat long _Fract lf_sat;
+
+_Sat short _Accum sa_sat;
+_Sat long _Accum la_sat;
+
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned long _Accum ula_sat;
+
+_Float16 h;
+
+
+// CHECK-LABEL: @half_fix1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load half, half* @h, align 2
+// CHECK-NEXT:[[TMP1:%.*]] = fmul half [[TMP0]], 0xH5800
+// 

[PATCH] D86631: [Fixed Point] Add fixed-point to floating point cast types and consteval.

2020-09-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 290266.
ebevhan added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86631/new/

https://reviews.llvm.org/D86631

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

Index: clang/test/Frontend/fixed_point_unknown_conversions.c
===
--- clang/test/Frontend/fixed_point_unknown_conversions.c
+++ clang/test/Frontend/fixed_point_unknown_conversions.c
@@ -22,16 +22,12 @@
   _Fract fract = accum; // ok
   _Accum *accum_ptr;
 
-  accum = f;   // expected-error{{conversion between fixed point and 'float' is not yet supported}}
-  accum = d;   // expected-error{{conversion between fixed point and 'double' is not yet supported}}
   accum = dc;  // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
   accum = ic;  // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
   accum = s;   // expected-error{{assigning to '_Accum' from incompatible type 'struct S'}}
   accum = ptr; // expected-error{{assigning to '_Accum' from incompatible type 'int *'}}
   accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}}
 
-  f = accum;   // expected-error{{conversion between fixed point and 'float' is not yet supported}}
-  d = accum;   // expected-error{{conversion between fixed point and 'double' is not yet supported}}
   dc = accum;  // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
   ic = accum;  // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
   s = accum;   // expected-error{{assigning to 'struct S' from incompatible type '_Accum'}}
Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -286,8 +286,3 @@
 
 // Division by zero
 short _Accum div_zero = 4.5k / 0.0lr;  // expected-error {{initializer element is not a compile-time constant}}
-
-void foo(void) {
-  _Accum x = 0.5k;
-  if (x == 0.5) {} // expected-error{{invalid operands to binary expression ('_Accum' and 'double')}}
-}
Index: clang/test/Frontend/fixed_point_conversions_const.c
===
--- clang/test/Frontend/fixed_point_conversions_const.c
+++ clang/test/Frontend/fixed_point_conversions_const.c
@@ -43,6 +43,37 @@
 short _Accum sa_const7 = -256;
 // CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
 
+// Fixed point to floating point
+float fl_const = 1.0hk;
+// CHECK-DAG: @fl_const = {{.*}}global float 1.00e+00, align 4
+float fl_const2 = -128.0k;
+// CHECK-DAG: @fl_const2 = {{.*}}global float -1.28e+02, align 4
+float fl_const3 = 0.0872802734375k;
+// CHECK-DAG: @fl_const3 = {{.*}}global float 0x3FB65800, align 4
+float fl_const4 = 192.5k;
+// CHECK-DAG: @fl_const4 = {{.*}}global float 1.925000e+02, align 4
+float fl_const5 = -192.5k;
+// CHECK-DAG: @fl_const5 = {{.*}}global float -1.925000e+02, align 4
+
+// Floating point to fixed point
+_Accum a_fl_const = 1.0f;
+// CHECK-DAG: @a_fl_const = {{.*}}global i32 32768, align 4
+_Accum a_fl_const2 = -128.0f;
+// CHECK-DAG: @a_fl_const2 = {{.*}}global i32 -4194304, align 4
+_Accum a_fl_const3 = 0.0872802734375f;
+// CHECK-DAG: @a_fl_const3 = {{.*}}global i32 2860, align 4
+_Accum a_fl_const4 = 0.0872802734375;
+// CHECK-DAG: @a_fl_const4 = {{.*}}global i32 2860, align 4
+_Accum a_fl_const5 = -0.0872802734375f;
+// CHECK-DAG: @a_fl_const5 = {{.*}}global i32 -2860, align 4
+_Fract f_fl_const = 0.5f;
+// CHECK-DAG: @f_fl_const = {{.*}}global i16 16384, align 2
+_Fract f_fl_const2 = -0.75;
+// CHECK-DAG: @f_fl_const2 = {{.*}}global i16 -24576, align 2
+unsigned short _Accum usa_fl_const = 48.75f;
+// SIGNED-DAG: @usa_fl_const = {{.*}}global i16 12480, align 2
+// UNSIGNED-DAG: @usa_fl_const = {{.*}}global i16 6240, align 2
+
 // Signedness
 unsigned short _Accum usa_const2 = 2.5hk;
 // SIGNED-DAG: @usa_const2  = {{.*}}global i16 640, align 2
Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ 

[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 290267.
ebevhan added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_half.c
  llvm/include/llvm/IR/FixedPointBuilder.h

Index: llvm/include/llvm/IR/FixedPointBuilder.h
===
--- llvm/include/llvm/IR/FixedPointBuilder.h
+++ llvm/include/llvm/IR/FixedPointBuilder.h
@@ -120,6 +120,17 @@
 C.isSigned(), C.isSaturated(), BothPadded);
   }
 
+  /// Given a floating point type and a fixed-point semantic, return a floating
+  /// point type which can accommodate the fixed-point semantic. This is either
+  /// \p Ty, or a floating point type with a larger exponent than Ty.
+  Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics ) {
+const fltSemantics *FloatSema = >getFltSemantics();
+while (!Sema.canAccommodateFloatSemantics(*FloatSema))
+  FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
+// There's seemingly no way to convert fltSemantics to Type.
+return ConstantFP::get(Ty->getContext(), APFloat(*FloatSema))->getType();
+  }
+
 public:
   FixedPointBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -159,6 +170,55 @@
DstSema, false);
   }
 
+  Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics ,
+   Type *DstTy) {
+Value *Result;
+Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
+// Convert the raw fixed-point value directly to floating point. If the
+// value is too large to fit, it will be rounded, not truncated.
+Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
+: B.CreateUIToFP(Src, OpTy);
+// Rescale the integral-in-floating point by the scaling factor. This is
+// lossless, except for overflow to infinity which is unlikely.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale(;
+if (OpTy != DstTy)
+  Result = B.CreateFPTrunc(Result, DstTy);
+return Result;
+  }
+
+  Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics ) {
+bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+Value *Result = Src;
+Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
+if (OpTy != Src->getType())
+  Result = B.CreateFPExt(Result, OpTy);
+// Rescale the floating point value so that its significant bits (for the
+// purposes of the conversion) are in the integral range.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, DstSema.getScale(;
+
+Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+if (DstSema.isSaturated()) {
+  Intrinsic::ID IID =
+  UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+  Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
+} else {
+  Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+}
+
+// When saturating unsigned-with-padding using signed operations, we may
+// get negative values. Emit an extra clamp to zero.
+if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+  Constant *Zero = Constant::getNullValue(Result->getType());
+  Result =
+  B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+}
+
+return Result;
+  }
+
   /// Add two fixed-point values and return the result in their common semantic.
   /// \p LHS - The left hand side
   /// \p LHSSema - The semantic of the left hand side
Index: clang/test/Frontend/fixed_point_conversions_half.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_half.c
@@ -0,0 +1,309 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Fract sf;
+long _Fract lf;
+
+short _Accum sa;
+long _Accum la;
+
+unsigned short _Accum usa;
+unsigned long _Accum ula;
+
+_Sat short _Fract sf_sat;
+_Sat long _Fract lf_sat;
+
+_Sat short _Accum sa_sat;
+_Sat long _Accum la_sat;
+
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned long _Accum ula_sat;
+
+_Float16 h;
+
+
+// CHECK-LABEL: @half_fix1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load half, half* @h, align 2
+// CHECK-NEXT:[[TMP1:%.*]] = fmul half [[TMP0]], 0xH5800
+// 

[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-09-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 290245.
ebevhan added a comment.

Added promotion mechanism.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_conversions.c
  clang/test/Frontend/fixed_point_conversions_half.c
  llvm/include/llvm/IR/FixedPointBuilder.h

Index: llvm/include/llvm/IR/FixedPointBuilder.h
===
--- llvm/include/llvm/IR/FixedPointBuilder.h
+++ llvm/include/llvm/IR/FixedPointBuilder.h
@@ -120,6 +120,17 @@
 C.isSigned(), C.isSaturated(), BothPadded);
   }
 
+  /// Given a floating point type and a fixed-point semantic, return a floating
+  /// point type which can accommodate the fixed-point semantic. This is either
+  /// \p Ty, or a floating point type with a larger exponent than Ty.
+  Type *getAccommodatingFloatType(Type *Ty, const FixedPointSemantics ) {
+const fltSemantics *FloatSema = >getFltSemantics();
+while (!Sema.canAccommodateFloatSemantics(*FloatSema))
+  FloatSema = APFixedPoint::promoteFloatSemantics(FloatSema);
+// There's seemingly no way to convert fltSemantics to Type.
+return ConstantFP::get(Ty->getContext(), APFloat(*FloatSema))->getType();
+  }
+
 public:
   FixedPointBuilder(IRBuilderTy ) : B(Builder) {}
 
@@ -159,6 +170,55 @@
DstSema, false);
   }
 
+  Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics ,
+   Type *DstTy) {
+Value *Result;
+Type *OpTy = getAccommodatingFloatType(DstTy, SrcSema);
+// Convert the raw fixed-point value directly to floating point. If the
+// value is too large to fit, it will be rounded, not truncated.
+Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, OpTy)
+: B.CreateUIToFP(Src, OpTy);
+// Rescale the integral-in-floating point by the scaling factor. This is
+// lossless, except for overflow to infinity which is unlikely.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, -(int)SrcSema.getScale(;
+if (OpTy != DstTy)
+  Result = B.CreateFPTrunc(Result, DstTy);
+return Result;
+  }
+
+  Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics ) {
+bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+Value *Result = Src;
+Type *OpTy = getAccommodatingFloatType(Src->getType(), DstSema);
+if (OpTy != Src->getType())
+  Result = B.CreateFPExt(Result, OpTy);
+// Rescale the floating point value so that its significant bits (for the
+// purposes of the conversion) are in the integral range.
+Result = B.CreateFMul(Result,
+ConstantFP::get(OpTy, std::pow(2, DstSema.getScale(;
+
+Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+if (DstSema.isSaturated()) {
+  Intrinsic::ID IID =
+  UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+  Result = B.CreateIntrinsic(IID, {ResultTy, OpTy}, {Result});
+} else {
+  Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+}
+
+// When saturating unsigned-with-padding using signed operations, we may
+// get negative values. Emit an extra clamp to zero.
+if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+  Constant *Zero = Constant::getNullValue(Result->getType());
+  Result =
+  B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+}
+
+return Result;
+  }
+
   /// Add two fixed-point values and return the result in their common semantic.
   /// \p LHS - The left hand side
   /// \p LHSSema - The semantic of the left hand side
Index: clang/test/Frontend/fixed_point_conversions_half.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_conversions_half.c
@@ -0,0 +1,309 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple arm64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Fract sf;
+long _Fract lf;
+
+short _Accum sa;
+long _Accum la;
+
+unsigned short _Accum usa;
+unsigned long _Accum ula;
+
+_Sat short _Fract sf_sat;
+_Sat long _Fract lf_sat;
+
+_Sat short _Accum sa_sat;
+_Sat long _Accum la_sat;
+
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned long _Accum ula_sat;
+
+_Float16 h;
+
+
+// CHECK-LABEL: @half_fix1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load half, half* @h, align 2
+// CHECK-NEXT:[[TMP1:%.*]] = fmul half [[TMP0]], 

[PATCH] D86796: [Sema] Address-space sensitive index check for unbounded arrays

2020-09-04 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:13981
+bool overflow;
+llvm::APInt product(index);
+product += 1;

ebevhan wrote:
> chrish_ericsson_atx wrote:
> > ebevhan wrote:
> > > What if index is wider than AddrBits, but the active bits are fewer? Then 
> > > you might miss out on triggering the overflow case in the multiplication.
> > Line 13984 checks for active bits of product being less than AddrBits, 
> > which is the same case (since product, by definition, has same width as 
> > index).  So I think this is covered.  If I've misunderstood, please re-ping.
> The overflow limit for _ovf is determined by the width of the APInt. If index 
> is 32 bits wide but only has 14 bits active, and AddrBits is 16, then an 
> umul_ovf might overflow past 16 bits but not for 32 bits since the product is 
> the same width as the index. Then we won't detect the overflow.
Scratch this; I missed the second getActiveBits check. With that it should be 
fine.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86796/new/

https://reviews.llvm.org/D86796

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


[PATCH] D86796: [Sema] Address-space sensitive index check for unbounded arrays

2020-09-04 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:14063
+  if (isUnboundedArray) {
+if (index.isUnsigned() || !index.isNegative()) {
+  const auto  = getASTContext();

This could be early return to avoid the indentation.



Comment at: clang/lib/Sema/SemaChecking.cpp:13981
+bool overflow;
+llvm::APInt product(index);
+product += 1;

chrish_ericsson_atx wrote:
> ebevhan wrote:
> > What if index is wider than AddrBits, but the active bits are fewer? Then 
> > you might miss out on triggering the overflow case in the multiplication.
> Line 13984 checks for active bits of product being less than AddrBits, which 
> is the same case (since product, by definition, has same width as index).  So 
> I think this is covered.  If I've misunderstood, please re-ping.
The overflow limit for _ovf is determined by the width of the APInt. If index 
is 32 bits wide but only has 14 bits active, and AddrBits is 16, then an 
umul_ovf might overflow past 16 bits but not for 32 bits since the product is 
the same width as the index. Then we won't detect the overflow.



Comment at: clang/lib/Sema/SemaChecking.cpp:13993
+  MaxElems.zext(std::max(AddrBits << 1, apElemBytes.getBitWidth()));
+  MaxElems += 1;
+  if (MaxElems.getBitWidth() < apElemBytes.getBitWidth())

chrish_ericsson_atx wrote:
> ebevhan wrote:
> > Though, why is the +1 here? Isn't this already the maximum number of 
> > elements?
> Initial value of MaxElems is APInt::getMaxValue(AddrBits), which is the index 
> of the last addressable CharUnit in the address space.  Adding 1 makes it the 
> total number of addressable CharUnits in the address space, which is what we 
> want as the numerator for computing total number of elements of a given size 
> that will fit in that address space.
> 
Ah, yes. Got indexes and sizes mixed up again.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86796/new/

https://reviews.llvm.org/D86796

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


[PATCH] D86796: [Sema] Address-space sensitive index check for unbounded arrays

2020-09-03 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:13981
+bool overflow;
+llvm::APInt product(index);
+product += 1;

What if index is wider than AddrBits, but the active bits are fewer? Then you 
might miss out on triggering the overflow case in the multiplication.



Comment at: clang/lib/Sema/SemaChecking.cpp:13992
+  MaxElems =
+  MaxElems.zext(std::max(AddrBits << 1, apElemBytes.getBitWidth()));
+  MaxElems += 1;

Should this not be AddrBits + 1 if you want to add 1 below?



Comment at: clang/lib/Sema/SemaChecking.cpp:13993
+  MaxElems.zext(std::max(AddrBits << 1, apElemBytes.getBitWidth()));
+  MaxElems += 1;
+  if (MaxElems.getBitWidth() < apElemBytes.getBitWidth())

Though, why is the +1 here? Isn't this already the maximum number of elements?



Comment at: clang/lib/Sema/SemaChecking.cpp:13994-13997
+  if (MaxElems.getBitWidth() < apElemBytes.getBitWidth())
+MaxElems = MaxElems.zext(apElemBytes.getBitWidth());
+  else if (apElemBytes.getBitWidth() < MaxElems.getBitWidth())
+apElemBytes = apElemBytes.zext(MaxElems.getBitWidth());

MaxElems should already be at a sufficient width here because of the earlier 
max. You can probably just do apElemBytes = 
apElemBytes.zextOrTrunc(MaxElems.getBitWidth())?



Comment at: clang/lib/Sema/SemaChecking.cpp:13966
   if (index.isUnsigned() || !index.isNegative()) {
-// It is possible that the type of the base expression after
-// IgnoreParenCasts is incomplete, even though the type of the base
-// expression before IgnoreParenCasts is complete (see PR39746 for an
-// example). In this case we have no information about whether the array
-// access exceeds the array bounds. However we can still diagnose an array
-// access which precedes the array bounds.
-if (BaseType->isIncompleteType())
-  return;
+if (isUnboundedArray) {
+  const auto  = getASTContext();

chrish_ericsson_atx wrote:
> ebevhan wrote:
> > It might simplify the patch to move this condition out of the tree and just 
> > early return for the other case. That is:
> > 
> > ```
> > if (isUnboundedArray) {
> >   if (!(index.isUnsigned() || !index.isNegative()))
> > return;
> > 
> >   ...
> >   return;
> > }
> > 
> > if (index.isUnsigned() ...
> > ```
> There's a bit more code (starting at line 14094 in this patch set) that 
> applies in all cases, so an early return here would prevent the "Array 
> declared here" note from being generated.
Ah, the note.

I wonder if it wouldn't be cleaner (and avoid indenting the entire block) if 
that was just duplicated.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86796/new/

https://reviews.llvm.org/D86796

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


[PATCH] D62574: Add support for target-configurable address spaces.

2020-09-02 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:10963
+bool
+ASTContext::isExplicitAddrSpaceConversionLegal(LangAS From, LangAS To) const {
+  // If From and To overlap, the cast is legal.

ebevhan wrote:
> Anastasia wrote:
> > Btw I assume that explicit cast can't reject what is not rejected by 
> > implicit cast?
> > 
> > I am not sure if we need to enforce or document this somehow considering 
> > that we provide full configurability now?
> It shouldn't do that, no. I don't think there's any way to guarantee this, 
> though.
> 
> I could add something to the target methods about it.
Wait, no. This is already guaranteed, because the method here in ASTContext 
will check for overlap first.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

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


[PATCH] D62574: Add support for target-configurable address spaces.

2020-09-01 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D62574#2242471 , @Anastasia wrote:

> The only thing is that it would be good to test the new target setting logic 
> somehow... do you have any ideas in mind? We could think of creating a dummy 
> target for that or adding a dummy setting in existing targets - maybe SPIR 
> could be a candidate. We have done something similar in the past if you look 
> at `FakeAddrSpaceMap` in `LangOpts`.

Perhaps we could add a configuration to AMDGPU? That has address spaces.

I'm not a big fan of adding an option just for testing.




Comment at: clang/include/clang/AST/ASTContext.h:2612
+
+  /// Returns true if an explicit cast from address space A to B is legal.
+  /// Explicit conversion between address spaces is permitted if the address

Anastasia wrote:
> Here we should say that this is an extension or enhancement of embedded C 
> rules that clang implements.
> 
> Technically for OpenCL we could refactor to use this functionality as we 
> don't support such explicit casts on disjoint address spaces. But then this 
> would not be necessarily a target setting.
I'm still a bit on the fence about what Embedded-C really stipulates. I don't 
think it's against the spec to simply disallow disjoint conversion altogether, 
but it's only necessary to keep Clang's current implementation working.



Comment at: clang/lib/AST/ASTContext.cpp:10959
+  // Otherwise, ask the target.
+  return Target->isAddressSpaceSupersetOf(A, B);
+}

Anastasia wrote:
> I guess we should add a similar check here as below?
> 
>  
> ```
> if (isTargetAddressSpace(From) || isTargetAddressSpace(To) ||
>   From == LangAS::Default || To == LangAS::Default)
> ```
Is it not useful for targets to be able to express relations of LangASes and 
target ASes?

The method below must be guarded because otherwise all casts between LangASes 
would be legal.



Comment at: clang/lib/AST/ASTContext.cpp:10963
+bool
+ASTContext::isExplicitAddrSpaceConversionLegal(LangAS From, LangAS To) const {
+  // If From and To overlap, the cast is legal.

Anastasia wrote:
> Btw I assume that explicit cast can't reject what is not rejected by implicit 
> cast?
> 
> I am not sure if we need to enforce or document this somehow considering that 
> we provide full configurability now?
It shouldn't do that, no. I don't think there's any way to guarantee this, 
though.

I could add something to the target methods about it.



Comment at: clang/lib/Sema/SemaCast.cpp:2423
   auto DestPointeeType = DestPtrType->getPointeeType();
-  if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType)) {
+  if (!Self.Context.isExplicitAddrSpaceConversionLegal(
+SrcPointeeType.getQualifiers(), DestPointeeType.getQualifiers())) {

Anastasia wrote:
> Btw just to point our that overlapping used to be a commutative operation so 
> you could swap arguments and still get the same answer but for 
> `isExplicitAddrSpaceConversionLegal` is not the same I assume?
Correct, isExplicitAddrSpaceConversionLegal doesn't have to be commutative.



Comment at: clang/lib/Sema/SemaOverload.cpp:3235
   //  - in non-top levels it is not a valid conversion.
+  // FIXME: This should probably be using isExplicitAddrSpaceConversionLegal,
+  // but we don't know if this is an implicit or explicit conversion.

Anastasia wrote:
> Sorry if this has been discussed previously, do you refer to the first or the 
> second case and is there any failing test case?
It refers to the first case of "valid to convert to addr space that is a 
superset in all cases". Technically, it could be permitted even if the addr 
space is not a superset, if this is an explicit cast. But we don't know that. 
We only know if it's a c-style cast, because those are always 'explicit'.

I don't have a test case, unfortunately. I just made this observation as I was 
redoing all of the overlap/superspace checks. It might not even be a problem.



Comment at: clang/lib/Sema/SemaOverload.cpp:5289
 
+  // FIXME: hasAddressSpace is wrong; this check will be skipped if FromType is
+  // not qualified with an address space, but if there's no implicit conversion

Anastasia wrote:
> Do you have a failing test case, if so feel free to create a bug?
Unsure how I'd make one. I suspect this can't be triggered in OpenCL++, because 
you can't really have LangAS::Default on FromType there, can you? It would 
always be some AS.

Doing it in another way would require a target that has configurable ASes, 
which doesn't exist yet. Also, it would require methods qualified with target 
ASes, and that doesn't work yet either.



Comment at: clang/test/CodeGenCXX/address-space-cast.cpp:41
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = addrspacecast i8* 

[PATCH] D86796: [Sema] Address-space sensitive index check for unbounded arrays

2020-09-01 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:13966
   if (index.isUnsigned() || !index.isNegative()) {
-// It is possible that the type of the base expression after
-// IgnoreParenCasts is incomplete, even though the type of the base
-// expression before IgnoreParenCasts is complete (see PR39746 for an
-// example). In this case we have no information about whether the array
-// access exceeds the array bounds. However we can still diagnose an array
-// access which precedes the array bounds.
-if (BaseType->isIncompleteType())
-  return;
+if (isUnboundedArray) {
+  const auto  = getASTContext();

It might simplify the patch to move this condition out of the tree and just 
early return for the other case. That is:

```
if (isUnboundedArray) {
  if (!(index.isUnsigned() || !index.isNegative()))
return;

  ...
  return;
}

if (index.isUnsigned() ...
```



Comment at: clang/lib/Sema/SemaChecking.cpp:13989
+  MaxElems <<= AddrBits;
+  MaxElems /= ElemBytes;
+

The size calculations here could probably be simplified by doing something like 
this:

* If getActiveBits of the index is greater than AddrBits, it's indexing outside
* Construct an AddrBits-wide APInt containing the index value
* Use umul_ovf with getTypeSizeInChars(ElementType); if that overflows, it's 
indexing outside



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86796/new/

https://reviews.llvm.org/D86796

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


[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-08-27 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: llvm/include/llvm/IR/FixedPointBuilder.h:171-172
+// lossless, except for overflow to infinity which is unlikely.
+return B.CreateFMul(Result,
+ConstantFP::get(DstTy, std::pow(2, -(int)SrcSema.getScale(;
+  }

leonardchan wrote:
> Was there a reason for preferring multiplying by the reciprocal instead of 
> dividing by a power of 2?
> 
> I think this was discussed before, but can't seem to remember/find the 
> conversation.
Multiplication should be more efficient than division with the same effect.

However, as @rjmccall mentioned in D54749, this rescaling might not work if the 
exponent is not large enough to fit the scaled value. This is unlikely for 
single precision float and larger formats, but it probably won't work for half 
precision.

I'm not entirely sure what to do about that. I was originally planning on 
adding an intrinsic that did pretty much the same thing as the one in that 
patch, but with a scaling factor. However, I figured that it would not be 
necessary when I noticed that an integer intrinsic was already in the works.

It feels odd to have intrinsics that do pretty much the same thing as another 
intrinsic but with an internal multiplication baked in. On top of that, it 
would require adding 4 new intrinsics (signed/unsigned, 
nonsaturating/saturating) which seems like a bit much.

Perhaps it may be necessary to emit something else when half precision is 
involved here...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86632/new/

https://reviews.llvm.org/D86632

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


[PATCH] D86632: [Fixed Point] Add codegen for conversion between fixed-point and floating point.

2020-08-26 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: leonardchan, rjmccall.
Herald added subscribers: llvm-commits, cfe-commits, bjope.
Herald added projects: clang, LLVM.
ebevhan requested review of this revision.

The patch adds the required methods to FixedPointBuilder
for converting between fixed-point and floating point,
and uses them from Clang.

This depends on D54749 .


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86632

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_conversions.c
  llvm/include/llvm/IR/FixedPointBuilder.h

Index: llvm/include/llvm/IR/FixedPointBuilder.h
===
--- llvm/include/llvm/IR/FixedPointBuilder.h
+++ llvm/include/llvm/IR/FixedPointBuilder.h
@@ -159,6 +159,48 @@
DstSema, false);
   }
 
+  Value *CreateFixedToFloating(Value *Src, const FixedPointSemantics ,
+   Type *DstTy) {
+Value *Result;
+// Convert the raw fixed-point value directly to floating point. If the
+// value is too large to fit, it will be rounded, not truncated.
+Result = SrcSema.isSigned() ? B.CreateSIToFP(Src, DstTy)
+: B.CreateUIToFP(Src, DstTy);
+// Rescale the integral-in-floating point by the scaling factor. This is
+// lossless, except for overflow to infinity which is unlikely.
+return B.CreateFMul(Result,
+ConstantFP::get(DstTy, std::pow(2, -(int)SrcSema.getScale(;
+  }
+
+  Value *CreateFloatingToFixed(Value *Src, const FixedPointSemantics ) {
+bool UseSigned = DstSema.isSigned() || DstSema.hasUnsignedPadding();
+Value *Result;
+// Rescale the floating point value so that its significant bits (for the
+// purposes of the conversion) are in the integral range.
+Result = B.CreateFMul(Src,
+ConstantFP::get(Src->getType(), std::pow(2, DstSema.getScale(;
+
+Type *ResultTy = B.getIntNTy(DstSema.getWidth());
+if (DstSema.isSaturated()) {
+  Intrinsic::ID IID =
+  UseSigned ? Intrinsic::fptosi_sat : Intrinsic::fptoui_sat;
+  Result = B.CreateIntrinsic(IID, {ResultTy, Src->getType()}, {Result});
+} else {
+  Result = UseSigned ? B.CreateFPToSI(Result, ResultTy)
+ : B.CreateFPToUI(Result, ResultTy);
+}
+
+// When saturating unsigned-with-padding using signed operations, we may
+// get negative values. Emit an extra clamp to zero.
+if (DstSema.isSaturated() && DstSema.hasUnsignedPadding()) {
+  Constant *Zero = Constant::getNullValue(Result->getType());
+  Result =
+  B.CreateSelect(B.CreateICmpSLT(Result, Zero), Zero, Result, "satmin");
+}
+
+return Result;
+  }
+
   /// Add two fixed-point values and return the result in their common semantic.
   /// \p LHS - The left hand side
   /// \p LHSSema - The semantic of the left hand side
Index: clang/test/Frontend/fixed_point_conversions.c
===
--- clang/test/Frontend/fixed_point_conversions.c
+++ clang/test/Frontend/fixed_point_conversions.c
@@ -26,11 +26,15 @@
 _Sat short _Fract sat_sf;
 _Sat _Fract sat_f;
 _Sat long _Fract sat_lf;
+_Sat unsigned _Fract sat_uf;
 
 short s;
 int i;
 unsigned int ui;
 
+float fl;
+double d;
+
 // CHECK-LABEL: @fix_same1(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:[[TMP0:%.*]] = load i32, i32* @a, align 4
@@ -695,3 +699,298 @@
 void int_sat4() {
   sat_usa = ui;
 }
+
+
+// CHECK-LABEL: @float_fix1(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* @fl, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = fmul float [[TMP0]], 1.28e+02
+// CHECK-NEXT:[[TMP2:%.*]] = fptosi float [[TMP1]] to i16
+// CHECK-NEXT:store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT:ret void
+//
+void float_fix1() {
+  sa = fl;
+}
+
+// CHECK-LABEL: @float_fix2(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* @fl, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
+// CHECK-NEXT:[[TMP2:%.*]] = fptosi float [[TMP1]] to i32
+// CHECK-NEXT:store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT:ret void
+//
+void float_fix2() {
+  a = fl;
+}
+
+// CHECK-LABEL: @float_fix3(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* @fl, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = fmul float [[TMP0]], 0x41E0
+// CHECK-NEXT:[[TMP2:%.*]] = fptosi float [[TMP1]] to i64
+// CHECK-NEXT:store i64 [[TMP2]], i64* @la, align 8
+// CHECK-NEXT:ret void
+//
+void float_fix3() {
+  la = fl;
+}
+
+// CHECK-LABEL: @float_fix4(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[TMP0:%.*]] = load float, float* @fl, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = fmul float [[TMP0]], 1.28e+02
+// CHECK-NEXT:[[TMP2:%.*]] = fptosi float [[TMP1]] to i8

[PATCH] D86631: [Fixed Point] Add fixed-point to floating point cast types and consteval.

2020-08-26 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: leonardchan, rjmccall.
Herald added subscribers: bjope, martong.
Herald added a project: clang.
ebevhan requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86631

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

Index: clang/test/Frontend/fixed_point_unknown_conversions.c
===
--- clang/test/Frontend/fixed_point_unknown_conversions.c
+++ clang/test/Frontend/fixed_point_unknown_conversions.c
@@ -22,16 +22,12 @@
   _Fract fract = accum; // ok
   _Accum *accum_ptr;
 
-  accum = f;   // expected-error{{conversion between fixed point and 'float' is not yet supported}}
-  accum = d;   // expected-error{{conversion between fixed point and 'double' is not yet supported}}
   accum = dc;  // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
   accum = ic;  // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
   accum = s;   // expected-error{{assigning to '_Accum' from incompatible type 'struct S'}}
   accum = ptr; // expected-error{{assigning to '_Accum' from incompatible type 'int *'}}
   accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}}
 
-  f = accum;   // expected-error{{conversion between fixed point and 'float' is not yet supported}}
-  d = accum;   // expected-error{{conversion between fixed point and 'double' is not yet supported}}
   dc = accum;  // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
   ic = accum;  // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
   s = accum;   // expected-error{{assigning to 'struct S' from incompatible type '_Accum'}}
Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -286,8 +286,3 @@
 
 // Division by zero
 short _Accum div_zero = 4.5k / 0.0lr;  // expected-error {{initializer element is not a compile-time constant}}
-
-void foo(void) {
-  _Accum x = 0.5k;
-  if (x == 0.5) {} // expected-error{{invalid operands to binary expression ('_Accum' and 'double')}}
-}
Index: clang/test/Frontend/fixed_point_conversions_const.c
===
--- clang/test/Frontend/fixed_point_conversions_const.c
+++ clang/test/Frontend/fixed_point_conversions_const.c
@@ -43,6 +43,37 @@
 short _Accum sa_const7 = -256;
 // CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
 
+// Fixed point to floating point
+float fl_const = 1.0hk;
+// CHECK-DAG: @fl_const = {{.*}}global float 1.00e+00, align 4
+float fl_const2 = -128.0k;
+// CHECK-DAG: @fl_const2 = {{.*}}global float -1.28e+02, align 4
+float fl_const3 = 0.0872802734375k;
+// CHECK-DAG: @fl_const3 = {{.*}}global float 0x3FB65800, align 4
+float fl_const4 = 192.5k;
+// CHECK-DAG: @fl_const4 = {{.*}}global float 1.925000e+02, align 4
+float fl_const5 = -192.5k;
+// CHECK-DAG: @fl_const5 = {{.*}}global float -1.925000e+02, align 4
+
+// Floating point to fixed point
+_Accum a_fl_const = 1.0f;
+// CHECK-DAG: @a_fl_const = {{.*}}global i32 32768, align 4
+_Accum a_fl_const2 = -128.0f;
+// CHECK-DAG: @a_fl_const2 = {{.*}}global i32 -4194304, align 4
+_Accum a_fl_const3 = 0.0872802734375f;
+// CHECK-DAG: @a_fl_const3 = {{.*}}global i32 2860, align 4
+_Accum a_fl_const4 = 0.0872802734375;
+// CHECK-DAG: @a_fl_const4 = {{.*}}global i32 2860, align 4
+_Accum a_fl_const5 = -0.0872802734375f;
+// CHECK-DAG: @a_fl_const5 = {{.*}}global i32 -2860, align 4
+_Fract f_fl_const = 0.5f;
+// CHECK-DAG: @f_fl_const = {{.*}}global i16 16384, align 2
+_Fract f_fl_const2 = -0.75;
+// CHECK-DAG: @f_fl_const2 = {{.*}}global i16 -24576, align 2
+unsigned short _Accum usa_fl_const = 48.75f;
+// SIGNED-DAG: @usa_fl_const = {{.*}}global i16 12480, align 2
+// UNSIGNED-DAG: @usa_fl_const = {{.*}}global i16 6240, align 2
+
 // Signedness
 unsigned short _Accum usa_const2 = 2.5hk;
 // SIGNED-DAG: @usa_const2  = {{.*}}global i16 640, align 2
Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ 

[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-08-24 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan abandoned this revision.
ebevhan added a comment.




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663

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


[PATCH] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-08-24 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG577f8b157a03: [Fixed Point] Add codegen for fixed-point 
shifts. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83294/new/

https://reviews.llvm.org/D83294

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_shift.c
  clang/test/Frontend/fixed_point_shift_const.c

Index: clang/test/Frontend/fixed_point_shift_const.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_shift_const.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Accum sa_const1 = 1.0hk << 2;
+// CHECK-DAG: @sa_const1 = {{.*}}global i16 512
+short _Accum sa_const2 = 0.5hk << 2;
+// CHECK-DAG: @sa_const2 = {{.*}}global i16 256
+short _Accum sa_const3 = 10.0hk >> 3;
+// CHECK-DAG: @sa_const3 = {{.*}}global i16 160
+short _Accum sa_const4 = 0.0546875hk << 8;
+// CHECK-DAG: @sa_const4 = {{.*}}global i16 1792
+short _Accum sa_const5 = -1.0hk << 2;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 -512
+short _Accum sa_const6 = -255.0hk >> 8;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128
+
+_Fract f_const1 = -1.0r >> 5;
+// CHECK-DAG: @f_const1 = {{.*}}global i16 -1024
+_Fract f_const2 = 0.0052490234375r >> 3;
+// CHECK-DAG: @f_const2 = {{.*}}global i16 21
+_Fract f_const3 = -0.0001r << 5;
+// CHECK-DAG: @f_const3 = {{.*}}global i16 -96
+_Fract f_const4 = -0.75r >> 15;
+// CHECK-DAG: @f_const4 = {{.*}}global i16 -1
+_Fract f_const5 = 0.078216552734375r << 3;
+// CHECK-DAG: @f_const5 = {{.*}}global i16 20504
+
+unsigned _Fract uf_const1 = 0.375ur >> 13;
+// SIGNED-DAG:   @uf_const1 = {{.*}}global i16 3
+// UNSIGNED-DAG: @uf_const1 = {{.*}}global i16 1
+unsigned _Fract uf_const2 = 0.0546875ur << 3;
+// SIGNED-DAG:   @uf_const2 = {{.*}}global i16 28672
+// UNSIGNED-DAG: @uf_const2 = {{.*}}global i16 14336
+
+_Sat short _Accum ssa_const1 = (_Sat short _Accum)31.875hk << 4;
+// CHECK-DAG: @ssa_const1 = {{.*}}global i16 32767
+_Sat short _Accum ssa_const2 = (_Sat short _Accum) - 1.0hk << 8;
+// CHECK-DAG: @ssa_const2 = {{.*}}global i16 -32768
+_Sat short _Accum ssa_const3 = (_Sat short _Accum)128.0hk << 8;
+// CHECK-DAG: @ssa_const3 = {{.*}}global i16 32767
+_Sat short _Fract ssf_const1 = (_Sat short _Fract) - 0.5hr << 3;
+// CHECK-DAG: @ssf_const1 = {{.*}}global i8 -128
+
+_Sat unsigned _Fract suf_const1 = (_Sat unsigned _Fract)0.5r << 1;
+// SIGNED-DAG:   @suf_const1 = {{.*}}global i16 -1
+// UNSIGNED-DAG: @suf_const1 = {{.*}}global i16 32767
+_Sat unsigned _Fract suf_const2 = (_Sat unsigned _Fract)0.25r << 1;
+// SIGNED-DAG:   @suf_const2 = {{.*}}global i16 -32768
+// UNSIGNED-DAG: @suf_const2 = {{.*}}global i16 16384
+_Sat unsigned _Accum sua_const2 = (_Sat unsigned _Accum)128.0uk << 10;
+// SIGNED-DAG:   @sua_const2 = {{.*}}global i32 -1
+// UNSIGNED-DAG: @sua_const2 = {{.*}}global i32 2147483647
Index: clang/test/Frontend/fixed_point_shift.c
===
--- clang/test/Frontend/fixed_point_shift.c
+++ clang/test/Frontend/fixed_point_shift.c
@@ -1,37 +1,580 @@
-// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
-// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
-
-short _Accum sa_const1 = 1.0hk << 2;   // CHECK-DAG: @sa_const1 = {{.*}}global i16 512
-short _Accum sa_const2 = 0.5hk << 2;   // CHECK-DAG: @sa_const2 = {{.*}}global i16 256
-short _Accum sa_const3 = 10.0hk >> 3;  // CHECK-DAG: @sa_const3 = {{.*}}global i16 160
-short _Accum sa_const4 = 0.0546875hk << 8; // CHECK-DAG: @sa_const4 = {{.*}}global i16 1792
-short _Accum sa_const5 = -1.0hk << 2;  // CHECK-DAG: @sa_const5 = {{.*}}global i16 -512
-short _Accum sa_const6 = -255.0hk >> 8;// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128
-
-_Fract f_const1 = -1.0r >> 5;  // CHECK-DAG: @f_const1 = {{.*}}global i16 -1024
-_Fract f_const2 = 0.0052490234375r >> 3;   // CHECK-DAG: @f_const2 = {{.*}}global i16 21
-_Fract f_const3 = -0.0001r << 5;   // CHECK-DAG: @f_const3 = {{.*}}global i16 -96
-_Fract f_const4 = -0.75r >> 15;// CHECK-DAG: @f_const4 = {{.*}}global i16 -1
-_Fract f_const5 = 0.078216552734375r << 3; // CHECK-DAG: @f_const5 = {{.*}}global i16 20504
-
-unsigned _Fract uf_const1 = 0.375ur >> 13;
-// SIGNED-DAG:   @uf_const1 = {{.*}}global i16 3
-// UNSIGNED-DAG: @uf_const1 = {{.*}}global i16 1
-unsigned _Fract uf_const2 = 

[PATCH] D86282: [Fixed Point] Use FixedPointBuilder to codegen fixed-point IR.

2020-08-24 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG808ac5464521: [Fixed Point] Use FixedPointBuilder to codegen 
fixed-point IR. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86282/new/

https://reviews.llvm.org/D86282

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c
  clang/test/Frontend/fixed_point_unary.c

Index: clang/test/Frontend/fixed_point_unary.c
===
--- clang/test/Frontend/fixed_point_unary.c
+++ clang/test/Frontend/fixed_point_unary.c
@@ -148,9 +148,9 @@
 // UNSIGNED-LABEL: @inc_sua(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i32, i32* @sua, align 4
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[TMP1]] to i32
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 32768)
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[TMP1]] to i31
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[RESIZE]] to i32
 // UNSIGNED-NEXT:store i32 [[RESIZE1]], i32* @sua, align 4
 // UNSIGNED-NEXT:ret void
 //
@@ -168,9 +168,9 @@
 // UNSIGNED-LABEL: @inc_susa(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @susa, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE]], i15 128)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP0]], i16 128)
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16
 // UNSIGNED-NEXT:store i16 [[RESIZE1]], i16* @susa, align 2
 // UNSIGNED-NEXT:ret void
 //
@@ -188,9 +188,9 @@
 // UNSIGNED-LABEL: @inc_suf(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @suf, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE]], i15 -1)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP0]], i16 32767)
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16
 // UNSIGNED-NEXT:store i16 [[RESIZE1]], i16* @suf, align 2
 // UNSIGNED-NEXT:ret void
 //
@@ -329,9 +329,11 @@
 // UNSIGNED-LABEL: @dec_sua(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i32, i32* @sua, align 4
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[TMP1]] to i32
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP0]], i32 32768)
+// UNSIGNED-NEXT:[[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
+// UNSIGNED-NEXT:[[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i31
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[RESIZE]] to i32
 // UNSIGNED-NEXT:store i32 [[RESIZE1]], i32* @sua, align 4
 // UNSIGNED-NEXT:ret void
 //
@@ -349,9 +351,11 @@
 // UNSIGNED-LABEL: @dec_susa(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @susa, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE]], i15 128)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 128)
+// UNSIGNED-NEXT:[[TMP2:%.*]] = icmp slt i16 [[TMP1]], 0
+// UNSIGNED-NEXT:[[SATMIN:%.*]] = select i1 [[TMP2]], i16 0, i16 [[TMP1]]
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[SATMIN]] to i15
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16
 // UNSIGNED-NEXT:store i16 [[RESIZE1]], i16* @susa, align 2
 // UNSIGNED-NEXT:ret void
 //
@@ -369,9 +373,11 @@
 // UNSIGNED-LABEL: @dec_suf(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @suf, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE]], i15 -1)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 

[PATCH] D86447: [AST] Change return type of getTypeInfoInChars to a proper struct instead of std::pair.

2020-08-24 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added a reviewer: efriedma.
Herald added subscribers: bjope, martong, jfb.
Herald added a project: clang.
ebevhan requested review of this revision.

Followup to D85191 .

This changes getTypeInfoInChars to return a TypeInfoChars
struct instead of a std::pair of CharUnits. This lets the
interface match getTypeInfo more closely.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86447

Files:
  clang/include/clang/AST/ASTContext.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/CodeGen/CGAtomic.cpp
  clang/lib/CodeGen/CGBlocks.cpp
  clang/lib/CodeGen/CGCUDANV.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/CodeGen/CGObjC.cpp
  clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
  clang/lib/CodeGen/CGValue.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp

Index: clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -248,8 +248,9 @@
   FieldInfo RetVal;
   RetVal.Field = FD;
   auto  = FD->getASTContext();
-  std::tie(RetVal.Size, RetVal.Align) =
-  Ctx.getTypeInfoInChars(FD->getType());
+  auto Info = Ctx.getTypeInfoInChars(FD->getType());
+  RetVal.Size = Info.Width;
+  RetVal.Align = Info.Align;
   assert(llvm::isPowerOf2_64(RetVal.Align.getQuantity()));
   if (auto Max = FD->getMaxAlignment())
 RetVal.Align = std::max(Ctx.toCharUnitsFromBits(Max), RetVal.Align);
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -359,7 +359,7 @@
 ///   leaving one or more empty slots behind as padding.
 static Address emitVoidPtrVAArg(CodeGenFunction , Address VAListAddr,
 QualType ValueTy, bool IsIndirect,
-std::pair ValueInfo,
+TypeInfoChars ValueInfo,
 CharUnits SlotSizeAndAlign,
 bool AllowHigherAlign) {
   // The size and alignment of the value that was passed directly.
@@ -368,8 +368,8 @@
 DirectSize = CGF.getPointerSize();
 DirectAlign = CGF.getPointerAlign();
   } else {
-DirectSize = ValueInfo.first;
-DirectAlign = ValueInfo.second;
+DirectSize = ValueInfo.Width;
+DirectAlign = ValueInfo.Align;
   }
 
   // Cast the address we've calculated to the right type.
@@ -383,7 +383,7 @@
 AllowHigherAlign);
 
   if (IsIndirect) {
-Addr = Address(CGF.Builder.CreateLoad(Addr), ValueInfo.second);
+Addr = Address(CGF.Builder.CreateLoad(Addr), ValueInfo.Align);
   }
 
   return Addr;
@@ -656,7 +656,7 @@
 "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!");
 
 auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty);
-CharUnits TyAlignForABI = TyInfo.second;
+CharUnits TyAlignForABI = TyInfo.Align;
 
 llvm::Type *BaseTy =
 llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
@@ -2062,8 +2062,8 @@
   //
   // Just messing with TypeInfo like this works because we never pass
   // anything indirectly.
-  TypeInfo.second = CharUnits::fromQuantity(
-getTypeStackAlignInBytes(Ty, TypeInfo.second.getQuantity()));
+  TypeInfo.Align = CharUnits::fromQuantity(
+getTypeStackAlignInBytes(Ty, TypeInfo.Align.getQuantity()));
 
   return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false,
   TypeInfo, CharUnits::fromQuantity(4),
@@ -4063,10 +4063,9 @@
 RegAddr = CGF.Builder.CreateElementBitCast(RegAddr, LTy);
 
 // Copy to a temporary if necessary to ensure the appropriate alignment.
-std::pair SizeAlign =
-getContext().getTypeInfoInChars(Ty);
-uint64_t TySize = SizeAlign.first.getQuantity();
-CharUnits TyAlign = SizeAlign.second;
+auto TInfo = getContext().getTypeInfoInChars(Ty);
+uint64_t TySize = TInfo.Width.getQuantity();
+CharUnits TyAlign = TInfo.Align;
 
 // Copy into a temporary if the type is more aligned than the
 // register save area.
@@ -4572,7 +4571,7 @@
 llvm::report_fatal_error("vector type is not supported on AIX yet");
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
-  TypeInfo.second = getParamTypeAlignment(Ty);
+  TypeInfo.Align = getParamTypeAlignment(Ty);
 
   CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize);
 
@@ -4691,7 +4690,7 @@
   QualType Ty) const {
   if (getTarget().getTriple().isOSDarwin()) {
 auto TI = getContext().getTypeInfoInChars(Ty);
-TI.second = 

[PATCH] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-08-21 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 286968.
ebevhan added a comment.

Revamped patch. It's now based on the FixedPointBuilder.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83294/new/

https://reviews.llvm.org/D83294

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_shift.c
  clang/test/Frontend/fixed_point_shift_const.c

Index: clang/test/Frontend/fixed_point_shift_const.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_shift_const.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Accum sa_const1 = 1.0hk << 2;
+// CHECK-DAG: @sa_const1 = {{.*}}global i16 512
+short _Accum sa_const2 = 0.5hk << 2;
+// CHECK-DAG: @sa_const2 = {{.*}}global i16 256
+short _Accum sa_const3 = 10.0hk >> 3;
+// CHECK-DAG: @sa_const3 = {{.*}}global i16 160
+short _Accum sa_const4 = 0.0546875hk << 8;
+// CHECK-DAG: @sa_const4 = {{.*}}global i16 1792
+short _Accum sa_const5 = -1.0hk << 2;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 -512
+short _Accum sa_const6 = -255.0hk >> 8;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128
+
+_Fract f_const1 = -1.0r >> 5;
+// CHECK-DAG: @f_const1 = {{.*}}global i16 -1024
+_Fract f_const2 = 0.0052490234375r >> 3;
+// CHECK-DAG: @f_const2 = {{.*}}global i16 21
+_Fract f_const3 = -0.0001r << 5;
+// CHECK-DAG: @f_const3 = {{.*}}global i16 -96
+_Fract f_const4 = -0.75r >> 15;
+// CHECK-DAG: @f_const4 = {{.*}}global i16 -1
+_Fract f_const5 = 0.078216552734375r << 3;
+// CHECK-DAG: @f_const5 = {{.*}}global i16 20504
+
+unsigned _Fract uf_const1 = 0.375ur >> 13;
+// SIGNED-DAG:   @uf_const1 = {{.*}}global i16 3
+// UNSIGNED-DAG: @uf_const1 = {{.*}}global i16 1
+unsigned _Fract uf_const2 = 0.0546875ur << 3;
+// SIGNED-DAG:   @uf_const2 = {{.*}}global i16 28672
+// UNSIGNED-DAG: @uf_const2 = {{.*}}global i16 14336
+
+_Sat short _Accum ssa_const1 = (_Sat short _Accum)31.875hk << 4;
+// CHECK-DAG: @ssa_const1 = {{.*}}global i16 32767
+_Sat short _Accum ssa_const2 = (_Sat short _Accum) - 1.0hk << 8;
+// CHECK-DAG: @ssa_const2 = {{.*}}global i16 -32768
+_Sat short _Accum ssa_const3 = (_Sat short _Accum)128.0hk << 8;
+// CHECK-DAG: @ssa_const3 = {{.*}}global i16 32767
+_Sat short _Fract ssf_const1 = (_Sat short _Fract) - 0.5hr << 3;
+// CHECK-DAG: @ssf_const1 = {{.*}}global i8 -128
+
+_Sat unsigned _Fract suf_const1 = (_Sat unsigned _Fract)0.5r << 1;
+// SIGNED-DAG:   @suf_const1 = {{.*}}global i16 -1
+// UNSIGNED-DAG: @suf_const1 = {{.*}}global i16 32767
+_Sat unsigned _Fract suf_const2 = (_Sat unsigned _Fract)0.25r << 1;
+// SIGNED-DAG:   @suf_const2 = {{.*}}global i16 -32768
+// UNSIGNED-DAG: @suf_const2 = {{.*}}global i16 16384
+_Sat unsigned _Accum sua_const2 = (_Sat unsigned _Accum)128.0uk << 10;
+// SIGNED-DAG:   @sua_const2 = {{.*}}global i32 -1
+// UNSIGNED-DAG: @sua_const2 = {{.*}}global i32 2147483647
Index: clang/test/Frontend/fixed_point_shift.c
===
--- clang/test/Frontend/fixed_point_shift.c
+++ clang/test/Frontend/fixed_point_shift.c
@@ -1,37 +1,580 @@
-// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
-// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
-
-short _Accum sa_const1 = 1.0hk << 2;   // CHECK-DAG: @sa_const1 = {{.*}}global i16 512
-short _Accum sa_const2 = 0.5hk << 2;   // CHECK-DAG: @sa_const2 = {{.*}}global i16 256
-short _Accum sa_const3 = 10.0hk >> 3;  // CHECK-DAG: @sa_const3 = {{.*}}global i16 160
-short _Accum sa_const4 = 0.0546875hk << 8; // CHECK-DAG: @sa_const4 = {{.*}}global i16 1792
-short _Accum sa_const5 = -1.0hk << 2;  // CHECK-DAG: @sa_const5 = {{.*}}global i16 -512
-short _Accum sa_const6 = -255.0hk >> 8;// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128
-
-_Fract f_const1 = -1.0r >> 5;  // CHECK-DAG: @f_const1 = {{.*}}global i16 -1024
-_Fract f_const2 = 0.0052490234375r >> 3;   // CHECK-DAG: @f_const2 = {{.*}}global i16 21
-_Fract f_const3 = -0.0001r << 5;   // CHECK-DAG: @f_const3 = {{.*}}global i16 -96
-_Fract f_const4 = -0.75r >> 15;// CHECK-DAG: @f_const4 = {{.*}}global i16 -1
-_Fract f_const5 = 0.078216552734375r << 3; // CHECK-DAG: @f_const5 = {{.*}}global i16 20504
-
-unsigned _Fract uf_const1 = 0.375ur >> 13;
-// SIGNED-DAG:   @uf_const1 = {{.*}}global i16 3
-// UNSIGNED-DAG: @uf_const1 = {{.*}}global i16 1
-unsigned _Fract uf_const2 = 0.0546875ur << 3;
-// SIGNED-DAG:   @uf_const2 = {{.*}}global i16 28672
-// UNSIGNED-DAG: @uf_const2 = 

[PATCH] D86282: [Fixed Point] Use FixedPointBuilder to codegen fixed-point IR.

2020-08-20 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: leonardchan, rjmccall.
Herald added a subscriber: bjope.
Herald added a project: clang.
ebevhan requested review of this revision.

This changes the methods in CGExprScalar to use
FixedPointBuilder to generate IR for fixed-point
conversions and operations.

Since FixedPointBuilder emits padded operations slightly
differently than the original code, some tests change.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D86282

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c
  clang/test/Frontend/fixed_point_unary.c

Index: clang/test/Frontend/fixed_point_unary.c
===
--- clang/test/Frontend/fixed_point_unary.c
+++ clang/test/Frontend/fixed_point_unary.c
@@ -148,9 +148,9 @@
 // UNSIGNED-LABEL: @inc_sua(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i32, i32* @sua, align 4
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[TMP1]] to i32
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 32768)
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[TMP1]] to i31
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[RESIZE]] to i32
 // UNSIGNED-NEXT:store i32 [[RESIZE1]], i32* @sua, align 4
 // UNSIGNED-NEXT:ret void
 //
@@ -168,9 +168,9 @@
 // UNSIGNED-LABEL: @inc_susa(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @susa, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE]], i15 128)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP0]], i16 128)
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16
 // UNSIGNED-NEXT:store i16 [[RESIZE1]], i16* @susa, align 2
 // UNSIGNED-NEXT:ret void
 //
@@ -188,9 +188,9 @@
 // UNSIGNED-LABEL: @inc_suf(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @suf, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE]], i15 -1)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP0]], i16 32767)
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16
 // UNSIGNED-NEXT:store i16 [[RESIZE1]], i16* @suf, align 2
 // UNSIGNED-NEXT:ret void
 //
@@ -329,9 +329,11 @@
 // UNSIGNED-LABEL: @dec_sua(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i32, i32* @sua, align 4
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[TMP1]] to i32
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP0]], i32 32768)
+// UNSIGNED-NEXT:[[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
+// UNSIGNED-NEXT:[[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[TMP1]]
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i31
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i31 [[RESIZE]] to i32
 // UNSIGNED-NEXT:store i32 [[RESIZE1]], i32* @sua, align 4
 // UNSIGNED-NEXT:ret void
 //
@@ -349,9 +351,11 @@
 // UNSIGNED-LABEL: @dec_susa(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @susa, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE]], i15 128)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT:[[TMP1:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 128)
+// UNSIGNED-NEXT:[[TMP2:%.*]] = icmp slt i16 [[TMP1]], 0
+// UNSIGNED-NEXT:[[SATMIN:%.*]] = select i1 [[TMP2]], i16 0, i16 [[TMP1]]
+// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[SATMIN]] to i15
+// UNSIGNED-NEXT:[[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16
 // UNSIGNED-NEXT:store i16 [[RESIZE1]], i16* @susa, align 2
 // UNSIGNED-NEXT:ret void
 //
@@ -369,9 +373,11 @@
 // UNSIGNED-LABEL: @dec_suf(
 // UNSIGNED-NEXT:  entry:
 // UNSIGNED-NEXT:[[TMP0:%.*]] = load i16, i16* @suf, align 2
-// UNSIGNED-NEXT:[[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
-// UNSIGNED-NEXT:[[TMP1:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE]], i15 -1)
-// UNSIGNED-NEXT:[[RESIZE1:%.*]] 

[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-20 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG1e7ec4842c1a: [AST] Get field size in chars rather than bits 
in RecordLayoutBuilder. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

Files:
  clang/lib/AST/RecordLayoutBuilder.cpp


Index: clang/lib/AST/RecordLayoutBuilder.cpp
===
--- clang/lib/AST/RecordLayoutBuilder.cpp
+++ clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1838,14 +1838,13 @@
   CharUnits EffectiveFieldSize;
 
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;
 // Flexible array members don't have any size, but they have to be
 // aligned appropriately for their element type.
 EffectiveFieldSize = FieldSize =
-IsIncompleteArrayType ? CharUnits::Zero()
-  : Context.toCharUnitsFromBits(TI.Width);
-AlignIsRequired = TI.AlignIsRequired;
+IsIncompleteArrayType ? CharUnits::Zero() : TI.first;
+AlignIsRequired = Context.getTypeInfo(D->getType()).AlignIsRequired;
   };
 
   if (D->getType()->isIncompleteArrayType()) {


Index: clang/lib/AST/RecordLayoutBuilder.cpp
===
--- clang/lib/AST/RecordLayoutBuilder.cpp
+++ clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1838,14 +1838,13 @@
   CharUnits EffectiveFieldSize;
 
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;
 // Flexible array members don't have any size, but they have to be
 // aligned appropriately for their element type.
 EffectiveFieldSize = FieldSize =
-IsIncompleteArrayType ? CharUnits::Zero()
-  : Context.toCharUnitsFromBits(TI.Width);
-AlignIsRequired = TI.AlignIsRequired;
+IsIncompleteArrayType ? CharUnits::Zero() : TI.first;
+AlignIsRequired = Context.getTypeInfo(D->getType()).AlignIsRequired;
   };
 
   if (D->getType()->isIncompleteArrayType()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85312: [ADT] Move FixedPoint.h from Clang to LLVM.

2020-08-20 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG1a995a0af3c4: [ADT] Move FixedPoint.h from Clang to LLVM. 
(authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85312/new/

https://reviews.llvm.org/D85312

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/OptionalDiagnostic.h
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/Basic/CMakeLists.txt
  clang/unittests/Basic/FixedPointTest.cpp
  llvm/include/llvm/ADT/APFixedPoint.h
  llvm/lib/Support/APFixedPoint.cpp
  llvm/lib/Support/CMakeLists.txt
  llvm/unittests/ADT/APFixedPointTest.cpp
  llvm/unittests/ADT/CMakeLists.txt

Index: llvm/unittests/ADT/CMakeLists.txt
===
--- llvm/unittests/ADT/CMakeLists.txt
+++ llvm/unittests/ADT/CMakeLists.txt
@@ -4,6 +4,7 @@
 
 add_llvm_unittest(ADTTests
   AnyTest.cpp
+  APFixedPointTest.cpp
   APFloatTest.cpp
   APIntTest.cpp
   APSIntTest.cpp
Index: llvm/unittests/ADT/APFixedPointTest.cpp
===
--- llvm/unittests/ADT/APFixedPointTest.cpp
+++ llvm/unittests/ADT/APFixedPointTest.cpp
@@ -1,4 +1,4 @@
-//===- unittests/Basic/FixedPointTest.cpp -- fixed point number tests -===//
+//===- unittests/ADT/FixedPointTest.cpp -- fixed point number tests -===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,12 +6,12 @@
 //
 //===--===//
 
-#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APFixedPoint.h"
 #include "llvm/ADT/APSInt.h"
 #include "gtest/gtest.h"
 
-using clang::APFixedPoint;
-using clang::FixedPointSemantics;
+using llvm::APFixedPoint;
+using llvm::FixedPointSemantics;
 using llvm::APInt;
 using llvm::APSInt;
 
Index: llvm/lib/Support/CMakeLists.txt
===
--- llvm/lib/Support/CMakeLists.txt
+++ llvm/lib/Support/CMakeLists.txt
@@ -67,6 +67,7 @@
   ABIBreak.cpp
   ARMTargetParser.cpp
   AMDGPUMetadata.cpp
+  APFixedPoint.cpp
   APFloat.cpp
   APInt.cpp
   APSInt.cpp
Index: llvm/lib/Support/APFixedPoint.cpp
===
--- llvm/lib/Support/APFixedPoint.cpp
+++ llvm/lib/Support/APFixedPoint.cpp
@@ -1,4 +1,4 @@
-//===- FixedPoint.cpp - Fixed point constant handling ---*- C++ -*-===//
+//===- APFixedPoint.cpp - Fixed point constant handling -*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -11,13 +11,13 @@
 //
 //===--===//
 
-#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APFixedPoint.h"
 
-namespace clang {
+namespace llvm {
 
 APFixedPoint APFixedPoint::convert(const FixedPointSemantics ,
bool *Overflow) const {
-  llvm::APSInt NewVal = Val;
+  APSInt NewVal = Val;
   unsigned DstWidth = DstSema.getWidth();
   unsigned DstScale = DstSema.getScale();
   bool Upscaling = DstScale > getScale();
@@ -31,10 +31,10 @@
 NewVal >>= (getScale() - DstScale);
   }
 
-  auto Mask = llvm::APInt::getBitsSetFrom(
+  auto Mask = APInt::getBitsSetFrom(
   NewVal.getBitWidth(),
   std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
-  llvm::APInt Masked(NewVal & Mask);
+  APInt Masked(NewVal & Mask);
 
   // Change in the bits above the sign
   if (!(Masked == Mask || Masked == 0)) {
@@ -61,8 +61,8 @@
 }
 
 int APFixedPoint::compare(const APFixedPoint ) const {
-  llvm::APSInt ThisVal = getValue();
-  llvm::APSInt OtherVal = Other.getValue();
+  APSInt ThisVal = getValue();
+  APSInt OtherVal = Other.getValue();
   bool ThisSigned = Val.isSigned();
   bool OtherSigned = OtherVal.isSigned();
   unsigned OtherScale = Other.getScale();
@@ -113,14 +113,14 @@
 
 APFixedPoint APFixedPoint::getMax(const FixedPointSemantics ) {
   bool IsUnsigned = !Sema.isSigned();
-  auto Val = llvm::APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
+  auto Val = APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
   if (IsUnsigned && Sema.hasUnsignedPadding())
 Val = Val.lshr(1);
   return APFixedPoint(Val, Sema);
 }
 
 APFixedPoint APFixedPoint::getMin(const 

[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-19 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1847
+IsIncompleteArrayType ? CharUnits::Zero() : TI.first;
+AlignIsRequired = Context.getTypeInfo(D->getType()).AlignIsRequired;
   };

efriedma wrote:
> Can we fix getTypeInfoInChars so it returns all the necessary info, so we 
> don't look up the typeinfo twice?
That feels like a hefty change since it would require changing every caller of 
getTypeInfoInChars. Do you want me to do that in this patch or in a separate 
one?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

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


[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-18 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

It doesn't feel like this patch got a very positive reception, but I'd still 
like to try a bit more to get it in.

Even though it's difficult to test this particular change upstream, would it 
still be acceptable to take the patch since it reverts the behavior to what it 
was previously? If there are worries that things may break in the future due to 
other changes, we do catch these things in our downstream testing and are 
fairly diligent about reporting back about them.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

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


[PATCH] D85312: [ADT] Move FixedPoint.h from Clang to LLVM.

2020-08-13 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Thanks for reviewing! I'm not really sure who to add as reviewers for D85314 
, though, and no one has replied to the RFC on 
the mailing list yet.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85312/new/

https://reviews.llvm.org/D85312

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


[PATCH] D62574: Add support for target-configurable address spaces.

2020-08-11 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

I think this works now. It should probably be given a few more reviewers to 
have a look. Do you have some suggestions, @Anastasia ?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

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


[PATCH] D62574: Add support for target-configurable address spaces.

2020-08-11 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 284765.
ebevhan retitled this revision from "Initial draft of target-configurable 
address spaces." to "Add support for target-configurable address spaces.".
ebevhan edited the summary of this revision.
ebevhan added a comment.

Rebased and updated summary.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

Files:
  clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/CanonicalType.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CodeGenCXX/address-space-cast.cpp
  clang/test/Sema/address_space_print_macro.c
  clang/test/Sema/address_spaces.c

Index: clang/test/Sema/address_spaces.c
===
--- clang/test/Sema/address_spaces.c
+++ clang/test/Sema/address_spaces.c
@@ -71,7 +71,8 @@
 
 // Clang extension doesn't forbid operations on pointers to different address spaces.
 char* cmp(_AS1 char *x,  _AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}} \
+// expected-error{{comparison between  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
 }
 
 char *sub(_AS1 char *x, _AS2 char *y) {
Index: clang/test/Sema/address_space_print_macro.c
===
--- clang/test/Sema/address_space_print_macro.c
+++ clang/test/Sema/address_space_print_macro.c
@@ -14,7 +14,8 @@
 }
 
 char *cmp(AS1 char *x, AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}} \
+// expected-error{{comparison between  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
 }
 
 __attribute__((address_space(1))) char test_array[10];
Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -37,8 +37,9 @@
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
   priv_void_ptr = (__private__ void *)gen_void_ptr;
 
-  // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
-  // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = addrspacecast i8* %[[cast]] to i8 addrspace(5)*
+  // CHECK-NEXT: store i8 addrspace(5)* %[[cast2]]
   priv_void_ptr = (__private__ void *)gen_int_ptr;
 
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
@@ -65,8 +66,9 @@
   // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
   func_pvoid((__private__ void *)gen_void_ptr);
 
-  // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
-  // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = addrspacecast i8* %[[cast]] to i8 addrspace(5)*
+  // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast2]])
   func_pvoid((__private__ void *)gen_int_ptr);
 
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1571,7 +1571,8 @@
   // C++ [temp.deduct.conv]p4:
   //   If the original A is a reference type, A can be more cv-qualified
   //   than the deduced A
-  if (!Arg.getQualifiers().compatiblyIncludes(Param.getQualifiers()))
+  if (!S.Context.compatiblyIncludes(Arg.getQualifiers(),
+  

[PATCH] D81904: [clang] Do not crash for unsupported fixed point to floating point conversion

2020-08-11 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd4408fe17f33: [clang] Do not crash for unsupported fixed 
point to floating point conversion (authored by gousemoodhin, committed by 
ebevhan).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D81904?vs=284232=284749#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81904/new/

https://reviews.llvm.org/D81904

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Frontend/fixed_point_errors.c


Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -286,3 +286,8 @@
 
 // Division by zero
 short _Accum div_zero = 4.5k / 0.0lr;  // expected-error {{initializer element 
is not a compile-time constant}}
+
+void foo(void) {
+  _Accum x = 0.5k;
+  if (x == 0.5) {} // expected-error{{invalid operands to binary expression 
('_Accum' and 'double')}}
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -1125,6 +1125,11 @@
   bool LHSFloat = LHSType->isRealFloatingType();
   bool RHSFloat = RHSType->isRealFloatingType();
 
+  // FIXME: Implement floating to fixed point conversion.(Bug 46268)
+  // Reference N1169 4.1.4 (Type conversion, usual arithmetic conversions).
+  if ((LHSType->isFixedPointType() && RHSFloat) ||
+  (LHSFloat && RHSType->isFixedPointType()))
+return QualType();
   // If we have two real floating types, convert the smaller operand
   // to the bigger result.
   if (LHSFloat && RHSFloat) {


Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -286,3 +286,8 @@
 
 // Division by zero
 short _Accum div_zero = 4.5k / 0.0lr;  // expected-error {{initializer element is not a compile-time constant}}
+
+void foo(void) {
+  _Accum x = 0.5k;
+  if (x == 0.5) {} // expected-error{{invalid operands to binary expression ('_Accum' and 'double')}}
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -1125,6 +1125,11 @@
   bool LHSFloat = LHSType->isRealFloatingType();
   bool RHSFloat = RHSType->isRealFloatingType();
 
+  // FIXME: Implement floating to fixed point conversion.(Bug 46268)
+  // Reference N1169 4.1.4 (Type conversion, usual arithmetic conversions).
+  if ((LHSType->isFixedPointType() && RHSFloat) ||
+  (LHSFloat && RHSType->isFixedPointType()))
+return QualType();
   // If we have two real floating types, convert the smaller operand
   // to the bigger result.
   if (LHSFloat && RHSFloat) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83325: [Sema] Iteratively strip sugar when removing address spaces.

2020-08-11 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG956582aa1658: [Sema] Iteratively strip sugar when removing 
address spaces. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83325/new/

https://reviews.llvm.org/D83325

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/CodeGenCXX/address-space-cast.cpp


Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -6,6 +6,16 @@
 void func_pvoid(__private__ void *x);
 void func_pint(__private__ int *x);
 
+class Base {
+};
+
+class Derived : public Base {
+};
+
+void fn(Derived *p) {
+  __private__ Base *b = (__private__ Base *)p;
+}
+
 void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2934,14 +2934,27 @@
 }
 
 QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
+  // If the type is not qualified with an address space, just return it
+  // immediately.
+  if (!T.hasAddressSpace())
+return T;
+
   // If we are composing extended qualifiers together, merge together
   // into one ExtQuals node.
   QualifierCollector Quals;
-  const Type *TypeNode = Quals.strip(T);
+  const Type *TypeNode;
 
-  // If the qualifier doesn't have an address space just return it.
-  if (!Quals.hasAddressSpace())
-return T;
+  while (T.hasAddressSpace()) {
+TypeNode = Quals.strip(T);
+
+// If the type no longer has an address space after stripping qualifiers,
+// jump out.
+if (!QualType(TypeNode, 0).hasAddressSpace())
+  break;
+
+// There might be sugar in the way. Strip it and try again.
+T = T.getSingleStepDesugaredType(*this);
+  }
 
   Quals.removeAddressSpace();
 


Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -6,6 +6,16 @@
 void func_pvoid(__private__ void *x);
 void func_pint(__private__ int *x);
 
+class Base {
+};
+
+class Derived : public Base {
+};
+
+void fn(Derived *p) {
+  __private__ Base *b = (__private__ Base *)p;
+}
+
 void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2934,14 +2934,27 @@
 }
 
 QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
+  // If the type is not qualified with an address space, just return it
+  // immediately.
+  if (!T.hasAddressSpace())
+return T;
+
   // If we are composing extended qualifiers together, merge together
   // into one ExtQuals node.
   QualifierCollector Quals;
-  const Type *TypeNode = Quals.strip(T);
+  const Type *TypeNode;
 
-  // If the qualifier doesn't have an address space just return it.
-  if (!Quals.hasAddressSpace())
-return T;
+  while (T.hasAddressSpace()) {
+TypeNode = Quals.strip(T);
+
+// If the type no longer has an address space after stripping qualifiers,
+// jump out.
+if (!QualType(TypeNode, 0).hasAddressSpace())
+  break;
+
+// There might be sugar in the way. Strip it and try again.
+T = T.getSingleStepDesugaredType(*this);
+  }
 
   Quals.removeAddressSpace();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83325: [Sema] Iteratively strip sugar when removing address spaces.

2020-08-11 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D83325#2209589 , @svenvh wrote:

> LGTM, but just wondering if the test actually belongs to this patch, as it 
> doesn't demonstrate the problem without one of your other patches?

Mm, that is true, but then I'd be submitting the patch without a test and that 
doesn't seem quite right.

I'm unsure if there's a way to exhibit the failure without the followup patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83325/new/

https://reviews.llvm.org/D83325

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


[PATCH] D83325: [Sema] Iteratively strip sugar when removing address spaces.

2020-08-10 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 284395.
ebevhan retitled this revision from "[Sema] Be more thorough when unpacking the 
AS-qualified pointee for a pointer conversion." to "[Sema] Iteratively strip 
sugar when removing address spaces.".
ebevhan edited the summary of this revision.
ebevhan added a comment.

Redid patch. Now we properly strip ASes from types by desugaring.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83325/new/

https://reviews.llvm.org/D83325

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/CodeGenCXX/address-space-cast.cpp


Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -6,6 +6,16 @@
 void func_pvoid(__private__ void *x);
 void func_pint(__private__ int *x);
 
+class Base {
+};
+
+class Derived : public Base {
+};
+
+void fn(Derived *p) {
+  __private__ Base *b = (__private__ Base *)p;
+}
+
 void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2934,14 +2934,27 @@
 }
 
 QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
+  // If the type is not qualified with an address space, just return it
+  // immediately.
+  if (!T.hasAddressSpace())
+return T;
+
   // If we are composing extended qualifiers together, merge together
   // into one ExtQuals node.
   QualifierCollector Quals;
-  const Type *TypeNode = Quals.strip(T);
+  const Type *TypeNode;
 
-  // If the qualifier doesn't have an address space just return it.
-  if (!Quals.hasAddressSpace())
-return T;
+  while (T.hasAddressSpace()) {
+TypeNode = Quals.strip(T);
+
+// If the type no longer has an address space after stripping qualifiers,
+// jump out.
+if (!QualType(TypeNode, 0).hasAddressSpace())
+  break;
+
+// There might be sugar in the way. Strip it and try again.
+T = T.getSingleStepDesugaredType(*this);
+  }
 
   Quals.removeAddressSpace();
 


Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -6,6 +6,16 @@
 void func_pvoid(__private__ void *x);
 void func_pint(__private__ int *x);
 
+class Base {
+};
+
+class Derived : public Base {
+};
+
+void fn(Derived *p) {
+  __private__ Base *b = (__private__ Base *)p;
+}
+
 void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2934,14 +2934,27 @@
 }
 
 QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
+  // If the type is not qualified with an address space, just return it
+  // immediately.
+  if (!T.hasAddressSpace())
+return T;
+
   // If we are composing extended qualifiers together, merge together
   // into one ExtQuals node.
   QualifierCollector Quals;
-  const Type *TypeNode = Quals.strip(T);
+  const Type *TypeNode;
 
-  // If the qualifier doesn't have an address space just return it.
-  if (!Quals.hasAddressSpace())
-return T;
+  while (T.hasAddressSpace()) {
+TypeNode = Quals.strip(T);
+
+// If the type no longer has an address space after stripping qualifiers,
+// jump out.
+if (!QualType(TypeNode, 0).hasAddressSpace())
+  break;
+
+// There might be sugar in the way. Strip it and try again.
+T = T.getSingleStepDesugaredType(*this);
+  }
 
   Quals.removeAddressSpace();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83212: [Fixed Point] Add fixed-point shift operations and consteval.

2020-08-07 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGaa0d19a0c8f5: [Fixed Point] Add fixed-point shift operations 
and consteval. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83212/new/

https://reviews.llvm.org/D83212

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Frontend/fixed_point_errors.c
  clang/test/Frontend/fixed_point_shift.c

Index: clang/test/Frontend/fixed_point_shift.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_shift.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Accum sa_const1 = 1.0hk << 2;   // CHECK-DAG: @sa_const1 = {{.*}}global i16 512
+short _Accum sa_const2 = 0.5hk << 2;   // CHECK-DAG: @sa_const2 = {{.*}}global i16 256
+short _Accum sa_const3 = 10.0hk >> 3;  // CHECK-DAG: @sa_const3 = {{.*}}global i16 160
+short _Accum sa_const4 = 0.0546875hk << 8; // CHECK-DAG: @sa_const4 = {{.*}}global i16 1792
+short _Accum sa_const5 = -1.0hk << 2;  // CHECK-DAG: @sa_const5 = {{.*}}global i16 -512
+short _Accum sa_const6 = -255.0hk >> 8;// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128
+
+_Fract f_const1 = -1.0r >> 5;  // CHECK-DAG: @f_const1 = {{.*}}global i16 -1024
+_Fract f_const2 = 0.0052490234375r >> 3;   // CHECK-DAG: @f_const2 = {{.*}}global i16 21
+_Fract f_const3 = -0.0001r << 5;   // CHECK-DAG: @f_const3 = {{.*}}global i16 -96
+_Fract f_const4 = -0.75r >> 15;// CHECK-DAG: @f_const4 = {{.*}}global i16 -1
+_Fract f_const5 = 0.078216552734375r << 3; // CHECK-DAG: @f_const5 = {{.*}}global i16 20504
+
+unsigned _Fract uf_const1 = 0.375ur >> 13;
+// SIGNED-DAG:   @uf_const1 = {{.*}}global i16 3
+// UNSIGNED-DAG: @uf_const1 = {{.*}}global i16 1
+unsigned _Fract uf_const2 = 0.0546875ur << 3;
+// SIGNED-DAG:   @uf_const2 = {{.*}}global i16 28672
+// UNSIGNED-DAG: @uf_const2 = {{.*}}global i16 14336
+
+_Sat short _Accum ssa_const1 = (_Sat short _Accum)31.875hk << 4; // CHECK-DAG: @ssa_const1 = {{.*}}global i16 32767
+_Sat short _Accum ssa_const2 = (_Sat short _Accum) - 1.0hk << 8; // CHECK-DAG: @ssa_const2 = {{.*}}global i16 -32768
+_Sat short _Accum ssa_const3 = (_Sat short _Accum)128.0hk << 8;  // CHECK-DAG: @ssa_const3 = {{.*}}global i16 32767
+_Sat short _Fract ssf_const1 = (_Sat short _Fract) - 0.5hr << 3; // CHECK-DAG: @ssf_const1 = {{.*}}global i8 -128
+
+_Sat unsigned _Fract suf_const1 = (_Sat unsigned _Fract)0.5r << 1;
+// SIGNED-DAG:   @suf_const1 = {{.*}}global i16 -1
+// UNSIGNED-DAG: @suf_const1 = {{.*}}global i16 32767
+_Sat unsigned _Fract suf_const2 = (_Sat unsigned _Fract)0.25r << 1;
+// SIGNED-DAG:   @suf_const2 = {{.*}}global i16 -32768
+// UNSIGNED-DAG: @suf_const2 = {{.*}}global i16 16384
+_Sat unsigned _Accum sua_const2 = (_Sat unsigned _Accum)128.0uk << 10;
+// SIGNED-DAG:   @sua_const2 = {{.*}}global i32 -1
+// UNSIGNED-DAG: @sua_const2 = {{.*}}global i32 2147483647
Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -259,11 +259,30 @@
 short _Accum mul_ovf2 = (-0.5hr - 0.5hr) * (-0.5hr - 0.5hr);  // expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
 short _Accum div_ovf1 = 255.0hk / 0.5hk;  // expected-warning {{overflow in expression; result is -2.0 with type 'short _Accum'}}
 
+short _Accum shl_ovf1 = 255.0hk << 8;   // expected-warning {{overflow in expression; result is -256.0 with type 'short _Accum'}}
+short _Fract shl_ovf2 = -0.25hr << 3;   // expected-warning {{overflow in expression; result is 0.0 with type 'short _Fract'}}
+unsigned short _Accum shl_ovf3 = 100.5uhk << 3; // expected-warning {{overflow in expression; result is 36.0 with type 'unsigned short _Accum'}}
+short _Fract shl_ovf4 = 0.25hr << 2;// expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
+
+_Accum shl_bw1 = 0.91552734375k << 32;   // expected-warning {{shift count >= width of type}} \
+ expected-warning {{overflow in expression; result is -65536.0 with type '_Accum'}}
+unsigned _Fract shl_bw2 = 0.65ur << 16;  // expected-warning {{shift count >= width of type}} \
+ expected-warning {{overflow in expression; result is 0.0 with type 'unsigned 

[PATCH] D85312: [ADT] Move FixedPoint.h from Clang to LLVM.

2020-08-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 283873.
ebevhan added a comment.

Fix some formatting.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85312/new/

https://reviews.llvm.org/D85312

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/OptionalDiagnostic.h
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/Basic/CMakeLists.txt
  clang/unittests/Basic/FixedPointTest.cpp
  llvm/include/llvm/ADT/APFixedPoint.h
  llvm/lib/Support/APFixedPoint.cpp
  llvm/lib/Support/CMakeLists.txt
  llvm/unittests/ADT/APFixedPointTest.cpp
  llvm/unittests/ADT/CMakeLists.txt

Index: llvm/unittests/ADT/CMakeLists.txt
===
--- llvm/unittests/ADT/CMakeLists.txt
+++ llvm/unittests/ADT/CMakeLists.txt
@@ -4,6 +4,7 @@
 
 add_llvm_unittest(ADTTests
   AnyTest.cpp
+  APFixedPointTest.cpp
   APFloatTest.cpp
   APIntTest.cpp
   APSIntTest.cpp
Index: llvm/unittests/ADT/APFixedPointTest.cpp
===
--- llvm/unittests/ADT/APFixedPointTest.cpp
+++ llvm/unittests/ADT/APFixedPointTest.cpp
@@ -1,4 +1,4 @@
-//===- unittests/Basic/FixedPointTest.cpp -- fixed point number tests -===//
+//===- unittests/ADT/FixedPointTest.cpp -- fixed point number tests -===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,12 +6,12 @@
 //
 //===--===//
 
-#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APFixedPoint.h"
 #include "llvm/ADT/APSInt.h"
 #include "gtest/gtest.h"
 
-using clang::APFixedPoint;
-using clang::FixedPointSemantics;
+using llvm::APFixedPoint;
+using llvm::FixedPointSemantics;
 using llvm::APInt;
 using llvm::APSInt;
 
Index: llvm/lib/Support/CMakeLists.txt
===
--- llvm/lib/Support/CMakeLists.txt
+++ llvm/lib/Support/CMakeLists.txt
@@ -56,6 +56,7 @@
   ABIBreak.cpp
   ARMTargetParser.cpp
   AMDGPUMetadata.cpp
+  APFixedPoint.cpp
   APFloat.cpp
   APInt.cpp
   APSInt.cpp
Index: llvm/lib/Support/APFixedPoint.cpp
===
--- llvm/lib/Support/APFixedPoint.cpp
+++ llvm/lib/Support/APFixedPoint.cpp
@@ -1,4 +1,4 @@
-//===- FixedPoint.cpp - Fixed point constant handling ---*- C++ -*-===//
+//===- APFixedPoint.cpp - Fixed point constant handling -*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -11,13 +11,13 @@
 //
 //===--===//
 
-#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APFixedPoint.h"
 
-namespace clang {
+namespace llvm {
 
 APFixedPoint APFixedPoint::convert(const FixedPointSemantics ,
bool *Overflow) const {
-  llvm::APSInt NewVal = Val;
+  APSInt NewVal = Val;
   unsigned DstWidth = DstSema.getWidth();
   unsigned DstScale = DstSema.getScale();
   bool Upscaling = DstScale > getScale();
@@ -31,10 +31,10 @@
 NewVal >>= (getScale() - DstScale);
   }
 
-  auto Mask = llvm::APInt::getBitsSetFrom(
+  auto Mask = APInt::getBitsSetFrom(
   NewVal.getBitWidth(),
   std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
-  llvm::APInt Masked(NewVal & Mask);
+  APInt Masked(NewVal & Mask);
 
   // Change in the bits above the sign
   if (!(Masked == Mask || Masked == 0)) {
@@ -61,8 +61,8 @@
 }
 
 int APFixedPoint::compare(const APFixedPoint ) const {
-  llvm::APSInt ThisVal = getValue();
-  llvm::APSInt OtherVal = Other.getValue();
+  APSInt ThisVal = getValue();
+  APSInt OtherVal = Other.getValue();
   bool ThisSigned = Val.isSigned();
   bool OtherSigned = OtherVal.isSigned();
   unsigned OtherScale = Other.getScale();
@@ -113,14 +113,14 @@
 
 APFixedPoint APFixedPoint::getMax(const FixedPointSemantics ) {
   bool IsUnsigned = !Sema.isSigned();
-  auto Val = llvm::APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
+  auto Val = APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
   if (IsUnsigned && Sema.hasUnsignedPadding())
 Val = Val.lshr(1);
   return APFixedPoint(Val, Sema);
 }
 
 APFixedPoint APFixedPoint::getMin(const FixedPointSemantics ) {
-  auto Val = llvm::APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned());
+  auto Val = APSInt::getMinValue(Sema.getWidth(), 

[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-06 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D85191#2197550 , @bjope wrote:

> In D85191#2196863 , @rsmith wrote:
>
>> In D85191#2195923 , @ebevhan wrote:
>>
>>> In D85191#2193645 , @rsmith wrote:
>>>
> This is not ideal, since it makes the calculations char size dependent, 
> and breaks for sizes that are not a multiple of the char size.

 How can we have a non-bitfield member whose size is not a multiple of the 
 size of a char?
>>>
>>> Downstream, we have fixed-point types that are 24 bits large, but where the 
>>> char size is 16. The type then takes up 2 chars, where 8 of the bits are 
>>> padding. The only way in Clang to express that the width of the bit 
>>> representation of a type should be smaller than the number of chars it 
>>> takes up in memory -- and consequently, produce an `i24` in IR -- is to 
>>> return a non-charsize multiple from getTypeInfo.
>>
>> This violates the C and C++ language rules, which require the size of every 
>> type to be a multiple of the size of char. A type with 24 value bits and 8 
>> padding bits should report a type size of 32 bits, just like `bool` reports 
>> a size of `CHAR_BIT` bits despite having only 1 value bit, and x86_64 `long 
>> double` reports a type size of 128 bits despite having only 80 value bits.
>
> I don't see that it breaks the language rules. The sizeof result for the 24 
> bit type should be 2 in the target described by @ebevhan  (two 16-bit bytes). 
> But I imagine that without this patch it is reported as 24/16=1, right?

Yes, this is what's happening. The sizeof should be reported as 2 (32 bits), 
but isn't, because toCharUnitsFromBits always rounds down.

> So isn't the problem that toCharUnitsFromBits is rounding down when given a 
> bitsize that isn't a multiple of CHAR_BIT? Would it perhaps make sense to let 
> it round up instead?

The issue with toCharUnitsFromBits is that it's an inherently dangerous API. 
There could be cases where you want to round down, and cases where you want to 
round up. The function cannot know.

It could be better if toCharUnitsFromBits took an extra parameter that 
explicitly specifies the rounding, and if that parameter is set to a default 
(for unspecified rounding) and the amount passed is not a multiple of the char 
size, it asserts. This would make a lot of tests fail until all of the uses are 
corrected, though.

In D85191#2196863 , @rsmith wrote:

> In D85191#2195923 , @ebevhan wrote:
>
>> In D85191#2193645 , @rsmith wrote:
>>
 This is not ideal, since it makes the calculations char size dependent, 
 and breaks for sizes that are not a multiple of the char size.
>>>
>>> How can we have a non-bitfield member whose size is not a multiple of the 
>>> size of a char?
>>
>> Downstream, we have fixed-point types that are 24 bits large, but where the 
>> char size is 16. The type then takes up 2 chars, where 8 of the bits are 
>> padding. The only way in Clang to express that the width of the bit 
>> representation of a type should be smaller than the number of chars it takes 
>> up in memory -- and consequently, produce an `i24` in IR -- is to return a 
>> non-charsize multiple from getTypeInfo.
>
> This violates the C and C++ language rules, which require the size of every 
> type to be a multiple of the size of char. A type with 24 value bits and 8 
> padding bits should report a type size of 32 bits, just like `bool` reports a 
> size of `CHAR_BIT` bits despite having only 1 value bit, and x86_64 `long 
> double` reports a type size of 128 bits despite having only 80 value bits.

But this is the crux of the matter; if you aren't allowed to return 
non-char-sizes from getTypeInfo, then there's no way to specify via 
TargetInfo/getTypeInfo that the number of value bits of a type is less than the 
size in chars. That is, that a type is padded. And as your examples show, C 
does not disallow that.

In D85191#2197663 , @efriedma wrote:

>> If the intent is for getTypeInfo to always return sizes that are multiples 
>> of the char size, then the design should be inverted and getTypeInfo should 
>> simply be calling getTypeInfoInChars and multiply that result by the char 
>> size. But that isn't how it works.
>
> The reason it doesn't work this way is just that someone made the wrong 
> choice a decade ago, and nobody has spent the time to rewrite it since.  
> Patch welcome.

This does sound like a good thing to do, but it would be problematic downstream 
since it would completely prohibit the design that we're trying to use.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191


[PATCH] D62574: Initial draft of target-configurable address spaces.

2020-08-06 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D62574#2183294 , @Anastasia wrote:

> In D62574#2136423 , @ebevhan wrote:
>
>> It seems that D70605  attempted to 
>> ameliorate the issues that I observed (pointer-conversion doing too much), 
>> but it didn't manage to solve the problem fully.
>
> Can you explain what's left to be done?

My cache is a bit flushed on this at the moment but I do believe that if the 
issue described in D83325  is resolved, this 
patch should work.




Comment at: lib/Sema/SemaOverload.cpp:3171
+  // qualification conversion for disjoint address spaces make address space
+  // casts *work*?
   Qualifiers FromQuals = FromType.getQualifiers();

Anastasia wrote:
> ebevhan wrote:
> > Anastasia wrote:
> > > ebevhan wrote:
> > > > Anastasia wrote:
> > > > > Anastasia wrote:
> > > > > > ebevhan wrote:
> > > > > > > Anastasia wrote:
> > > > > > > > I guess if address spaces don't overlap we don't have a valid 
> > > > > > > > qualification conversion. This seems to align with the logic 
> > > > > > > > for cv. My guess is that none of the other conversions will be 
> > > > > > > > valid for non overlapping address spaces and the error will 
> > > > > > > > occur.
> > > > > > > > 
> > > > > > > > I think at this point we might not need to know if it's 
> > > > > > > > implicit or explicit? I believe we might have a separate check 
> > > > > > > > for this somewhere because it works for OpenCL. I don't know 
> > > > > > > > though if it might simplify the flow if we move this logic 
> > > > > > > > rather here.
> > > > > > > > 
> > > > > > > > The cv checks above seem to use `CStyle` flag. I am wondering 
> > > > > > > > if we could use it to detect implicit or explicit. Because we 
> > > > > > > > can only cast address space with C style cast at the moment.  
> > > > > > > > Although after adding `addrspace_cast` operator that will no 
> > > > > > > > longer be the only way.
> > > > > > > > I guess if address spaces don't overlap we don't have a valid 
> > > > > > > > qualification conversion. This seems to align with the logic 
> > > > > > > > for cv. My guess is that none of the other conversions will be 
> > > > > > > > valid for non overlapping address spaces and the error will 
> > > > > > > > occur.
> > > > > > > 
> > > > > > > Right. So the reasoning is that if the address spaces are 
> > > > > > > disjoint according to the overlap rule, then it cannot be 
> > > > > > > considered a qualification conversion.
> > > > > > > 
> > > > > > > But with the new hooks, it's possible for a target to allow 
> > > > > > > explicit conversion even if address spaces do not overlap 
> > > > > > > according to the rules. So even though there is no overlap, such 
> > > > > > > a conversion could still be a qualification conversion if it was 
> > > > > > > explicit (either via a c-style cast or an `addrspace_cast`). This 
> > > > > > > is in fact the default for all targets (see the patch in 
> > > > > > > TargetInfo.h).
> > > > > > > 
> > > > > > > I think I need a refresher on how the casts were meant to work; 
> > > > > > > were both `static_cast` and `reinterpret_cast` supposed to be 
> > > > > > > capable of implicit conversion (say, private -> generic) but only 
> > > > > > > `addrspace_cast` for the other direction (generic -> private)? Or 
> > > > > > > was `reinterpret_cast` supposed to fail in the first case?
> > > > > > Just as a summary:
> > > > > > 
> > > > > > - All casts should allow safe/implicit AS conversions i.e. 
> > > > > > `__private`/`__local`/`__global` -> `__generic` in OpenCL
> > > > > > - All casts except for C-style and `addrspace_cast` should disallow 
> > > > > > unsafe/explicit conversions i.e. generic -> 
> > > > > > `__private`/`__local`/`__global` in OpenCL
> > > > > > - All casts should disallow forbidden conversions with no address 
> > > > > > space overlap i.e. `__constant` <-> any other in OpenCL
> > > > > > 
> > > > > > In OpenCL overlapping logic is only used for explicit i.e. unsafe 
> > > > > > conversion. So it seems we might only need those conversions here 
> > > > > > then? 
> > > > > Did you have time to look into this?
> > > > I still don't really understand why the code checks for overlap here. 
> > > > Removing this check causes one test case to break, 
> > > > CodeGenCXX/address-space-cast.cpp. Specifically, this:
> > > > 
> > > > ```
> > > > #define __private__ __attribute__((address_space(5)))
> > > > 
> > > > void test_cast(char *gen_char_ptr, void *gen_void_ptr, int 
> > > > *gen_int_ptr) {
> > > >   __private__ void *priv_void_ptr = (__private__ void *)gen_char_ptr;
> > > > }
> > > > ```
> > > > 
> > > > It tries to resolve the C-style cast with TryAddressSpaceCast, but 
> > > > fails as the underlying pointee types (`char` and `void`) are 
> > > > different. Then it tries to do it 

[PATCH] D85312: [ADT] Move FixedPoint.h from Clang to LLVM.

2020-08-05 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
Herald added subscribers: llvm-commits, cfe-commits, dexonsmith, hiraditya, 
mgorny.
Herald added projects: clang, LLVM.
ebevhan requested review of this revision.

This patch moves FixedPointSemantics and APFixedPoint
from Clang to LLVM ADT.

This will make it easier to use the fixed-point
classes in LLVM for constructing an IR builder for
fixed-point and for reusing the APFixedPoint class
for constant evaluation purposes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85312

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/OptionalDiagnostic.h
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/unittests/Basic/CMakeLists.txt
  clang/unittests/Basic/FixedPointTest.cpp
  llvm/include/llvm/ADT/APFixedPoint.h
  llvm/lib/Support/APFixedPoint.cpp
  llvm/lib/Support/CMakeLists.txt
  llvm/unittests/ADT/APFixedPointTest.cpp
  llvm/unittests/ADT/CMakeLists.txt

Index: llvm/unittests/ADT/CMakeLists.txt
===
--- llvm/unittests/ADT/CMakeLists.txt
+++ llvm/unittests/ADT/CMakeLists.txt
@@ -4,6 +4,7 @@
 
 add_llvm_unittest(ADTTests
   AnyTest.cpp
+  APFixedPointTest.cpp
   APFloatTest.cpp
   APIntTest.cpp
   APSIntTest.cpp
Index: llvm/unittests/ADT/APFixedPointTest.cpp
===
--- llvm/unittests/ADT/APFixedPointTest.cpp
+++ llvm/unittests/ADT/APFixedPointTest.cpp
@@ -1,4 +1,4 @@
-//===- unittests/Basic/FixedPointTest.cpp -- fixed point number tests -===//
+//===- unittests/ADT/FixedPointTest.cpp -- fixed point number tests -===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,12 +6,12 @@
 //
 //===--===//
 
-#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APFixedPoint.h"
 #include "llvm/ADT/APSInt.h"
 #include "gtest/gtest.h"
 
-using clang::APFixedPoint;
-using clang::FixedPointSemantics;
+using llvm::APFixedPoint;
+using llvm::FixedPointSemantics;
 using llvm::APInt;
 using llvm::APSInt;
 
Index: llvm/lib/Support/CMakeLists.txt
===
--- llvm/lib/Support/CMakeLists.txt
+++ llvm/lib/Support/CMakeLists.txt
@@ -56,6 +56,7 @@
   ABIBreak.cpp
   ARMTargetParser.cpp
   AMDGPUMetadata.cpp
+  APFixedPoint.cpp
   APFloat.cpp
   APInt.cpp
   APSInt.cpp
Index: llvm/lib/Support/APFixedPoint.cpp
===
--- llvm/lib/Support/APFixedPoint.cpp
+++ llvm/lib/Support/APFixedPoint.cpp
@@ -1,4 +1,4 @@
-//===- FixedPoint.cpp - Fixed point constant handling ---*- C++ -*-===//
+//===- APFixedPoint.cpp - Fixed point constant handling -*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -11,13 +11,13 @@
 //
 //===--===//
 
-#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APFixedPoint.h"
 
-namespace clang {
+namespace llvm {
 
 APFixedPoint APFixedPoint::convert(const FixedPointSemantics ,
bool *Overflow) const {
-  llvm::APSInt NewVal = Val;
+  APSInt NewVal = Val;
   unsigned DstWidth = DstSema.getWidth();
   unsigned DstScale = DstSema.getScale();
   bool Upscaling = DstScale > getScale();
@@ -31,10 +31,10 @@
 NewVal >>= (getScale() - DstScale);
   }
 
-  auto Mask = llvm::APInt::getBitsSetFrom(
+  auto Mask = APInt::getBitsSetFrom(
   NewVal.getBitWidth(),
   std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
-  llvm::APInt Masked(NewVal & Mask);
+  APInt Masked(NewVal & Mask);
 
   // Change in the bits above the sign
   if (!(Masked == Mask || Masked == 0)) {
@@ -61,8 +61,8 @@
 }
 
 int APFixedPoint::compare(const APFixedPoint ) const {
-  llvm::APSInt ThisVal = getValue();
-  llvm::APSInt OtherVal = Other.getValue();
+  APSInt ThisVal = getValue();
+  APSInt OtherVal = Other.getValue();
   bool ThisSigned = Val.isSigned();
   bool OtherSigned = OtherVal.isSigned();
   unsigned OtherScale = Other.getScale();
@@ -113,14 +113,14 @@
 
 APFixedPoint APFixedPoint::getMax(const FixedPointSemantics ) {
   bool IsUnsigned = !Sema.isSigned();
-  auto Val = llvm::APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
+  auto Val = APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
   if 

[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-05 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1841
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;

ebevhan wrote:
> Xiangling_L wrote:
> > In most cases, `getTypeInfoInChars` invokes `getTypeInfo` underneath. So to 
> > make people be careful about this, I would suggest to leave a comment 
> > explaining/claiming we have to call `getTypeInfoInChars` here. And also 
> > maybe adding a testcase to guard the scenario you were talking about would 
> > be helpful to prevent someone to use `getTypeInfo` here in the future.
> I can do that.
> 
> I honestly don't think it would be a bad idea to add an assertion to 
> toCharUnitsFromBits that checks for non-bytesize-multiple amounts. I wonder 
> how much would fail if I did that, though.
Oh, I guess I only really replied to the first part about adding a comment 
here... I'm not sure I can make a test case for this, since I don't think 
there's anything that triggers this upstream.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

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


[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-05 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D85191#2193645 , @rsmith wrote:

>> This is not ideal, since it makes the calculations char size dependent, and 
>> breaks for sizes that are not a multiple of the char size.
>
> How can we have a non-bitfield member whose size is not a multiple of the 
> size of a char?

Downstream, we have fixed-point types that are 24 bits large, but where the 
char size is 16. The type then takes up 2 chars, where 8 of the bits are 
padding. The only way in Clang to express that the width of the bit 
representation of a type should be smaller than the number of chars it takes up 
in memory -- and consequently, produce an `i24` in IR -- is to return a 
non-charsize multiple from getTypeInfo.

We did it this way because it was possible. If the intent is for getTypeInfo to 
always return sizes that are multiples of the char size, then the design should 
be inverted and getTypeInfo should simply be calling getTypeInfoInChars and 
multiply that result by the char size. But that isn't how it works.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

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


[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-04 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1841
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;

Xiangling_L wrote:
> In most cases, `getTypeInfoInChars` invokes `getTypeInfo` underneath. So to 
> make people be careful about this, I would suggest to leave a comment 
> explaining/claiming we have to call `getTypeInfoInChars` here. And also maybe 
> adding a testcase to guard the scenario you were talking about would be 
> helpful to prevent someone to use `getTypeInfo` here in the future.
I can do that.

I honestly don't think it would be a bad idea to add an assertion to 
toCharUnitsFromBits that checks for non-bytesize-multiple amounts. I wonder how 
much would fail if I did that, though.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

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


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-08-04 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

I submitted a patch with the changes at D85191 
.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

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


[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-04 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: jasonliu, efriedma.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
ebevhan requested review of this revision.

In D79719 , LayoutField was refactored to 
fetch the size of field
types in bits and then convert to chars, rather than fetching
them in chars directly. This is not ideal, since it makes the
calculations char size dependent, and breaks for sizes that
are not a multiple of the char size.

This patch changes it to use getTypeInfoInChars instead of
getTypeInfo.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85191

Files:
  clang/lib/AST/RecordLayoutBuilder.cpp


Index: clang/lib/AST/RecordLayoutBuilder.cpp
===
--- clang/lib/AST/RecordLayoutBuilder.cpp
+++ clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1838,14 +1838,13 @@
   CharUnits EffectiveFieldSize;
 
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;
 // Flexible array members don't have any size, but they have to be
 // aligned appropriately for their element type.
 EffectiveFieldSize = FieldSize =
-IsIncompleteArrayType ? CharUnits::Zero()
-  : Context.toCharUnitsFromBits(TI.Width);
-AlignIsRequired = TI.AlignIsRequired;
+IsIncompleteArrayType ? CharUnits::Zero() : TI.first;
+AlignIsRequired = Context.getTypeInfo(D->getType()).AlignIsRequired;
   };
 
   if (D->getType()->isIncompleteArrayType()) {


Index: clang/lib/AST/RecordLayoutBuilder.cpp
===
--- clang/lib/AST/RecordLayoutBuilder.cpp
+++ clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1838,14 +1838,13 @@
   CharUnits EffectiveFieldSize;
 
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;
 // Flexible array members don't have any size, but they have to be
 // aligned appropriately for their element type.
 EffectiveFieldSize = FieldSize =
-IsIncompleteArrayType ? CharUnits::Zero()
-  : Context.toCharUnitsFromBits(TI.Width);
-AlignIsRequired = TI.AlignIsRequired;
+IsIncompleteArrayType ? CharUnits::Zero() : TI.first;
+AlignIsRequired = Context.getTypeInfo(D->getType()).AlignIsRequired;
   };
 
   if (D->getType()->isIncompleteArrayType()) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83325: [Sema] Be more thorough when unpacking the AS-qualified pointee for a pointer conversion.

2020-08-03 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D83325#2170813 , @rjmccall wrote:

> `removeAddrSpaceQualType` should guarantee that it removes the address space 
> qualifier; you shouldn't need to do something special here.  That means it 
> needs to iteratively desugar and collect qualifiers as long as the type is 
> still address-space-qualified.

Well, from what I observed, it is not doing that, so perhaps that's what needs 
to be addressed. That's a bit more involved, though.

We will still end up stripping all sugar up until we hit the AS-qualification, 
though. Unless we are supposed to reconstitute the sugared type with the AS 
altered somehow?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83325/new/

https://reviews.llvm.org/D83325

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


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-08-03 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1778
-std::pair FieldInfo =
-  Context.getTypeInfoInChars(D->getType());
-EffectiveFieldSize = FieldSize = FieldInfo.first;

It seems that in factoring out this to setDeclInfo, it was changed from using 
getTypeInfoInChars to using getTypeInfo+toCharUnitsFromBits. This is causing 
some downstream issues for us with non-bytesize-multiple types.

Changing setDeclInfo to use the original function instead seems to work without 
issues. Would it be acceptable to change this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

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


[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-07-16 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D82663#2153834 , @rjmccall wrote:

> I don't understand.  The problem statement as I understood it is that using 
> unsigned intrinsics to do unsigned-with-padding operations is leading to poor 
> code-gen, so you want to start using signed intrinsics, which you can safely 
> do because unsigned-with-padding types are intended to be exactly signed 
> types with a dynamic range restriction to non-negative values.  The result of 
> that operation is still logically an unsigned-with-padding value; there's no 
> need to return back a modified semantic that says that the result is really a 
> signed value because it's *not* really a signed value, you're just computing 
> it a different way.  I also don't understand why you think need a modified 
> semantics value in the first place as opposed to just using a more complex 
> condition when deciding which intrinsics to use.


Well, it's not just about intrinsics. For saturating operations, the common 
semantic width is currently narrowed by one bit to get the correct saturating 
behavior on the operation afterwards. This affects the conversion to the common 
semantic, since the type will be one bit narrower.

But I realize now that it probably doesn't matter if we simply don't do that 
narrowing when constructing the common semantic. That way it will always have 
the right width and we can just do as you say and select the right intrinsic 
based on the padding bit information. Alright, that should probably work.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663



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


[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-07-15 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D82663#2144551 , @rjmccall wrote:

> In D82663#2144219 , @ebevhan wrote:
>
> > In D82663#2142426 , @rjmccall 
> > wrote:
> >
> > > Would it be sensible to use a technical design more like what the matrix 
> > > folks are doing, where LLVM provides a small interface for emitting 
> > > operations with various semantics?  FixedPointSemantics would move to 
> > > that header, and Clang would just call into it.  That way you get a lot 
> > > more flexibility in how you generate code, and the Clang IRGen logic is 
> > > still transparently correct.  If you want to add intrinsics or otherwise 
> > > change the IR patterns used for various operations, you don't have to 
> > > rewrite a bunch of Clang IRGen logic every time, you just have to update 
> > > the tests.  It'd then be pretty straightforward to have internal helper 
> > > functions in that interface for computing things like whether you should 
> > > use signed or unsigned intrinsics given the desired FixedPointSemantics.
> >
> >
> > This seems like a reasonable thing to do for other reasons as well. Also 
> > moving the actual APFixedPoint class to LLVM would make it easier to reuse 
> > the fixedpoint calculation code for constant folding in LLVM, for example.
>
>
> Just to say "I told you so", I'm pretty sure I told people this would happen. 
> :)


Well, transferring the fixed point concept over to LLVM felt like it would 
happen sooner or later, for the reasons we've discussed here as well as for 
other reasons. I'm not sure that the discrepancies between the Clang and LLVM 
semantics were predicted to be the driving factor behind the move, though.

>>> My interest here is mainly in (1) keeping IRGen's logic as obviously 
>>> correct as possible, (2) not hard-coding a bunch of things that really feel 
>>> like workarounds for backend limitations, and (3) not complicating core 
>>> abstractions like FixedPointSemantics with unnecessary extra rules for 
>>> appropriate use, like having to pass an extra "for codegen" flag to get 
>>> optimal codegen.  If IRGen can just pass down the high-level semantics it 
>>> wants to some library that will make intelligent decisions about how to 
>>> emit IR, that seems best.
>> 
>> Just to clarify something here; would the interface in LLVM still emit 
>> signed operations for unsigned with padding?
> 
> If that's the best IR pattern to emit, yes.
> 
>> If so, why does dealing with the padding bit detail in LLVM rather than 
>> Clang make more sense?
> 
> Because frontends should be able to just say "I have a value of a type with 
> these semantics, I need you to do these operations, go do them".  The whole 
> purpose of this interface would be to go down a level of abstraction by 
> picking the best IR to represent those operations.
> 
> Maybe we're not in agreement about what this interface looks like — I'm 
> imagining something like
> 
>   struct FixedPointEmitter {
> IRBuilder 
> FixedPointEmitter(IRBuilder ) : B(B) {}
>   
> Value *convert(Value *src, FixedPointSemantics srcSemantics, 
> FixedPointSemantics destSemantics);
> Value *add(Value *lhs, FixedPointSemantics lhsSemantics, Value *rhs, 
> FixedPointSemantics rhsSemantics)
>   };

I've spent some time going over this and trying to figure out how it would 
work. I think the interface seems fine on the surface, but I don't see how it 
directly solves the issues at hand. Regardless of whether this is factored out 
to LLVM, we still have the issue that we have to massage the semantic 
**somewhere** in order to get different behavior for certain kinds of semantics 
during binop codegen.

Since the binop functions take two different semantics, it must perform 
conversions internally to get the values to match up before the operation. This 
would probably just be to the common semantic between the two, and it would 
then return the Value in the common semantic (since we don't know what to 
convert back to).

In order for the binop functions to have special behavior for padded unsigned, 
they would need to modify the common semantic internally in order to get the 
conversion right. This means that the semantic of the returned Value will 
**not** be what you would normally get from `getCommonSemantic`, so the caller 
of the function will have no idea what the semantic of the returned value is.

Even if we only treat it as an internal detail of the binop functions and never 
expose this 'modified' semantic externally, this means we might end up with 
superfluous operations since (for padded saturating unsigned) we will be forced 
to trunc the result by one bit to match the real common semantic before we 
return.

The only solution I can think of is to also return the semantic of the result 
Value, which feels like it makes the interface pretty bulky.

I can start off by moving APFixedPoint and 

[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-07-10 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D82663#2142426 , @rjmccall wrote:

> Would it be sensible to use a technical design more like what the matrix 
> folks are doing, where LLVM provides a small interface for emitting 
> operations with various semantics?  FixedPointSemantics would move to that 
> header, and Clang would just call into it.  That way you get a lot more 
> flexibility in how you generate code, and the Clang IRGen logic is still 
> transparently correct.  If you want to add intrinsics or otherwise change the 
> IR patterns used for various operations, you don't have to rewrite a bunch of 
> Clang IRGen logic every time, you just have to update the tests.  It'd then 
> be pretty straightforward to have internal helper functions in that interface 
> for computing things like whether you should use signed or unsigned 
> intrinsics given the desired FixedPointSemantics.


This seems like a reasonable thing to do for other reasons as well. Also moving 
the actual APFixedPoint class to LLVM would make it easier to reuse the 
fixedpoint calculation code for constant folding in LLVM, for example.

> My interest here is mainly in (1) keeping IRGen's logic as obviously correct 
> as possible, (2) not hard-coding a bunch of things that really feel like 
> workarounds for backend limitations, and (3) not complicating core 
> abstractions like FixedPointSemantics with unnecessary extra rules for 
> appropriate use, like having to pass an extra "for codegen" flag to get 
> optimal codegen.  If IRGen can just pass down the high-level semantics it 
> wants to some library that will make intelligent decisions about how to emit 
> IR, that seems best.

Just to clarify something here; would the interface in LLVM still emit signed 
operations for unsigned with padding?  If so, why does dealing with the padding 
bit detail in LLVM rather than Clang make more sense? The regular IRBuilder is 
relatively straightforward in its behavior.  I suspect that if anything, LLVM 
would be equally unwilling to take to take IRBuilder patches that emitted 
signed intrinsics for certain unsigned operations only due to a detail in 
Embedded-C's implementation of fixedpoint support.

I could remove the special behavior from FixedPointSemantics and only deal with 
it in EmitFixedPointBinOp instead. I agree that the FixedPointSemantics 
interface is muddied by the extra parameter.
Unless I alter the semantics object it might make EmitFixedPointBinOp rather 
messy, though.

---

Regarding backend limitations, I guess I could propose an alternate solution. 
If we change FixedPointSemantics to strip the padding bit for both saturating 
and nonsaturating operations, it may be possible to detect in isel that the 
corresponding signed operation could be used instead when we promote the type 
of an unsigned one. For example, if we emit i15 umul.fix scale 15, we could 
tell in lowering that i16 smul.fix scale 15 is legal and use that instead. Same 
for all the other intrinsics, including the non-fixedpoint uadd.sat/usub.sat.

The issue with this approach (which is why I didn't really want to do it) is 
that it's not testable. No upstream target has these intrinsics marked as 
legal. I doubt anyone would accept a patch with no tests.
It may also be less efficient than just emitting the signed operations in the 
first place, because we are forced to trunc and zext in IR before and after 
every operation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663



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


[PATCH] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-07-10 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan marked an inline comment as done.
ebevhan added inline comments.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:3857
+
+  // TODO: This misses out on the sanitizer check below.
+  if (Ops.isFixedPointOp())

leonardchan wrote:
> I don't suppose you could file a bug for this and CC me on it so we can 
> remember to do this sometime after this lands?
I could do that. I guess the issue is larger than just this; I think other ops 
do not get proper UBSan checks for fixedpoint. So the ticket would probably 
entail supporting UBSan for fixedpoint, which is maybe a bit larger in scope.



Comment at: clang/test/Frontend/fixed_point_compound.c:388-390
+  // UNSIGNED-NEXT: [[TMP7:%.*]] = icmp slt i16 [[TMP6]], 0
+  // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP7]], i16 0, i16 [[TMP6]]
+  // UNSIGNED-NEXT: store i16 [[SATMIN]], i16* @suf, align 2

leonardchan wrote:
> I'm assuming these checks are also a result of D82663? I don't think for the 
> padding case, we should need to do the compare and select if we're already 
> using the signed sat intrinsic. But I'm guessing it might make the 
> implementation more complicated by having to check for this.
> 
> If this codegen comes from the `EmitFixedPointConversion` at the end of 
> `EmitFixedPointBinOp`, perhaps it might be worthwhile adding a parameter in 
> `EmitFixedPointConversion` to indicate that we shouldn't emit this. I think 
> there's some cases in D82663 also where we might not need to do these checks 
> afterwards with other operations like with:
> 
> ```
> // UNSIGNED-NEXT: [[TMP25:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP22]], 
> i16 32767)
> // UNSIGNED-NEXT: [[TMP26:%.*]] = icmp slt i16 [[TMP25]], 0
> // UNSIGNED-NEXT: [[SATMIN2:%.*]] = select i1 [[TMP26]], i16 0, i16 [[TMP25]]
> // UNSIGNED-NEXT: store i16 [[SATMIN2]], i16* @suf, align 2
> ```
Yes, this is correct. And it is also correct that in the case of shift (and 
other operations) it is not necessary. It was just more elegant to make the 
common semantic signed and the result semantic unsigned and get the clamp 
automatically.

I think the alternative is to handle the signedness of ops separate from the 
semantic during codegen and then emit a clamp manually per-operation instead of 
relying on the result conversion.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83294/new/

https://reviews.llvm.org/D83294



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


[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-07-09 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D82663#2140507 , @leonardchan wrote:

> In D82663#2130355 , @ebevhan wrote:
>
> > Well, it's not so much as adding the bit, but adding the information that 
> > the bit exists. That means either new intrinsics for all of the operations, 
> > or adding flags to the existing ones. That's a fair bit of added 
> > complexity. Also,  +  would do virtually 
> > the exact same thing as the new unsigned-with-padding operations, so the 
> > utility of adding all of it is a bit questionable.
>
>
> Could the work involved just be adding the flags, then in 
> `llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp` for unsigned 
> operations, choosing between the signed/unsigned underlying `ISD` when 
> lowering intrinsics to DAG? I think you could just pass the padding bit to 
> `FixedPointIntrinsicToOpcode` and handle it from there. This is just off the 
> top of my head so I could be missing other things.


It wouldn't just be restricted to fixed-point intrinsics, though. It would have 
to be added to intrinsics like uadd.sat and usub.sat as well, which aren't 
really tied to fixed-point at all. Changing the semantics of those intrinsics 
would be unfortunate for targets that have started using them for their own 
instructions. I don't really think it's an option to move the padding semantic 
info into the IR; the intrinsic interface is fairly lean, and I think keeping 
it that way is a good idea.

I could change the emission to not be so heavy-handed and only use signed 
operations for the intrinsics, rather than everything. That makes 
EmitFixedPointBinOp a bit messier, though.




Comment at: clang/lib/Basic/FixedPoint.cpp:143-158
+  // For codegen purposes, make unsigned with padding semantics signed instead.
+  // This means that we will generate signed operations. The result from these
+  // operations is defined, since ending up with a negative result is undefined
+  // for nonsaturating semantics, and for saturating semantics we will
+  // perform a clamp-to-zero in the last conversion to result semantics (since
+  // we are going from saturating signed to saturating unsigned).
+  //

leonardchan wrote:
> If this is exclusively for codegen purposes with binary operations, would it 
> be clearer to move this to `EmitFixedPointBinOp`? If 
> `UnsignedPaddingIsSigned` doesn't need to be used for stuff like constant 
> evaluation, it might be clearer not to provide it for everyone.
FixedPointSemantics is immutable except for saturation, unfortunately. I'd end 
up having to reconstruct the semantics object from scratch immediately after 
calling getCommonSemantics.



Comment at: clang/test/Frontend/fixed_point_add.c:290-294
+  // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
+  // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
+  // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
+  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[USA_EXT]], [[I]]
+  // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16

leonardchan wrote:
> If this is a workaround for not being able to convey the padding bit to LLVM 
> intrinsics, I think we should only limit changes to instances we would use 
> intrinsics.
I suppose this makes sense, but the logic will be a bit more convoluted in that 
case.

It is true that in most cases, the clamp-to-zero resulting from the 
signed->unsigned conversion at the end isn't even necessary. For addition, 
multiplication, division and shift, the result of positive operands can never 
become negative, so there's no point to the clamp.

It just felt more general to do it for all of them instead of littering 
EmitFixedPointBinOp with special cases. But perhaps it would be better to deal 
with each case individually instead. Still feels like that would make the 
implementation less clean.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663



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


[PATCH] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-07-09 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan marked an inline comment as done.
ebevhan added inline comments.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:3603-3604
   auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy);
-  auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema, true);
+  auto CommonFixedSema = LHSFixedSema.getCommonSemantics(
+  IsShift ? LHSFixedSema : RHSFixedSema, true);
 

leonardchan wrote:
> Could this instead be:
> 
> ```
> auto CommonFixedSema = IsShift ? LHSFixedSema : 
> LHSFixedSema.getCommonSemantics(RHSFixedSema, true);
> ```
> 
> 
In theory, yes, but I'm sort of piggybacking off of D82663, and for the 
signedness to be correct we need to get the 'common' semantic even in the shift 
case.



Comment at: clang/test/Frontend/fixed_point_compound.c:384
+  // CHECK-NEXT:[[TMP4:%.*]] = load i16, i16* @suf, align 2
+  // CHECK-NEXT:[[TMP5:%.*]] = trunc i32 [[TMP3]] to i16
+  // SIGNED-NEXT:   [[TMP6:%.*]] = call i16 @llvm.ushl.sat.i16(i16 [[TMP4]], 
i16 [[TMP5]])

leonardchan wrote:
> This seems very unlikely, but if `i` in this case was a value at least 2^16, 
> the upper half would be cut off and we'd potentially shift by an improper 
> amount for some values of `i` when we should actually clamp to the max value. 
> We should probably still   find the common semantics for both sides if we're 
> doing a shift.
If the value is so large to be cut off by that truncation then the value is 
greater than the bitwidth, which is UB. So I don't think it's an issue.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83294/new/

https://reviews.llvm.org/D83294



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


[PATCH] D62574: Initial draft of target-configurable address spaces.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 276163.
ebevhan added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574

Files:
  clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/CanonicalType.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaFixItUtils.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/CodeGenCXX/address-space-cast.cpp
  clang/test/Sema/address_space_print_macro.c
  clang/test/Sema/address_spaces.c

Index: clang/test/Sema/address_spaces.c
===
--- clang/test/Sema/address_spaces.c
+++ clang/test/Sema/address_spaces.c
@@ -71,7 +71,8 @@
 
 // Clang extension doesn't forbid operations on pointers to different address spaces.
 char* cmp(_AS1 char *x,  _AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}} \
+// expected-error{{comparison between  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
 }
 
 char *sub(_AS1 char *x, _AS2 char *y) {
Index: clang/test/Sema/address_space_print_macro.c
===
--- clang/test/Sema/address_space_print_macro.c
+++ clang/test/Sema/address_space_print_macro.c
@@ -14,7 +14,8 @@
 }
 
 char *cmp(AS1 char *x, AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}} \
+// expected-error{{comparison between  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
 }
 
 __attribute__((address_space(1))) char test_array[10];
Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -37,8 +37,9 @@
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
   priv_void_ptr = (__private__ void *)gen_void_ptr;
 
-  // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
-  // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = addrspacecast i8* %[[cast]] to i8 addrspace(5)*
+  // CHECK-NEXT: store i8 addrspace(5)* %[[cast2]]
   priv_void_ptr = (__private__ void *)gen_int_ptr;
 
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
@@ -65,8 +66,9 @@
   // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
   func_pvoid((__private__ void *)gen_void_ptr);
 
-  // CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
-  // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
+  // CHECK: %[[cast:.*]] = bitcast i32* %{{.*}} to i8*
+  // CHECK-NEXT: %[[cast2:.*]] = addrspacecast i8* %[[cast]] to i8 addrspace(5)*
+  // CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast2]])
   func_pvoid((__private__ void *)gen_int_ptr);
 
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -1457,7 +1457,8 @@
   // C++ [temp.deduct.conv]p4:
   //   If the original A is a reference type, A can be more cv-qualified
   //   than the deduced A
-  if (!Arg.getQualifiers().compatiblyIncludes(Param.getQualifiers()))
+  if (!S.Context.compatiblyIncludes(Arg.getQualifiers(),
+Param.getQualifiers()))
 return Sema::TDK_NonDeducedMismatch;
 
   // Strip out all extra qualifiers from the argument to figure out the
@@ -3389,7 +3390,7 @@
 
 if 

[PATCH] D62574: Initial draft of target-configurable address spaces.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D62574#2136553 , @danilaml wrote:

> In D62574#2135662 , @ebevhan wrote:
>
> > It's generally not safe to alter address spaces below the top level. C is 
> > just very permissive about it.
>
>
> Isn't that also true for the top-level casts? Unless when it is. And the 
> target should know when it's safe or not. It's just that for non top-level 
> casts there is added condition that casts are noop (i.e. don't change the bit 
> pattern of the pointer). At least that's how I see it.


Yes, I see what you mean. I think that the default assumption in Clang at the 
moment is that it is not safe to do so, hence the current design. Not that 
there are many targets that use address spaces, so perhaps that assumption is 
too conservative for ones that do downstream.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574



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


[PATCH] D83325: [Sema] Be more thorough when unpacking the AS-qualified pointee for a pointer conversion.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: svenvh, rjmccall.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When performing a pointer conversion as the second conversion
in an SCS where the conversion is a derived-to-base and the
address space of the type wants to change, we need to defer
the address space conversion until the third step since we
must perform two ImplicitCasts at once otherwise. We do this
by repacking the destination type we give to
CheckPointerConversion with the source address space.

However, this repacking does not take sugar into account, so
if the address spaces in question are hidden behind nodes like
AttributedType or MacroQualifiedType, it won't work properly.
Also, if the source AS is Default, getAddrSpaceQualType fails,
since it cannot apply a Default AS.

Use the canonical destination type to ensure that we strip
any sugar that would get in the way.

I'm unsure if this is currently broken upstream without other
patches to exploit the behavior, but the fix seems to work for
the use case in D62574 .


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83325

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/CodeGenCXX/address-space-cast.cpp


Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -6,6 +6,16 @@
 void func_pvoid(__private__ void *x);
 void func_pint(__private__ int *x);
 
+class Base {
+};
+
+class Derived : public Base {
+};
+
+void fn(Derived *p) {
+  __private__ Base *b = (__private__ Base *)p;
+}
+
 void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4237,14 +4237,21 @@
 }
 
 // Defer address space conversion to the third conversion.
+// FIXME: If PerformImplicitConversion did not try to pass the final
+// destination type to every conversion function in here, this would not
+// be necessary since the address space conversion would be handled as
+// a qualification conversion instead.
 QualType FromPteeType = From->getType()->getPointeeType();
 QualType ToPteeType = ToType->getPointeeType();
 QualType NewToType = ToType;
 if (!FromPteeType.isNull() && !ToPteeType.isNull() &&
 FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) {
-  NewToType = Context.removeAddrSpaceQualType(ToPteeType);
-  NewToType = Context.getAddrSpaceQualType(NewToType,
-   FromPteeType.getAddressSpace());
+  NewToType =
+  Context.removeAddrSpaceQualType(ToPteeType.getCanonicalType());
+  if (FromPteeType.getAddressSpace() != LangAS::Default)
+NewToType = Context.getAddrSpaceQualType(
+NewToType, FromPteeType.getAddressSpace());
+
   if (ToType->isObjCObjectPointerType())
 NewToType = Context.getObjCObjectPointerType(NewToType);
   else if (ToType->isBlockPointerType())


Index: clang/test/CodeGenCXX/address-space-cast.cpp
===
--- clang/test/CodeGenCXX/address-space-cast.cpp
+++ clang/test/CodeGenCXX/address-space-cast.cpp
@@ -6,6 +6,16 @@
 void func_pvoid(__private__ void *x);
 void func_pint(__private__ int *x);
 
+class Base {
+};
+
+class Derived : public Base {
+};
+
+void fn(Derived *p) {
+  __private__ Base *b = (__private__ Base *)p;
+}
+
 void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
   // CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
   // CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4237,14 +4237,21 @@
 }
 
 // Defer address space conversion to the third conversion.
+// FIXME: If PerformImplicitConversion did not try to pass the final
+// destination type to every conversion function in here, this would not
+// be necessary since the address space conversion would be handled as
+// a qualification conversion instead.
 QualType FromPteeType = From->getType()->getPointeeType();
 QualType ToPteeType = ToType->getPointeeType();
 QualType NewToType = ToType;
 if (!FromPteeType.isNull() && !ToPteeType.isNull() &&
 FromPteeType.getAddressSpace() != ToPteeType.getAddressSpace()) {
-  NewToType = Context.removeAddrSpaceQualType(ToPteeType);
-  NewToType = Context.getAddrSpaceQualType(NewToType,
-  

[PATCH] D70605: [OpenCL] Fix address space for implicit conversion (PR43145)

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:4106
+  NewToType = Context.getAddrSpaceQualType(NewToType,
+   FromPteeType.getAddressSpace());
+  if (ToType->isObjCObjectPointerType())

svenvh wrote:
> ebevhan wrote:
> > I don't think this will manage to properly repack the type if it's hidden 
> > behind enough sugar. When I enable C++ address space conversions in a 
> > non-OpenCL context, this breaks the derived-to-base example in 
> > CodeGenCXX/address-space-cast.cpp.
> > 
> > IsPointerConversion doesn't have an issue with this since it reconstructs 
> > the destination type with the appropriate qualifiers through 
> > BuildSimilarlyQualifiedPointerType.
> > 
> > Wouldn't it make more sense to have *PointerConversion only handle the 
> > derived-to-base and leave the address space conversion to 
> > *QualificationConversion?
> > Wouldn't it make more sense to have *PointerConversion only handle the 
> > derived-to-base and leave the address space conversion to 
> > *QualificationConversion?
> 
> I didn't have a thorough look to understand all implications of that, but 
> maybe it's worth trying.  Not sure I'll be able to follow up on this any time 
> soon, would you be able to give it a try?
I'll see if I can have a look, or at least make the existing implementation a 
bit more thorough.

To be entirely honest, I feel a bit stupid right now: I forgot that **I** added 
the derived-to-base test in the test case I mentioned in my local experimental 
branch, so of course you wouldn't be able to use that as a baseline. Oops!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70605/new/

https://reviews.llvm.org/D70605



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


[PATCH] D62574: Initial draft of target-configurable address spaces.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

It seems that D70605  attempted to ameliorate 
the issues that I observed (pointer-conversion doing too much), but it didn't 
manage to solve the problem fully.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574



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


[PATCH] D70605: [OpenCL] Fix address space for implicit conversion (PR43145)

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

I know this is some really late feedback on this patch. I struck upon some 
issues with while rebasing D62574 .




Comment at: clang/lib/Sema/SemaExprCXX.cpp:4106
+  NewToType = Context.getAddrSpaceQualType(NewToType,
+   FromPteeType.getAddressSpace());
+  if (ToType->isObjCObjectPointerType())

I don't think this will manage to properly repack the type if it's hidden 
behind enough sugar. When I enable C++ address space conversions in a 
non-OpenCL context, this breaks the derived-to-base example in 
CodeGenCXX/address-space-cast.cpp.

IsPointerConversion doesn't have an issue with this since it reconstructs the 
destination type with the appropriate qualifiers through 
BuildSimilarlyQualifiedPointerType.

Wouldn't it make more sense to have *PointerConversion only handle the 
derived-to-base and leave the address space conversion to 
*QualificationConversion?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70605/new/

https://reviews.llvm.org/D70605



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


[PATCH] D62574: Initial draft of target-configurable address spaces.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a subscriber: danilaml.
ebevhan added a comment.

In D62574#2133160 , @danilaml wrote:

> What are the remaining roadblocks left before this patch can be merged? I'm 
> interested in having a target-specific way to define the allowed 
> explicit/implicit address space conversions.


This has been on my backburner for various reasons, so I'm not sure what the 
status is any more. I could try rebasing it and seeing where things are at.
I don't believe that the issues I mentioned last have been dealt with, though.

This was also only an initial concept. I think that even once all the issues 
with the patch have been ironed out, it would require a round of wider review 
since it's a fairly hefty API change.

> Also, it appears that currently whether implicit casts between pointers of 
> different AS are allowed is determined by the superset relations only, 
> however https://reviews.llvm.org/D73360 introduced another (openCL-specific) 
> variable into the mix: whether the conversion is a top level or not. IMHO, 
> this should also be configured by the target, although I'm not sure whether 
> it needs a separate hook (isBitcastNoop or similar?) or it needs to check the 
> legality of the implicit casts differently.

That patch only seems to apply to C++, I think? The restriction on 
top-level-only conversion should be correct, at least in C++.
It's generally not safe to alter address spaces below the top level. C is just 
very permissive about it.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62574/new/

https://reviews.llvm.org/D62574



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


[PATCH] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: rjmccall, leonardchan, bjope.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch adds codegen to Clang for fixed-point shift
operations.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83294

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_shift.c

Index: clang/test/Frontend/fixed_point_shift.c
===
--- clang/test/Frontend/fixed_point_shift.c
+++ clang/test/Frontend/fixed_point_shift.c
@@ -35,3 +35,361 @@
 _Sat unsigned _Accum sua_const2 = (_Sat unsigned _Accum)128.0uk << 10;
 // SIGNED-DAG:   @sua_const2 = {{.*}}global i32 -1
 // UNSIGNED-DAG: @sua_const2 = {{.*}}global i32 2147483647
+
+// CHECK-LABEL: @SignedLeftShift(
+void SignedLeftShift() {
+  short _Accum sa;
+  _Accum a;
+  long _Accum la;
+
+  short _Fract sf;
+  _Fract f;
+  long _Fract lf;
+
+  int i;
+  unsigned u;
+
+  // CHECK: [[TMP0:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:[[TMP1:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
+  // CHECK-NEXT:[[TMP3:%.*]] = shl i16 [[TMP0]], [[TMP2]]
+  // CHECK-NEXT:store i16 [[TMP3]], i16* %sa, align 2
+  sa = sa << i;
+
+  // CHECK: [[TMP4:%.*]] = load i32, i32* %a, align 4
+  // CHECK-NEXT:[[TMP5:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP6:%.*]] = shl i32 [[TMP4]], [[TMP5]]
+  // CHECK-NEXT:store i32 [[TMP6]], i32* %a, align 4
+  a = a << i;
+
+  // CHECK: [[TMP7:%.*]] = load i64, i64* %la, align 8
+  // CHECK-NEXT:[[TMP8:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP9:%.*]] = zext i32 [[TMP8]] to i64
+  // CHECK-NEXT:[[TMP10:%.*]] = shl i64 [[TMP7]], [[TMP9]]
+  // CHECK-NEXT:store i64 [[TMP10]], i64* %la, align 8
+  la = la << i;
+
+  // CHECK: [[TMP11:%.*]] = load i8, i8* %sf, align 1
+  // CHECK-NEXT:[[TMP12:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP13:%.*]] = trunc i32 [[TMP12]] to i8
+  // CHECK-NEXT:[[TMP14:%.*]] = shl i8 [[TMP11]], [[TMP13]]
+  // CHECK-NEXT:store i8 [[TMP14]], i8* %sf, align 1
+  sf = sf << i;
+
+  // CHECK: [[TMP15:%.*]] = load i16, i16* %f, align 2
+  // CHECK-NEXT:[[TMP16:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP17:%.*]] = trunc i32 [[TMP16]] to i16
+  // CHECK-NEXT:[[TMP18:%.*]] = shl i16 [[TMP15]], [[TMP17]]
+  // CHECK-NEXT:store i16 [[TMP18]], i16* %f, align 2
+  f = f << i;
+
+  // CHECK: [[TMP19:%.*]] = load i32, i32* %lf, align 4
+  // CHECK-NEXT:[[TMP20:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP21:%.*]] = shl i32 [[TMP19]], [[TMP20]]
+  // CHECK-NEXT:store i32 [[TMP21]], i32* %lf, align 4
+  lf = lf << i;
+
+  // CHECK: [[TMP22:%.*]] = load i32, i32* %a, align 4
+  // CHECK-NEXT:[[TMP23:%.*]] = load i32, i32* %u, align 4
+  // CHECK-NEXT:[[TMP24:%.*]] = shl i32 [[TMP22]], [[TMP23]]
+  // CHECK-NEXT:store i32 [[TMP24]], i32* %a, align 4
+  a = a << u;
+
+  // CHECK: [[TMP25:%.*]] = load i16, i16* %f, align 2
+  // CHECK-NEXT:[[TMP26:%.*]] = load i32, i32* %u, align 4
+  // CHECK-NEXT:[[TMP27:%.*]] = trunc i32 [[TMP26]] to i16
+  // CHECK-NEXT:[[TMP28:%.*]] = shl i16 [[TMP25]], [[TMP27]]
+  // CHECK-NEXT:store i16 [[TMP28]], i16* %f, align 2
+  f = f << u;
+}
+
+// CHECK-LABEL: @UnsignedLeftShift(
+void UnsignedLeftShift() {
+  unsigned short _Accum usa;
+  unsigned _Accum ua;
+  unsigned long _Accum ula;
+
+  unsigned short _Fract usf;
+  unsigned _Fract uf;
+  unsigned long _Fract ulf;
+
+  int i;
+  unsigned u;
+
+  // CHECK: [[TMP0:%.*]] = load i16, i16* %usa, align 2
+  // CHECK-NEXT:[[TMP1:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
+  // CHECK-NEXT:[[TMP3:%.*]] = shl i16 [[TMP0]], [[TMP2]]
+  // CHECK-NEXT:store i16 [[TMP3]], i16* %usa, align 2
+  usa = usa << i;
+
+  // CHECK: [[TMP4:%.*]] = load i32, i32* %ua, align 4
+  // CHECK-NEXT:[[TMP5:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP6:%.*]] = shl i32 [[TMP4]], [[TMP5]]
+  // CHECK-NEXT:store i32 [[TMP6]], i32* %ua, align 4
+  ua = ua << i;
+
+  // CHECK: [[TMP7:%.*]] = load i64, i64* %ula, align 8
+  // CHECK-NEXT:[[TMP8:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP9:%.*]] = zext i32 [[TMP8]] to i64
+  // CHECK-NEXT:[[TMP10:%.*]] = shl i64 [[TMP7]], [[TMP9]]
+  // CHECK-NEXT:store i64 [[TMP10]], i64* %ula, align 8
+  ula = ula << i;
+
+  // CHECK: [[TMP11:%.*]] = load i8, i8* %usf, align 1
+  // CHECK-NEXT:[[TMP12:%.*]] = load i32, i32* %i, align 4
+  // CHECK-NEXT:[[TMP13:%.*]] = trunc i32 [[TMP12]] to i8
+  // CHECK-NEXT:[[TMP14:%.*]] = shl i8 [[TMP11]], [[TMP13]]
+  // CHECK-NEXT:store i8 

[PATCH] D83212: [Fixed Point] Add fixed-point shift operations and consteval.

2020-07-07 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 275962.
ebevhan added a comment.

Fix test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83212/new/

https://reviews.llvm.org/D83212

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Frontend/fixed_point_errors.c
  clang/test/Frontend/fixed_point_shift.c

Index: clang/test/Frontend/fixed_point_shift.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_shift.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Accum sa_const1 = 1.0hk << 2;   // CHECK-DAG: @sa_const1 = {{.*}}global i16 512
+short _Accum sa_const2 = 0.5hk << 2;   // CHECK-DAG: @sa_const2 = {{.*}}global i16 256
+short _Accum sa_const3 = 10.0hk >> 3;  // CHECK-DAG: @sa_const3 = {{.*}}global i16 160
+short _Accum sa_const4 = 0.0546875hk << 8; // CHECK-DAG: @sa_const4 = {{.*}}global i16 1792
+short _Accum sa_const5 = -1.0hk << 2;  // CHECK-DAG: @sa_const5 = {{.*}}global i16 -512
+short _Accum sa_const6 = -255.0hk >> 8;// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128
+
+_Fract f_const1 = -1.0r >> 5;  // CHECK-DAG: @f_const1 = {{.*}}global i16 -1024
+_Fract f_const2 = 0.0052490234375r >> 3;   // CHECK-DAG: @f_const2 = {{.*}}global i16 21
+_Fract f_const3 = -0.0001r << 5;   // CHECK-DAG: @f_const3 = {{.*}}global i16 -96
+_Fract f_const4 = -0.75r >> 15;// CHECK-DAG: @f_const4 = {{.*}}global i16 -1
+_Fract f_const5 = 0.078216552734375r << 3; // CHECK-DAG: @f_const5 = {{.*}}global i16 20504
+
+unsigned _Fract uf_const1 = 0.375ur >> 13;
+// SIGNED-DAG:   @uf_const1 = {{.*}}global i16 3
+// UNSIGNED-DAG: @uf_const1 = {{.*}}global i16 1
+unsigned _Fract uf_const2 = 0.0546875ur << 3;
+// SIGNED-DAG:   @uf_const2 = {{.*}}global i16 28672
+// UNSIGNED-DAG: @uf_const2 = {{.*}}global i16 14336
+
+_Sat short _Accum ssa_const1 = (_Sat short _Accum)31.875hk << 4; // CHECK-DAG: @ssa_const1 = {{.*}}global i16 32767
+_Sat short _Accum ssa_const2 = (_Sat short _Accum) - 1.0hk << 8; // CHECK-DAG: @ssa_const2 = {{.*}}global i16 -32768
+_Sat short _Accum ssa_const3 = (_Sat short _Accum)128.0hk << 8;  // CHECK-DAG: @ssa_const3 = {{.*}}global i16 32767
+_Sat short _Fract ssf_const1 = (_Sat short _Fract) - 0.5hr << 3; // CHECK-DAG: @ssf_const1 = {{.*}}global i8 -128
+
+_Sat unsigned _Fract suf_const1 = (_Sat unsigned _Fract)0.5r << 1;
+// SIGNED-DAG:   @suf_const1 = {{.*}}global i16 -1
+// UNSIGNED-DAG: @suf_const1 = {{.*}}global i16 32767
+_Sat unsigned _Fract suf_const2 = (_Sat unsigned _Fract)0.25r << 1;
+// SIGNED-DAG:   @suf_const2 = {{.*}}global i16 -32768
+// UNSIGNED-DAG: @suf_const2 = {{.*}}global i16 16384
+_Sat unsigned _Accum sua_const2 = (_Sat unsigned _Accum)128.0uk << 10;
+// SIGNED-DAG:   @sua_const2 = {{.*}}global i32 -1
+// UNSIGNED-DAG: @sua_const2 = {{.*}}global i32 2147483647
Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -259,11 +259,30 @@
 short _Accum mul_ovf2 = (-0.5hr - 0.5hr) * (-0.5hr - 0.5hr);  // expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
 short _Accum div_ovf1 = 255.0hk / 0.5hk;  // expected-warning {{overflow in expression; result is -2.0 with type 'short _Accum'}}
 
+short _Accum shl_ovf1 = 255.0hk << 8;   // expected-warning {{overflow in expression; result is -256.0 with type 'short _Accum'}}
+short _Fract shl_ovf2 = -0.25hr << 3;   // expected-warning {{overflow in expression; result is 0.0 with type 'short _Fract'}}
+unsigned short _Accum shl_ovf3 = 100.5uhk << 3; // expected-warning {{overflow in expression; result is 36.0 with type 'unsigned short _Accum'}}
+short _Fract shl_ovf4 = 0.25hr << 2;// expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
+
+_Accum shl_bw1 = 0.91552734375k << 32;   // expected-warning {{shift count >= width of type}} \
+ expected-warning {{overflow in expression; result is -65536.0 with type '_Accum'}}
+unsigned _Fract shl_bw2 = 0.65ur << 16;  // expected-warning {{shift count >= width of type}} \
+ expected-warning {{overflow in expression; result is 0.0 with type 'unsigned _Fract'}}
+_Sat short _Accum shl_bw3 = (_Sat short _Accum)80.0hk << 17; // expected-warning {{shift count >= width of type}}
+short _Accum shr_bw1 = 1.0hk >> 17; 

[PATCH] D83212: [Fixed Point] Add fixed-point shift operations and consteval.

2020-07-06 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: rjmccall, leonardchan, bjope.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83212

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Frontend/fixed_point_errors.c
  clang/test/Frontend/fixed_point_shift.c

Index: clang/test/Frontend/fixed_point_shift.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_shift.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Accum sa_const1 = 1.0hk << 2;   // CHECK-DAG: @sa_const1 = global i16 512
+short _Accum sa_const2 = 0.5hk << 2;   // CHECK-DAG: @sa_const2 = global i16 256
+short _Accum sa_const3 = 10.0hk >> 3;  // CHECK-DAG: @sa_const3 = global i16 160
+short _Accum sa_const4 = 0.0546875hk << 8; // CHECK-DAG: @sa_const4 = global i16 1792
+short _Accum sa_const5 = -1.0hk << 2;  // CHECK-DAG: @sa_const5 = global i16 -512
+short _Accum sa_const6 = -255.0hk >> 8;// CHECK-DAG: @sa_const6 = global i16 -128
+
+_Fract f_const1 = -1.0r >> 5;  // CHECK-DAG: @f_const1 = global i16 -1024
+_Fract f_const2 = 0.0052490234375r >> 3;   // CHECK-DAG: @f_const2 = global i16 21
+_Fract f_const3 = -0.0001r << 5;   // CHECK-DAG: @f_const3 = global i16 -96
+_Fract f_const4 = -0.75r >> 15;// CHECK-DAG: @f_const4 = global i16 -1
+_Fract f_const5 = 0.078216552734375r << 3; // CHECK-DAG: @f_const5 = global i16 20504
+
+unsigned _Fract uf_const1 = 0.375ur >> 13;
+// SIGNED-DAG:   @uf_const1 = global i16 3
+// UNSIGNED-DAG: @uf_const1 = global i16 1
+unsigned _Fract uf_const2 = 0.0546875ur << 3;
+// SIGNED-DAG:   @uf_const2 = global i16 28672
+// UNSIGNED-DAG: @uf_const2 = global i16 14336
+
+_Sat short _Accum ssa_const1 = (_Sat short _Accum)31.875hk << 4; // CHECK-DAG: @ssa_const1 = global i16 32767
+_Sat short _Accum ssa_const2 = (_Sat short _Accum) - 1.0hk << 8; // CHECK-DAG: @ssa_const2 = global i16 -32768
+_Sat short _Accum ssa_const3 = (_Sat short _Accum)128.0hk << 8;  // CHECK-DAG: @ssa_const3 = global i16 32767
+_Sat short _Fract ssf_const1 = (_Sat short _Fract) - 0.5hr << 3; // CHECK-DAG: @ssf_const1 = global i8 -128
+
+_Sat unsigned _Fract suf_const1 = (_Sat unsigned _Fract)0.5r << 1;
+// SIGNED-DAG:   @suf_const1 = global i16 -1
+// UNSIGNED-DAG: @suf_const1 = global i16 32767
+_Sat unsigned _Fract suf_const2 = (_Sat unsigned _Fract)0.25r << 1;
+// SIGNED-DAG:   @suf_const2 = global i16 -32768
+// UNSIGNED-DAG: @suf_const2 = global i16 16384
+_Sat unsigned _Accum sua_const2 = (_Sat unsigned _Accum)128.0uk << 10;
+// SIGNED-DAG:   @sua_const2 = global i32 -1
+// UNSIGNED-DAG: @sua_const2 = global i32 2147483647
Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -259,11 +259,30 @@
 short _Accum mul_ovf2 = (-0.5hr - 0.5hr) * (-0.5hr - 0.5hr);  // expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
 short _Accum div_ovf1 = 255.0hk / 0.5hk;  // expected-warning {{overflow in expression; result is -2.0 with type 'short _Accum'}}
 
+short _Accum shl_ovf1 = 255.0hk << 8;   // expected-warning {{overflow in expression; result is -256.0 with type 'short _Accum'}}
+short _Fract shl_ovf2 = -0.25hr << 3;   // expected-warning {{overflow in expression; result is 0.0 with type 'short _Fract'}}
+unsigned short _Accum shl_ovf3 = 100.5uhk << 3; // expected-warning {{overflow in expression; result is 36.0 with type 'unsigned short _Accum'}}
+short _Fract shl_ovf4 = 0.25hr << 2;// expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
+
+_Accum shl_bw1 = 0.91552734375k << 32;   // expected-warning {{shift count >= width of type}} \
+ expected-warning {{overflow in expression; result is -65536.0 with type '_Accum'}}
+unsigned _Fract shl_bw2 = 0.65ur << 16;  // expected-warning {{shift count >= width of type}} \
+ expected-warning {{overflow in expression; result is 0.0 with type 'unsigned _Fract'}}
+_Sat short _Accum shl_bw3 = (_Sat short _Accum)80.0hk << 17; // expected-warning {{shift count >= width of type}}
+short _Accum shr_bw1 = 1.0hk >> 17;  // expected-warning {{shift count >= width of type}}
+
+_Accum shl_neg1 = 25.5k << -5;  // expected-warning {{shift count is 

[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-07-06 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 275657.
ebevhan added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_comparisons.c
  clang/test/Frontend/fixed_point_compound.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c
  clang/test/Frontend/fixed_point_unary.c

Index: clang/test/Frontend/fixed_point_unary.c
===
--- clang/test/Frontend/fixed_point_unary.c
+++ clang/test/Frontend/fixed_point_unary.c
@@ -68,28 +68,28 @@
 // CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
 // SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP18]], i32 65536)
 // SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
-// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP18]], i32 32768)
+// UNSIGNED-NEXT: [[TMP20:%.*]] = icmp slt i32 [[TMP19]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP20]], i32 0, i32 [[TMP19]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sua, align 4
   sua++;
 
 // CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
 // SIGNED-NEXT:   [[TMP21:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP20]], i16 256)
 // SIGNED-NEXT:   store i16 [[TMP21]], i16* @susa, align 2
-// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
-// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE2]], i15 128)
-// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
+// UNSIGNED-NEXT: [[TMP22:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP20]], i16 128)
+// UNSIGNED-NEXT: [[TMP23:%.*]] = icmp slt i16 [[TMP22]], 0
+// UNSIGNED-NEXT: [[SATMIN1:%.*]] = select i1 [[TMP23]], i16 0, i16 [[TMP22]]
+// UNSIGNED-NEXT: store i16 [[SATMIN1]], i16* @susa, align 2
   susa++;
 
 // CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
 // SIGNED-NEXT:   [[TMP23:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP22]], i16 -1)
 // SIGNED-NEXT:   store i16 [[TMP23]], i16* @suf, align 2
-// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
-// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE4]], i15 -1)
-// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
+// UNSIGNED-NEXT: [[TMP25:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP22]], i16 32767)
+// UNSIGNED-NEXT: [[TMP26:%.*]] = icmp slt i16 [[TMP25]], 0
+// UNSIGNED-NEXT: [[SATMIN2:%.*]] = select i1 [[TMP26]], i16 0, i16 [[TMP25]]
+// UNSIGNED-NEXT: store i16 [[SATMIN2]], i16* @suf, align 2
   suf++;
 }
 
@@ -146,28 +146,28 @@
 // CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
 // SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[TMP18]], i32 65536)
 // SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
-// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP18]], i32 32768)
+// UNSIGNED-NEXT: [[TMP20:%.*]] = icmp slt i32 [[TMP19]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP20]], i32 0, i32 [[TMP19]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sua, align 4
   sua--;
 
 // CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
 // SIGNED-NEXT:   [[TMP21:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP20]], i16 256)
 // SIGNED-NEXT:   store i16 [[TMP21]], i16* @susa, align 2
-// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
-// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE2]], i15 128)
-// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
+// UNSIGNED-NEXT: [[TMP22:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP20]], i16 128)
+// UNSIGNED-NEXT: [[TMP23:%.*]] = icmp slt i16 [[TMP22]], 0
+// UNSIGNED-NEXT: [[SATMIN1:%.*]] = select i1 [[TMP23]], i16 0, i16 [[TMP22]]
+// UNSIGNED-NEXT: store i16 [[SATMIN1]], i16* @susa, align 2
   susa--;
 
 // CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
 // SIGNED-NEXT:   [[TMP23:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP22]], i16 -1)
 // SIGNED-NEXT: 

[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-07-03 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Well, it's not so much as adding the bit, but adding the information that the 
bit exists. That means either new intrinsics for all of the operations, or 
adding flags to the existing ones. That's a fair bit of added complexity. Also, 
 +  would do virtually the exact same thing as 
the new unsigned-with-padding operations, so the utility of adding all of it is 
a bit questionable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663



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


[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-06-30 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

Another point is, if we for example have an i16 umul.fix in legalization, we 
have no way of knowing in the general case that it is safe to replace it with 
an smul.fix, since the information that the MSB is not significant does not 
exist on IR level. This is the 'loss of padding bit' that I'm referring to.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663



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


[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-06-30 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

In D82663#2117451 , @rjmccall wrote:

> Why not legalize to the signed operation?


My feeling was that it wasn't right do so in LLVM, because LLVM has no notion 
of the padding bit and therefore doesn't really care about Clang's rationale 
for doing the legalization that way.
If an illegal udiv.fix.sat needs to be legalized via promotion, it makes more 
sense to legalize it to another unsigned operation rather than arbitrarily 
doing it as a signed one.

I guess it could be done in cases where the resulting signed operation was 
legal and the unsigned one was not, but that isn't testable upstream since none 
of the operations are legal on upstream targets.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663



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


[PATCH] D82662: [CodeGen] Use the common semantic for fixed-point codegen, not the result semantic.

2020-06-29 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfefa34faf551: [CodeGen] Use the common semantic for 
fixed-point codegen, not the result… (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82662/new/

https://reviews.llvm.org/D82662

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c

Index: clang/test/Frontend/fixed_point_sub.c
===
--- clang/test/Frontend/fixed_point_sub.c
+++ clang/test/Frontend/fixed_point_sub.c
@@ -419,7 +419,7 @@
   // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40
   // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40
   // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8
-  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.usub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]])
+  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.ssub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]])
   // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535
   // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]]
   // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0
@@ -428,7 +428,7 @@
   // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39
   // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39
   // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7
-  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.usub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]])
+  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.ssub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]])
   // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
   // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
   // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0
Index: clang/test/Frontend/fixed_point_mul.c
===
--- clang/test/Frontend/fixed_point_mul.c
+++ clang/test/Frontend/fixed_point_mul.c
@@ -276,12 +276,12 @@
   // SIGNED-NEXT:   [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i40
   // SIGNED-NEXT:   [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i40
   // SIGNED-NEXT:   [[UPSCALE9:%.*]] = shl i40 [[RESIZE8]], 8
-  // SIGNED-NEXT:   [[TMP8:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8)
+  // SIGNED-NEXT:   [[TMP8:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8)
   // SIGNED-NEXT:   [[RESIZE10:%.*]] = trunc i40 [[TMP8]] to i16
   // UNSIGNED-NEXT: [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i39
   // UNSIGNED-NEXT: [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i39
   // UNSIGNED-NEXT: [[UPSCALE9:%.*]] = shl i39 [[RESIZE8]], 7
-  // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7)
+  // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.smul.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7)
   // UNSIGNED-NEXT: [[RESIZE10:%.*]] = trunc i39 [[TMP8]] to i16
   // CHECK-NEXT:store i16 [[RESIZE10]], i16* %usa, align 2
   usa = usa * i;
@@ -454,7 +454,7 @@
   // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40
   // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40
   // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8
-  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.umul.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8)
+  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.smul.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8)
   // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535
   // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]]
   // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0
@@ -463,7 +463,7 @@
   // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39
   // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39
   // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7
-  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.umul.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7)
+  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.smul.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7)
   // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
   // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
   // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0
Index: clang/test/Frontend/fixed_point_div.c
===
--- clang/test/Frontend/fixed_point_div.c
+++ clang/test/Frontend/fixed_point_div.c
@@ -297,12 +297,12 @@
   // 

[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 273762.
ebevhan added a comment.

Fixed some broken CHECK lines.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82663/new/

https://reviews.llvm.org/D82663

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_comparisons.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c
  clang/test/Frontend/fixed_point_unary.c

Index: clang/test/Frontend/fixed_point_unary.c
===
--- clang/test/Frontend/fixed_point_unary.c
+++ clang/test/Frontend/fixed_point_unary.c
@@ -68,28 +68,28 @@
 // CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
 // SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP18]], i32 65536)
 // SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
-// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP18]], i32 32768)
+// UNSIGNED-NEXT: [[TMP20:%.*]] = icmp slt i32 [[TMP19]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP20]], i32 0, i32 [[TMP19]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sua, align 4
   sua++;
 
 // CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
 // SIGNED-NEXT:   [[TMP21:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP20]], i16 256)
 // SIGNED-NEXT:   store i16 [[TMP21]], i16* @susa, align 2
-// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
-// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE2]], i15 128)
-// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
+// UNSIGNED-NEXT: [[TMP22:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP20]], i16 128)
+// UNSIGNED-NEXT: [[TMP23:%.*]] = icmp slt i16 [[TMP22]], 0
+// UNSIGNED-NEXT: [[SATMIN1:%.*]] = select i1 [[TMP23]], i16 0, i16 [[TMP22]]
+// UNSIGNED-NEXT: store i16 [[SATMIN1]], i16* @susa, align 2
   susa++;
 
 // CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
 // SIGNED-NEXT:   [[TMP23:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP22]], i16 -1)
 // SIGNED-NEXT:   store i16 [[TMP23]], i16* @suf, align 2
-// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
-// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE4]], i15 -1)
-// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
+// UNSIGNED-NEXT: [[TMP25:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP22]], i16 32767)
+// UNSIGNED-NEXT: [[TMP26:%.*]] = icmp slt i16 [[TMP25]], 0
+// UNSIGNED-NEXT: [[SATMIN2:%.*]] = select i1 [[TMP26]], i16 0, i16 [[TMP25]]
+// UNSIGNED-NEXT: store i16 [[SATMIN2]], i16* @suf, align 2
   suf++;
 }
 
@@ -146,28 +146,28 @@
 // CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
 // SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[TMP18]], i32 65536)
 // SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
-// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP18]], i32 32768)
+// UNSIGNED-NEXT: [[TMP20:%.*]] = icmp slt i32 [[TMP19]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP20]], i32 0, i32 [[TMP19]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sua, align 4
   sua--;
 
 // CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
 // SIGNED-NEXT:   [[TMP21:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP20]], i16 256)
 // SIGNED-NEXT:   store i16 [[TMP21]], i16* @susa, align 2
-// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
-// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE2]], i15 128)
-// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
+// UNSIGNED-NEXT: [[TMP22:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP20]], i16 128)
+// UNSIGNED-NEXT: [[TMP23:%.*]] = icmp slt i16 [[TMP22]], 0
+// UNSIGNED-NEXT: [[SATMIN1:%.*]] = select i1 [[TMP23]], i16 0, i16 [[TMP22]]
+// UNSIGNED-NEXT: store i16 [[SATMIN1]], i16* @susa, align 2
   susa--;
 
 // CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
 // SIGNED-NEXT:   [[TMP23:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP22]], i16 -1)
 // SIGNED-NEXT:   store i16 [[TMP23]], 

[PATCH] D82662: [CodeGen] Use the common semantic for fixed-point codegen, not the result semantic.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added a reviewer: leonardchan.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Using the result semantic is wrong in some cases, such as
unsigned fixed-point + signed integer. In this case, the
result semantic is unsigned and the common semantic is
signed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82662

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c

Index: clang/test/Frontend/fixed_point_sub.c
===
--- clang/test/Frontend/fixed_point_sub.c
+++ clang/test/Frontend/fixed_point_sub.c
@@ -419,7 +419,7 @@
   // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40
   // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40
   // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8
-  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.usub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]])
+  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.ssub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]])
   // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535
   // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]]
   // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0
@@ -428,7 +428,7 @@
   // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39
   // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39
   // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7
-  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.usub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]])
+  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.ssub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]])
   // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
   // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
   // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0
Index: clang/test/Frontend/fixed_point_mul.c
===
--- clang/test/Frontend/fixed_point_mul.c
+++ clang/test/Frontend/fixed_point_mul.c
@@ -276,12 +276,12 @@
   // SIGNED-NEXT:   [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i40
   // SIGNED-NEXT:   [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i40
   // SIGNED-NEXT:   [[UPSCALE9:%.*]] = shl i40 [[RESIZE8]], 8
-  // SIGNED-NEXT:   [[TMP8:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8)
+  // SIGNED-NEXT:   [[TMP8:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[RESIZE7]], i40 [[UPSCALE9]], i32 8)
   // SIGNED-NEXT:   [[RESIZE10:%.*]] = trunc i40 [[TMP8]] to i16
   // UNSIGNED-NEXT: [[RESIZE7:%.*]] = zext i16 [[TMP6]] to i39
   // UNSIGNED-NEXT: [[RESIZE8:%.*]] = sext i32 [[TMP7]] to i39
   // UNSIGNED-NEXT: [[UPSCALE9:%.*]] = shl i39 [[RESIZE8]], 7
-  // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7)
+  // UNSIGNED-NEXT: [[TMP8:%.*]] = call i39 @llvm.smul.fix.i39(i39 [[RESIZE7]], i39 [[UPSCALE9]], i32 7)
   // UNSIGNED-NEXT: [[RESIZE10:%.*]] = trunc i39 [[TMP8]] to i16
   // CHECK-NEXT:store i16 [[RESIZE10]], i16* %usa, align 2
   usa = usa * i;
@@ -454,7 +454,7 @@
   // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40
   // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40
   // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8
-  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.umul.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8)
+  // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.smul.fix.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]], i32 8)
   // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535
   // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]]
   // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0
@@ -463,7 +463,7 @@
   // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39
   // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39
   // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7
-  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.umul.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7)
+  // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.smul.fix.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]], i32 7)
   // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
   // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
   // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0
Index: clang/test/Frontend/fixed_point_div.c
===
--- clang/test/Frontend/fixed_point_div.c
+++ 

[PATCH] D82663: [CodeGen] Have CodeGen for fixed-point unsigned with padding emit signed operations.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added reviewers: leonardchan, rjmccall, bjope.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The design of unsigned fixed-point with padding did not really
work as originally intended downstream.

The issue with the design is that the concept of the unsigned
padding bit disappears in the transition to IR. On the LLVM
level, there is no padding bit and anything goes with the
operations. This has the unfortunate effect of generating
invalid operations during ISel for operations that a target
should be perfectly capable of selecting for.

For example, for an unsigned saturating _Fract division of
width 16, we emit IR for an i15 udiv.fix.sat. In the legalization
of this operation in ISel, the operand and result are promoted
to i16, and to preserve the saturating behavior, the LHS is
shifted left by 1.

However... This means that we now have a division operation
with a significant value in the LHS MSB. If the target could
select this, there would be no meaning to the padding bit.
Considering that ISel will always promote this due to type
illegality, there's no way around the production of illegal
operations.

This patch changes CodeGen to emit signed operations when
emitting code for unsigned with padding. At least for us
downstream, being able to reuse the signed instructions is
the one of the points of having the padding bit, so this
design seems to align better.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82663

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/Basic/FixedPoint.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_add.c
  clang/test/Frontend/fixed_point_comparisons.c
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c
  clang/test/Frontend/fixed_point_sub.c
  clang/test/Frontend/fixed_point_unary.c

Index: clang/test/Frontend/fixed_point_unary.c
===
--- clang/test/Frontend/fixed_point_unary.c
+++ clang/test/Frontend/fixed_point_unary.c
@@ -68,28 +68,28 @@
 // CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
 // SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP18]], i32 65536)
 // SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
-// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: [[TMP19:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP18]], i32 32768)
+// UNSIGNED-NEXT: [[TMP20:%.*]] = icmp slt i32 [[TMP19]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP20]], i32 0, i32 [[TMP19]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sua, align 4
   sua++;
 
 // CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
 // SIGNED-NEXT:   [[TMP21:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP20]], i16 256)
 // SIGNED-NEXT:   store i16 [[TMP21]], i16* @susa, align 2
-// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
-// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE2]], i15 128)
-// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
+// UNSIGNED-NEXT: [[TMP22:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP20]], i16 128)
+// UNSIGNED-NEXT: [[TMP23:%.*]] = icmp slt i16 [[TMP22]], 0
+// UNSIGNED-NEXT: [[SATMIN1:%.*]] = select i1 [[TMP23]], i16 0, i16 [[TMP22]]
+// UNSIGNED-NEXT: store i16 [[SATMIN1]], i16* @susa, align 2
   susa++;
 
 // CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
 // SIGNED-NEXT:   [[TMP23:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP22]], i16 -1)
 // SIGNED-NEXT:   store i16 [[TMP23]], i16* @suf, align 2
-// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
-// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE4]], i15 -1)
-// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
+// UNSIGNED-NEXT: [[TMP25:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP22]], i16 32767)
+// UNSIGNED-NEXT: [[TMP26:%.*]] = icmp slt i16 [[TMP25]], 0
+// UNSIGNED-NEXT: [[SATMIN2:%.*]] = select i1 [[TMP26]], i16 0, i16 [[TMP25]]
+// UNSIGNED-NEXT: store i16 [[SATMIN2]], i16* @suf, align 2
   suf++;
 }
 
@@ -146,28 +146,28 @@
 // CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
 // SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[TMP18]], i32 65536)
 // SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
-// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 32768)
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4

[PATCH] D73186: [AST] Add fixed-point multiplication constant evaluation.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG53f5c8b4a14c: [AST] Add fixed-point multiplication constant 
evaluation. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73186/new/

https://reviews.llvm.org/D73186

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Basic/FixedPoint.cpp
  clang/test/Frontend/fixed_point_mul.c

Index: clang/test/Frontend/fixed_point_mul.c
===
--- clang/test/Frontend/fixed_point_mul.c
+++ clang/test/Frontend/fixed_point_mul.c
@@ -1,6 +1,49 @@
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
 
+// Multiplication between different fixed point types
+short _Accum sa_const = 2.0hk * 2.0hk;  // CHECK-DAG: @sa_const  = {{.*}}global i16 512, align 2
+_Accum a_const = 3.0hk * 2.0k;  // CHECK-DAG: @a_const   = {{.*}}global i32 196608, align 4
+long _Accum la_const = 4.0hk * 2.0lk;   // CHECK-DAG: @la_const  = {{.*}}global i64 17179869184, align 8
+short _Accum sa_const2 = 0.5hr * 2.0hk; // CHECK-DAG: @sa_const2  = {{.*}}global i16 128, align 2
+short _Accum sa_const3 = 0.5r * 3.0hk;  // CHECK-DAG: @sa_const3  = {{.*}}global i16 192, align 2
+short _Accum sa_const4 = 0.5lr * 4.0hk; // CHECK-DAG: @sa_const4  = {{.*}}global i16 256, align 2
+
+// Unsigned multiplication
+unsigned short _Accum usa_const = 1.0uhk * 2.0uhk;
+// CHECK-SIGNED-DAG:   @usa_const = {{.*}}global i16 768, align 2
+// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2
+
+// Unsigned * signed
+short _Accum sa_const5 = 20.0uhk * 3.0hk;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 7680, align 2
+
+// Multiplication with negative number
+short _Accum sa_const6 = 0.5hr * (-2.0hk);
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128, align 2
+
+// Int multiplication
+unsigned short _Accum usa_const2 = 5 * 10.5uhk;
+// CHECK-SIGNED-DAG:   @usa_const2 = {{.*}}global i16 640, align 2
+// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const7 = 3 * (-0.5hk);   // CHECK-DAG: @sa_const7 = {{.*}}global i16 -192, align 2
+short _Accum sa_const8 = 100 * (-2.0hk); // CHECK-DAG: @sa_const8 = {{.*}}global i16 -25600, align 2
+long _Fract lf_const = -0.25lr * 3;  // CHECK-DAG: @lf_const  = {{.*}}global i32 -1610612736, align 4
+
+// Saturated multiplication
+_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk * 3.0hk;
+// CHECK-DAG: @sat_sa_const = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk * 128.0uhk;
+// CHECK-SIGNED-DAG:   @sat_usa_const = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)128.0hk * -128;
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 -32768, align 2
+_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk * 30;
+// CHECK-SIGNED-DAG:   @sat_usa_const2 = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk * (-2);
+// CHECK-DAG:   @sat_usa_const3 = {{.*}}global i16 0, align 2
+
 void SignedMultiplication() {
   // CHECK-LABEL: SignedMultiplication
   short _Accum sa;
Index: clang/lib/Basic/FixedPoint.cpp
===
--- clang/lib/Basic/FixedPoint.cpp
+++ clang/lib/Basic/FixedPoint.cpp
@@ -197,6 +197,63 @@
   return APFixedPoint(Result, CommonFXSema);
 }
 
+APFixedPoint APFixedPoint::mul(const APFixedPoint ,
+   bool *Overflow) const {
+  auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+  APFixedPoint ConvertedThis = convert(CommonFXSema);
+  APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+  llvm::APSInt ThisVal = ConvertedThis.getValue();
+  llvm::APSInt OtherVal = ConvertedOther.getValue();
+  bool Overflowed = false;
+
+  // Widen the LHS and RHS so we can perform a full multiplication.
+  unsigned Wide = CommonFXSema.getWidth() * 2;
+  if (CommonFXSema.isSigned()) {
+ThisVal = ThisVal.sextOrSelf(Wide);
+OtherVal = OtherVal.sextOrSelf(Wide);
+  } else {
+ThisVal = ThisVal.zextOrSelf(Wide);
+OtherVal = OtherVal.zextOrSelf(Wide);
+  }
+
+  // Perform the full multiplication and downscale to get the same scale.
+  //
+  // Note that the right shifts here perform an implicit downwards rounding.
+  // This rounding could discard bits that would technically place the result
+  // outside the representable range. We interpret the 

[PATCH] D73188: [AST] Improve overflow diagnostics for fixed-point constant evaluation.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG474177c05381: [AST] Improve overflow diagnostics for 
fixed-point constant evaluation. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73188/new/

https://reviews.llvm.org/D73188

Files:
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/test/Frontend/fixed_point_errors.c

Index: clang/test/Frontend/fixed_point_errors.c
===
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -250,3 +250,17 @@
 char c_const = 256.0uk;   // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'char'}}
 short _Accum sa_const5 = 256; // expected-warning{{implicit conversion from 256 cannot fit within the range of values for 'short _Accum'}}
 unsigned short _Accum usa_const2 = -2;// expected-warning{{implicit conversion from -2 cannot fit within the range of values for 'unsigned short _Accum'}}
+
+short _Accum add_ovf1 = 255.0hk + 20.0hk; // expected-warning {{overflow in expression; result is -237.0 with type 'short _Accum'}}
+short _Accum add_ovf2 = 10 + 0.5hr;   // expected-warning {{overflow in expression; result is 0.5 with type 'short _Fract'}}
+short _Accum sub_ovf1 = 16.0uhk - 32.0uhk;// expected-warning {{overflow in expression; result is 240.0 with type 'unsigned short _Accum'}}
+short _Accum sub_ovf2 = -255.0hk - 20;// expected-warning {{overflow in expression; result is 237.0 with type 'short _Accum'}}
+short _Accum mul_ovf1 = 200.0uhk * 10.0uhk;   // expected-warning {{overflow in expression; result is 208.0 with type 'unsigned short _Accum'}}
+short _Accum mul_ovf2 = (-0.5hr - 0.5hr) * (-0.5hr - 0.5hr);  // expected-warning {{overflow in expression; result is -1.0 with type 'short _Fract'}}
+short _Accum div_ovf1 = 255.0hk / 0.5hk;  // expected-warning {{overflow in expression; result is -2.0 with type 'short _Accum'}}
+
+// No warnings for saturation
+short _Fract add_sat  = (_Sat short _Fract)0.5hr + 0.5hr;
+short _Accum sub_sat  = (_Sat short _Accum)-200.0hk - 80.0hk;
+short _Accum mul_sat  = (_Sat short _Accum)80.0hk * 10.0hk;
+short _Fract div_sat  = (_Sat short _Fract)0.9hr / 0.1hr;
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -12881,8 +12881,14 @@
   return false;
 bool Overflowed;
 APFixedPoint Result = Src.convert(DestFXSema, );
-if (Overflowed && !HandleOverflow(Info, E, Result, DestType))
-  return false;
+if (Overflowed) {
+  if (Info.checkingForUndefinedBehavior())
+Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
+ diag::warn_fixedpoint_constant_overflow)
+  << Result.toString() << E->getType();
+  else if (!HandleOverflow(Info, E, Result, E->getType()))
+return false;
+}
 return Success(Result, E);
   }
   case CK_IntegralToFixedPoint: {
@@ -12894,8 +12900,14 @@
 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
 Src, Info.Ctx.getFixedPointSemantics(DestType), );
 
-if (Overflowed && !HandleOverflow(Info, E, IntResult, DestType))
-  return false;
+if (Overflowed) {
+  if (Info.checkingForUndefinedBehavior())
+Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
+ diag::warn_fixedpoint_constant_overflow)
+  << IntResult.toString() << E->getType();
+  else if (!HandleOverflow(Info, E, IntResult, E->getType()))
+return false;
+}
 
 return Success(IntResult, E);
   }
@@ -12920,47 +12932,41 @@
   if (!EvaluateFixedPointOrInteger(RHS, RHSFX, Info))
 return false;
 
+  bool OpOverflow = false, ConversionOverflow = false;
+  APFixedPoint Result(LHSFX.getSemantics());
   switch (E->getOpcode()) {
   case BO_Add: {
-bool AddOverflow, ConversionOverflow;
-APFixedPoint Result = LHSFX.add(RHSFX, )
-   .convert(ResultFXSema, );
-if ((AddOverflow || ConversionOverflow) &&
-!HandleOverflow(Info, E, Result, E->getType()))
-  return false;
-return Success(Result, E);
+Result = LHSFX.add(RHSFX, )
+  .convert(ResultFXSema, );
+break;
   }
   case BO_Sub: {
-bool AddOverflow, ConversionOverflow;
-APFixedPoint Result = LHSFX.sub(RHSFX, )
-   .convert(ResultFXSema, );
-if ((AddOverflow || ConversionOverflow) &&
-!HandleOverflow(Info, E, Result, E->getType()))
-  return false;
-return Success(Result, E);
+Result = LHSFX.sub(RHSFX, )
+ 

[PATCH] D73189: [AST] Fix certain consteval assignment and comma operator issues with fixed-point types.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGda2f852e1913: [AST] Fix certain consteval assignment and 
comma operator issues with fixed… (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73189/new/

https://reviews.llvm.org/D73189

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/Frontend/fixed_point_crash.c


Index: clang/test/Frontend/fixed_point_crash.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_crash.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+union a {
+  _Accum x;
+  int i;
+};
+
+int fn1() {
+  union a m;
+  m.x = 5.6k;
+  return m.i;
+}
+
+int fn2() {
+  union a m;
+  m.x = 7, 5.6k; // expected-warning {{expression result unused}}
+  return m.x, m.i; // expected-warning {{expression result unused}}
+}
+
+_Accum acc = (0.5r, 6.9k); // expected-warning {{expression result unused}}
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -12920,6 +12920,9 @@
 }
 
 bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
+return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
+
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
   FixedPointSemantics ResultFXSema =


Index: clang/test/Frontend/fixed_point_crash.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_crash.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+union a {
+  _Accum x;
+  int i;
+};
+
+int fn1() {
+  union a m;
+  m.x = 5.6k;
+  return m.i;
+}
+
+int fn2() {
+  union a m;
+  m.x = 7, 5.6k; // expected-warning {{expression result unused}}
+  return m.x, m.i; // expected-warning {{expression result unused}}
+}
+
+_Accum acc = (0.5r, 6.9k); // expected-warning {{expression result unused}}
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -12920,6 +12920,9 @@
 }
 
 bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
+return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
+
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
   FixedPointSemantics ResultFXSema =
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73185: [AST] Add fixed-point subtraction constant evaluation.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGeccf7fc7b31a: [AST] Add fixed-point subtraction constant 
evaluation. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73185/new/

https://reviews.llvm.org/D73185

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Basic/FixedPoint.cpp
  clang/test/Frontend/fixed_point_sub.c

Index: clang/test/Frontend/fixed_point_sub.c
===
--- clang/test/Frontend/fixed_point_sub.c
+++ clang/test/Frontend/fixed_point_sub.c
@@ -1,6 +1,55 @@
 // RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
 // RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
 
+// Subtraction between different fixed point types
+short _Accum sa_const = 1.0hk - 2.0hk;  // CHECK-DAG: @sa_const  = {{.*}}global i16 -128, align 2
+_Accum a_const = 1.0hk - 2.0k;  // CHECK-DAG: @a_const   = {{.*}}global i32 -32768, align 4
+long _Accum la_const = 1.0hk - 2.0lk;   // CHECK-DAG: @la_const  = {{.*}}global i64 -2147483648, align 8
+short _Accum sa_const2 = 0.5hr - 2.0hk; // CHECK-DAG: @sa_const2  = {{.*}}global i16 -192, align 2
+short _Accum sa_const3 = 0.5r - 2.0hk;  // CHECK-DAG: @sa_const3  = {{.*}}global i16 -192, align 2
+short _Accum sa_const4 = 0.5lr - 2.0hk; // CHECK-DAG: @sa_const4  = {{.*}}global i16 -192, align 2
+short _Accum sa_const5 = 2.0hk - 0.5lr; // CHECK-DAG: @sa_const5  = {{.*}}global i16 192, align 2
+
+// Unsigned subtraction
+unsigned short _Accum usa_const = 3.0uhk - 2.0uhk;
+// CHECK-SIGNED-DAG:   @usa_const = {{.*}}global i16 768, align 2
+// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2
+
+// Unsigned - signed
+short _Accum sa_const6 = 1.0uhk - 2.0hk;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -128, align 2
+
+// Subtraction with negative number
+short _Accum sa_const7 = 0.5hr - (-2.0hk);
+// CHECK-DAG: @sa_const7 = {{.*}}global i16 320, align 2
+
+// Int subtraction
+unsigned short _Accum usa_const2 = 2 - 0.5uhk;
+// CHECK-SIGNED-DAG:   @usa_const2 = {{.*}}global i16 640, align 2
+// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const8 = 2 - (-0.5hk);   // CHECK-DAG: @sa_const8 = {{.*}}global i16 320, align 2
+short _Accum sa_const9 = 257 - 2.0hk;// CHECK-DAG: @sa_const9 = {{.*}}global i16 32640, align 2
+long _Fract lf_const = 0.5lr - 1;// CHECK-DAG: @lf_const  = {{.*}}global i32 -1073741824, align 4
+
+// Saturated subtraction
+_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk - (-128.0hk);
+// CHECK-DAG: @sat_sa_const = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk - (-128.0uhk);
+// CHECK-SIGNED-DAG:   @sat_usa_const = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)128.0hk - (-128);
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk - (-128);
+// CHECK-SIGNED-DAG:   @sat_usa_const2 = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk - 2;
+// CHECK-DAG:   @sat_usa_const3 = {{.*}}global i16 0, align 2
+_Sat short _Accum sat_sa_const3 = (_Sat short _Accum)-128.0hk - 128;
+// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 -32768, align 2
+_Sat short _Accum sat_sa_const4 = (_Sat short _Accum)-150.0hk - 130.0lk;
+// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
+
+
 void SignedSubtraction() {
   // CHECK-LABEL: SignedSubtraction
   short _Accum sa;
Index: clang/lib/Basic/FixedPoint.cpp
===
--- clang/lib/Basic/FixedPoint.cpp
+++ clang/lib/Basic/FixedPoint.cpp
@@ -173,6 +173,30 @@
   return APFixedPoint(Result, CommonFXSema);
 }
 
+APFixedPoint APFixedPoint::sub(const APFixedPoint ,
+   bool *Overflow) const {
+  auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+  APFixedPoint ConvertedThis = convert(CommonFXSema);
+  APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+  llvm::APSInt ThisVal = ConvertedThis.getValue();
+  llvm::APSInt OtherVal = ConvertedOther.getValue();
+  bool Overflowed = false;
+
+  llvm::APSInt Result;
+  if (CommonFXSema.isSaturated()) {
+Result = CommonFXSema.isSigned() ? ThisVal.ssub_sat(OtherVal)
+ : ThisVal.usub_sat(OtherVal);
+  } else {
+Result = ThisVal.isSigned() ? ThisVal.ssub_ov(OtherVal, Overflowed)
+: 

[PATCH] D73187: [AST] Add fixed-point division constant evaluation.

2020-06-26 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG94e8ec631dda: [AST] Add fixed-point division constant 
evaluation. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73187/new/

https://reviews.llvm.org/D73187

Files:
  clang/include/clang/Basic/FixedPoint.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Basic/FixedPoint.cpp
  clang/test/Frontend/fixed_point_div.c

Index: clang/test/Frontend/fixed_point_div.c
===
--- clang/test/Frontend/fixed_point_div.c
+++ clang/test/Frontend/fixed_point_div.c
@@ -1,6 +1,70 @@
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
 
+// Division between different fixed point types
+short _Accum sa_const = 1.0hk / 2.0hk;  // CHECK-DAG: @sa_const  = {{.*}}global i16 64, align 2
+_Accum a_const = 1.0hk / 2.0k;  // CHECK-DAG: @a_const   = {{.*}}global i32 16384, align 4
+long _Accum la_const = 1.0hk / 2.0lk;   // CHECK-DAG: @la_const  = {{.*}}global i64 1073741824, align 8
+short _Accum sa_const2 = 0.5hr / 2.0hk; // CHECK-DAG: @sa_const2  = {{.*}}global i16 32, align 2
+short _Accum sa_const3 = 0.5r / 2.0hk;  // CHECK-DAG: @sa_const3  = {{.*}}global i16 32, align 2
+short _Accum sa_const4 = 0.5lr / 2.0hk; // CHECK-DAG: @sa_const4  = {{.*}}global i16 32, align 2
+short _Accum sa_const5 = 2.0hk / 0.5lr; // CHECK-DAG: @sa_const5  = {{.*}}global i16 512, align 2
+
+// Unsigned division
+unsigned short _Accum usa_const = 3.0uhk / 2.0uhk;
+// CHECK-SIGNED-DAG:   @usa_const = {{.*}}global i16 192, align 2
+// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2
+
+// Unsigned / signed
+short _Accum sa_const6 = 1.0uhk / 2.0hk;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 64, align 2
+
+// Division with negative number
+short _Accum sa_const7 = 0.5hr / (-2.0hk);
+// CHECK-DAG: @sa_const7 = {{.*}}global i16 -32, align 2
+
+// Int division
+unsigned short _Accum usa_const2 = 2 / 0.5uhk;
+// CHECK-SIGNED-DAG:   @usa_const2 = {{.*}}global i16 512, align 2
+// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 1024, align 2
+short _Accum sa_const8 = 2 / (-0.5hk);   // CHECK-DAG: @sa_const8 = {{.*}}global i16 -512, align 2
+short _Accum sa_const9 = 256 / 2.0hk;// CHECK-DAG: @sa_const9 = {{.*}}global i16 16384, align 2
+long _Fract lf_const = 0.5lr / -1;   // CHECK-DAG: @lf_const  = {{.*}}global i32 -1073741824, align 4
+
+// Saturated division
+_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk / (-0.25hk);
+// CHECK-DAG: @sat_sa_const = {{.*}}global i16 -32768, align 2
+_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk / (0.25uhk);
+// CHECK-SIGNED-DAG:   @sat_usa_const = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)-128.0hk / (-0.0125hr);
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk / (-128);
+// CHECK-SIGNED-DAG:   @sat_usa_const2 = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk / -1;
+// CHECK-DAG:   @sat_usa_const3 = {{.*}}global i16 0, align 2
+_Sat short _Accum sat_sa_const3 = (_Sat short _Accum)-128.0hk / 128;
+// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 -128, align 2
+_Sat short _Accum sat_sa_const4 = (_Sat short _Accum)-25.7hk / 0.1lk;
+// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
+
+// Some more cases
+short _Accum sa_const10 = 255.9921875hk / 255.9921875hk;
+// CHECK-DAG: @sa_const10 = {{.*}}global i16 128, align 2
+short _Accum sat_sa_const5 = (_Sat short _Accum)(-255.0hk - 1.0hk) / 0.0078125hk;
+// CHECK-DAG: @sat_sa_const5 = {{.*}}global i16 -32768, align 2
+_Sat short _Accum sat_sa_const6 = (_Sat short _Accum)(-255.0hk - 1.0hk) / -0.0078125hk;
+// CHECK-DAG: @sat_sa_const6 = {{.*}}global i16 32767, align 2
+short _Accum sa_const12 = 255.9921875hk / -1.0hk;
+// CHECK-DAG: @sa_const12 = {{.*}}global i16 -32767, align 2
+_Sat short _Accum sat_sa_const7 = (_Sat short _Accum)(-255.0hk - 1.0hk) / -1.0hk;
+// CHECK-DAG: @sat_sa_const7 = {{.*}}global i16 32767, align 2
+short _Accum sa_const13 = 0.0234375hk / 2.0hk;
+// CHECK-DAG: @sa_const13 = {{.*}}global i16 1, align 2
+short _Accum sa_const14 = -0.0234375hk / 2.0hk;
+// CHECK-DAG: @sa_const14 = {{.*}}global i16 -2, align 2
+
 void SignedDivision() {
   // CHECK-LABEL: SignedDivision
   short _Accum sa;
Index: clang/lib/Basic/FixedPoint.cpp

[PATCH] D73186: [AST] Add fixed-point multiplication constant evaluation.

2020-06-25 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added a comment.

The last patchset contains the comment about rounding, so I think I will 
consider this accepted.

As a final addendum to the discussion on rounding and overflow... The last 
Appendix to the E-C TR does actually say:

  2.   In the first edition requires that overflow handling is done before 
rounding; for the second edition the order is changed: rounding should be done 
first, followed by overflow handling. Note that this change does not affect any 
result when the overflow mode is saturation. 

The wording in the main text could be a bit clearer about it being explicit, 
though.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73186/new/

https://reviews.llvm.org/D73186



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


[PATCH] D78294: [Fixed Point] Move the compassign LHS type correction a bit further down. NFCI.

2020-04-17 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfd7a34186137: [Fixed Point] Move the compassign LHS type 
correction a bit further down. NFCI. (authored by ebevhan).

Changed prior to commit:
  https://reviews.llvm.org/D78294?vs=258033=258251#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78294/new/

https://reviews.llvm.org/D78294

Files:
  clang/lib/Sema/SemaExpr.cpp


Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13639,14 +13639,6 @@
   if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid())
 return ExprError();
 
-  // The LHS is not converted to the result type for fixed-point compound
-  // assignment as the common type is computed on demand. Reset the CompLHSTy
-  // to the LHS type we would have gotten after unary conversions.
-  if (!CompLHSTy.isNull() &&
-  (LHS.get()->getType()->isFixedPointType() ||
-   RHS.get()->getType()->isFixedPointType()))
-CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
-
   if (ResultTy->isRealFloatingType() &&
   (getLangOpts().getFPRoundingMode() != RoundingMode::NearestTiesToEven ||
getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore))
@@ -13705,6 +13697,12 @@
 OK = LHS.get()->getObjectKind();
   }
 
+  // The LHS is not converted to the result type for fixed-point compound
+  // assignment as the common type is computed on demand. Reset the CompLHSTy
+  // to the LHS type we would have gotten after unary conversions.
+  if (CompResultTy->isFixedPointType())
+CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
+
   if (ConvertHalfVec)
 return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
OpLoc, CurFPFeatures);


Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13639,14 +13639,6 @@
   if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid())
 return ExprError();
 
-  // The LHS is not converted to the result type for fixed-point compound
-  // assignment as the common type is computed on demand. Reset the CompLHSTy
-  // to the LHS type we would have gotten after unary conversions.
-  if (!CompLHSTy.isNull() &&
-  (LHS.get()->getType()->isFixedPointType() ||
-   RHS.get()->getType()->isFixedPointType()))
-CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
-
   if (ResultTy->isRealFloatingType() &&
   (getLangOpts().getFPRoundingMode() != RoundingMode::NearestTiesToEven ||
getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore))
@@ -13705,6 +13697,12 @@
 OK = LHS.get()->getObjectKind();
   }
 
+  // The LHS is not converted to the result type for fixed-point compound
+  // assignment as the common type is computed on demand. Reset the CompLHSTy
+  // to the LHS type we would have gotten after unary conversions.
+  if (CompResultTy->isFixedPointType())
+CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
+
   if (ConvertHalfVec)
 return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
OpLoc, CurFPFeatures);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78294: [Fixed Point] Move the compassign LHS type correction a bit further down. NFCI.

2020-04-16 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan created this revision.
ebevhan added a reviewer: leonardchan.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We can simplify the LHSTy correction for
fixed-point compassign by moving it below
the point where we know we have a compound
assignment.

Also, we shouldn't look at the LHS and RHS
separately; look at the computation result
type instead.

Looking at the LHS and RHS is also wrong
for compassigns with fixed and floating
point (though this does not work upstream
yet).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78294

Files:
  clang/lib/Sema/SemaExpr.cpp


Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13639,14 +13639,6 @@
   if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid())
 return ExprError();
 
-  // The LHS is not converted to the result type for fixed-point compound
-  // assignment as the common type is computed on demand. Reset the CompLHSTy
-  // to the LHS type we would have gotten after unary conversions.
-  if (!CompLHSTy.isNull() &&
-  (LHS.get()->getType()->isFixedPointType() ||
-   RHS.get()->getType()->isFixedPointType()))
-CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
-
   if (ResultTy->isRealFloatingType() &&
   (getLangOpts().getFPRoundingMode() != RoundingMode::NearestTiesToEven ||
getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore))
@@ -13705,6 +13697,12 @@
 OK = LHS.get()->getObjectKind();
   }
 
+  // The LHS is not converted to the result type for fixed-point compound
+  // assignment as the common type is computed on demand. Reset the CompLHSTy
+  // to the LHS type we would have gotten after unary conversions.
+  if (CompResultTy->isFixedPointType())
+CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
+
   if (ConvertHalfVec)
 return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
OpLoc, FPFeatures);


Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13639,14 +13639,6 @@
   if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid())
 return ExprError();
 
-  // The LHS is not converted to the result type for fixed-point compound
-  // assignment as the common type is computed on demand. Reset the CompLHSTy
-  // to the LHS type we would have gotten after unary conversions.
-  if (!CompLHSTy.isNull() &&
-  (LHS.get()->getType()->isFixedPointType() ||
-   RHS.get()->getType()->isFixedPointType()))
-CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
-
   if (ResultTy->isRealFloatingType() &&
   (getLangOpts().getFPRoundingMode() != RoundingMode::NearestTiesToEven ||
getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore))
@@ -13705,6 +13697,12 @@
 OK = LHS.get()->getObjectKind();
   }
 
+  // The LHS is not converted to the result type for fixed-point compound
+  // assignment as the common type is computed on demand. Reset the CompLHSTy
+  // to the LHS type we would have gotten after unary conversions.
+  if (CompResultTy->isFixedPointType())
+CompLHSTy = UsualUnaryConversions(LHS.get()).get()->getType();
+
   if (ConvertHalfVec)
 return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
OpLoc, FPFeatures);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73257: [AST] Compress the FixedPointSemantics type better.

2020-04-08 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd5d0d8eb7d09: [AST] Compress the FixedPointSemantics type 
better. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73257/new/

https://reviews.llvm.org/D73257

Files:
  clang/include/clang/Basic/FixedPoint.h


Index: clang/include/clang/Basic/FixedPoint.h
===
--- clang/include/clang/Basic/FixedPoint.h
+++ clang/include/clang/Basic/FixedPoint.h
@@ -75,11 +75,11 @@
   }
 
 private:
-  unsigned Width;
-  unsigned Scale;
-  bool IsSigned;
-  bool IsSaturated;
-  bool HasUnsignedPadding;
+  unsigned Width  : 16;
+  unsigned Scale  : 13;
+  unsigned IsSigned   : 1;
+  unsigned IsSaturated: 1;
+  unsigned HasUnsignedPadding : 1;
 };
 
 /// The APFixedPoint class works similarly to APInt/APSInt in that it is a


Index: clang/include/clang/Basic/FixedPoint.h
===
--- clang/include/clang/Basic/FixedPoint.h
+++ clang/include/clang/Basic/FixedPoint.h
@@ -75,11 +75,11 @@
   }
 
 private:
-  unsigned Width;
-  unsigned Scale;
-  bool IsSigned;
-  bool IsSaturated;
-  bool HasUnsignedPadding;
+  unsigned Width  : 16;
+  unsigned Scale  : 13;
+  unsigned IsSigned   : 1;
+  unsigned IsSaturated: 1;
+  unsigned HasUnsignedPadding : 1;
 };
 
 /// The APFixedPoint class works similarly to APInt/APSInt in that it is a
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73183: [CodeGen] Emit IR for fixed-point unary operators.

2020-04-08 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG39baaabf6de4: [CodeGen] Emit IR for fixed-point unary 
operators. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73183/new/

https://reviews.llvm.org/D73183

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_unary.c

Index: clang/test/Frontend/fixed_point_unary.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_unary.c
@@ -0,0 +1,264 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+_Accum a;
+_Fract f;
+long _Fract lf;
+unsigned _Accum ua;
+short unsigned _Accum usa;
+unsigned _Fract uf;
+
+_Sat _Accum sa;
+_Sat _Fract sf;
+_Sat long _Fract slf;
+_Sat unsigned _Accum sua;
+_Sat short unsigned _Accum susa;
+_Sat unsigned _Fract suf;
+
+// CHECK-LABEL: @Increment(
+void Increment() {
+// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = sub i32 [[TMP0]], -32768
+// CHECK-NEXT:store i32 [[TMP1]], i32* @a, align 4
+  a++;
+
+// CHECK: [[TMP2:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT:[[TMP3:%.*]] = sub i16 [[TMP2]], -32768
+// CHECK-NEXT:store i16 [[TMP3]], i16* @f, align 2
+  f++;
+
+// CHECK: [[TMP4:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT:[[TMP5:%.*]] = sub i32 [[TMP4]], -2147483648
+// CHECK-NEXT:store i32 [[TMP5]], i32* @lf, align 4
+  lf++;
+
+// CHECK: [[TMP6:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT:   [[TMP7:%.*]] = add i32 [[TMP6]], 65536
+// UNSIGNED-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], 32768
+// CHECK-NEXT:store i32 [[TMP7]], i32* @ua, align 4
+  ua++;
+
+// CHECK: [[TMP8:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT:   [[TMP9:%.*]] = add i16 [[TMP8]], 256
+// UNSIGNED-NEXT: [[TMP9:%.*]] = add i16 [[TMP8]], 128
+// CHECK-NEXT:store i16 [[TMP9]], i16* @usa, align 2
+  usa++;
+
+// CHECK: [[TMP10:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT:   [[TMP11:%.*]] = add i16 [[TMP10]], undef
+// UNSIGNED-NEXT: [[TMP11:%.*]] = add i16 [[TMP10]], -32768
+// CHECK-NEXT:store i16 [[TMP11]], i16* @uf, align 2
+  uf++;
+
+// CHECK: [[TMP12:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT:[[TMP13:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP12]], i32 -32768)
+// CHECK-NEXT:store i32 [[TMP13]], i32* @sa, align 4
+  sa++;
+
+// CHECK: [[TMP14:%.*]] = load i16, i16* @sf, align 2
+// CHECK-NEXT:[[TMP15:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP14]], i16 -32768)
+// CHECK-NEXT:store i16 [[TMP15]], i16* @sf, align 2
+  sf++;
+
+// CHECK: [[TMP16:%.*]] = load i32, i32* @slf, align 4
+// CHECK-NEXT:[[TMP17:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP16]], i32 -2147483648)
+// CHECK-NEXT:store i32 [[TMP17]], i32* @slf, align 4
+  slf++;
+
+// CHECK: [[TMP18:%.*]] = load i32, i32* @sua, align 4
+// SIGNED-NEXT:   [[TMP19:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP18]], i32 65536)
+// SIGNED-NEXT:   store i32 [[TMP19]], i32* @sua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP18]] to i31
+// UNSIGNED-NEXT: [[TMP19:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 32768)
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i31 [[TMP19]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @sua, align 4
+  sua++;
+
+// CHECK: [[TMP20:%.*]] = load i16, i16* @susa, align 2
+// SIGNED-NEXT:   [[TMP21:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP20]], i16 256)
+// SIGNED-NEXT:   store i16 [[TMP21]], i16* @susa, align 2
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP20]] to i15
+// UNSIGNED-NEXT: [[TMP21:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE2]], i15 128)
+// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP21]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @susa, align 2
+  susa++;
+
+// CHECK: [[TMP22:%.*]] = load i16, i16* @suf, align 2
+// SIGNED-NEXT:   [[TMP23:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP22]], i16 -1)
+// SIGNED-NEXT:   store i16 [[TMP23]], i16* @suf, align 2
+// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
+// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE4]], i15 -1)
+// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
+  suf++;
+}
+
+// CHECK-LABEL: @Decrement(
+void Decrement() {
+// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = add i32 [[TMP0]], -32768
+// CHECK-NEXT:store i32 [[TMP1]], i32* @a, align 4
+  a--;
+
+// CHECK: [[TMP2:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT:[[TMP3:%.*]] = add i16 [[TMP2]], -32768
+// 

[PATCH] D73184: [CodeGen] Emit IR for compound assignment with fixed-point operands.

2020-04-08 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG313461f6d8f9: [CodeGen] Emit IR for compound assignment with 
fixed-point operands. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73184/new/

https://reviews.llvm.org/D73184

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Frontend/fixed_point_compound.c

Index: clang/test/Frontend/fixed_point_compound.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_compound.c
@@ -0,0 +1,374 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+short _Fract shf;
+_Accum a;
+unsigned _Fract uf;
+unsigned long _Accum ula;
+
+_Sat short _Fract sshf;
+_Sat _Accum sa;
+_Sat unsigned _Fract suf;
+_Sat unsigned long _Accum sula;
+
+int i;
+unsigned int u;
+signed char c;
+
+
+// CHECK-LABEL: @Addition(
+void Addition() {
+// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT:[[TMP1:%.*]] = load i8, i8* @shf, align 1
+// CHECK-NEXT:[[RESIZE:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT:[[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT:[[TMP2:%.*]] = add i32 [[UPSCALE]], [[TMP0]]
+// CHECK-NEXT:[[DOWNSCALE:%.*]] = ashr i32 [[TMP2]], 8
+// CHECK-NEXT:[[RESIZE1:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT:store i8 [[RESIZE1]], i8* @shf, align 1
+  shf += a;
+
+// CHECK: [[TMP3:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT:[[TMP4:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT:   [[RESIZE2:%.*]] = sext i32 [[TMP4]] to i33
+// SIGNED-NEXT:   [[UPSCALE3:%.*]] = shl i33 [[RESIZE2]], 1
+// SIGNED-NEXT:   [[RESIZE4:%.*]] = zext i16 [[TMP3]] to i33
+// SIGNED-NEXT:   [[TMP5:%.*]] = add i33 [[UPSCALE3]], [[RESIZE4]]
+// SIGNED-NEXT:   [[DOWNSCALE5:%.*]] = ashr i33 [[TMP5]], 1
+// SIGNED-NEXT:   [[RESIZE6:%.*]] = trunc i33 [[DOWNSCALE5]] to i32
+// SIGNED-NEXT:   store i32 [[RESIZE6]], i32* @a, align 4
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i16 [[TMP3]] to i32
+// UNSIGNED-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[RESIZE2]]
+// UNSIGNED-NEXT: store i32 [[TMP5]], i32* @a, align 4
+  a += uf;
+
+// CHECK: [[TMP6:%.*]] = load i64, i64* @ula, align 8
+// CHECK-NEXT:[[TMP7:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT:[[RESIZE7:%.*]] = zext i16 [[TMP7]] to i64
+// CHECK-NEXT:[[UPSCALE8:%.*]] = shl i64 [[RESIZE7]], 16
+// CHECK-NEXT:[[TMP8:%.*]] = add i64 [[UPSCALE8]], [[TMP6]]
+// CHECK-NEXT:[[DOWNSCALE9:%.*]] = lshr i64 [[TMP8]], 16
+// CHECK-NEXT:[[RESIZE10:%.*]] = trunc i64 [[DOWNSCALE9]] to i16
+// CHECK-NEXT:store i16 [[RESIZE10]], i16* @uf, align 2
+  uf += ula;
+
+// CHECK: [[TMP9:%.*]] = load i8, i8* @shf, align 1
+// CHECK-NEXT:[[TMP10:%.*]] = load i64, i64* @ula, align 8
+// SIGNED-NEXT:   [[RESIZE11:%.*]] = zext i64 [[TMP10]] to i65
+// SIGNED-NEXT:   [[RESIZE12:%.*]] = sext i8 [[TMP9]] to i65
+// SIGNED-NEXT:   [[UPSCALE13:%.*]] = shl i65 [[RESIZE12]], 25
+// SIGNED-NEXT:   [[TMP11:%.*]] = add i65 [[RESIZE11]], [[UPSCALE13]]
+// SIGNED-NEXT:   [[DOWNSCALE14:%.*]] = ashr i65 [[TMP11]], 1
+// SIGNED-NEXT:   [[RESIZE15:%.*]] = trunc i65 [[DOWNSCALE14]] to i64
+// SIGNED-NEXT:   [[UPSCALE16:%.*]] = shl i64 [[RESIZE15]], 1
+// SIGNED-NEXT:   store i64 [[UPSCALE16]], i64* @ula, align 8
+// UNSIGNED-NEXT: [[RESIZE7:%.*]] = sext i8 [[TMP9]] to i64
+// UNSIGNED-NEXT: [[UPSCALE8:%.*]] = shl i64 [[RESIZE7]], 24
+// UNSIGNED-NEXT: [[TMP11:%.*]] = add i64 [[TMP10]], [[UPSCALE8]]
+// UNSIGNED-NEXT: store i64 [[TMP11]], i64* @ula, align 8
+  ula += shf;
+
+// CHECK: [[TMP12:%.*]] = load i8, i8* @shf, align 1
+// CHECK-NEXT:[[TMP13:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT:   [[RESIZE17:%.*]] = zext i16 [[TMP13]] to i17
+// SIGNED-NEXT:   [[RESIZE18:%.*]] = sext i8 [[TMP12]] to i17
+// SIGNED-NEXT:   [[UPSCALE19:%.*]] = shl i17 [[RESIZE18]], 9
+// SIGNED-NEXT:   [[TMP14:%.*]] = add i17 [[RESIZE17]], [[UPSCALE19]]
+// SIGNED-NEXT:   [[DOWNSCALE20:%.*]] = ashr i17 [[TMP14]], 1
+// SIGNED-NEXT:   [[RESIZE21:%.*]] = trunc i17 [[DOWNSCALE20]] to i16
+// SIGNED-NEXT:   [[UPSCALE22:%.*]] = shl i16 [[RESIZE21]], 1
+// SIGNED-NEXT:   store i16 [[UPSCALE22]], i16* @uf, align 2
+// UNSIGNED-NEXT: [[RESIZE9:%.*]] = sext i8 [[TMP12]] to i16
+// UNSIGNED-NEXT: [[UPSCALE10:%.*]] = shl i16 [[RESIZE9]], 8
+// UNSIGNED-NEXT: [[TMP14:%.*]] = add i16 [[TMP13]], [[UPSCALE10]]
+// UNSIGNED-NEXT: store i16 [[TMP14]], i16* @uf, align 2
+  uf += shf;
+
+// CHECK: [[TMP15:%.*]] = load i8, i8* @shf, align 1
+// CHECK-NEXT:[[TMP16:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT:[[RESIZE23:%.*]] = sext i8 [[TMP15]] to i32
+// CHECK-NEXT:

[PATCH] D73182: [CodeGen] Emit IR for fixed-point multiplication and division.

2020-04-08 Thread Bevin Hansson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0b9922e67a0b: [CodeGen] Emit IR for fixed-point 
multiplication and division. (authored by ebevhan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73182/new/

https://reviews.llvm.org/D73182

Files:
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/Frontend/fixed_point_div.c
  clang/test/Frontend/fixed_point_mul.c

Index: clang/test/Frontend/fixed_point_mul.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_mul.c
@@ -0,0 +1,431 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+void SignedMultiplication() {
+  // CHECK-LABEL: SignedMultiplication
+  short _Accum sa;
+  _Accum a, b, c, d;
+  long _Accum la;
+  unsigned short _Accum usa;
+  unsigned _Accum ua;
+  unsigned long _Accum ula;
+
+  short _Fract sf;
+  _Fract f;
+  long _Fract lf;
+  unsigned short _Fract usf;
+  unsigned _Fract uf;
+  unsigned long _Fract ulf;
+
+  // Same type
+  // CHECK:   [[TMP0:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:  [[TMP1:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:  [[TMP2:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+  // CHECK-NEXT:  store i16 [[TMP2]], i16* %sa, align 2
+  sa = sa * sa;
+
+  // To larger scale and larger width
+  // CHECK:   [[TMP3:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:  [[TMP4:%.*]] = load i32, i32* %a, align 4
+  // CHECK-NEXT:  [[RESIZE:%.*]] = sext i16 [[TMP3]] to i32
+  // CHECK-NEXT:  [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+  // CHECK-NEXT:  [[TMP5:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[UPSCALE]], i32 [[TMP4]], i32 15)
+  // CHECK-NEXT:  store i32 [[TMP5]], i32* %a, align 4
+  a = sa * a;
+
+  // To same scale and smaller width
+  // CHECK:   [[TMP6:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:  [[TMP7:%.*]] = load i8, i8* %sf, align 1
+  // CHECK-NEXT:  [[RESIZE1:%.*]] = sext i8 [[TMP7]] to i16
+  // CHECK-NEXT:  [[TMP8:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[TMP6]], i16 [[RESIZE1]], i32 7)
+  // CHECK-NEXT:  store i16 [[TMP8]], i16* %sa, align 2
+  sa = sa * sf;
+
+  // To smaller scale and same width.
+  // CHECK:   [[TMP9:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:  [[TMP10:%.*]] = load i16, i16* %f, align 2
+  // CHECK-NEXT:  [[RESIZE2:%.*]] = sext i16 [[TMP9]] to i24
+  // CHECK-NEXT:  [[UPSCALE3:%.*]] = shl i24 [[RESIZE2]], 8
+  // CHECK-NEXT:  [[RESIZE4:%.*]] = sext i16 [[TMP10]] to i24
+  // CHECK-NEXT:  [[TMP11:%.*]] = call i24 @llvm.smul.fix.i24(i24 [[UPSCALE3]], i24 [[RESIZE4]], i32 15)
+  // CHECK-NEXT:  [[DOWNSCALE:%.*]] = ashr i24 [[TMP11]], 8
+  // CHECK-NEXT:  [[RESIZE5:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+  // CHECK-NEXT:  store i16 [[RESIZE5]], i16* %sa, align 2
+  sa = sa * f;
+
+  // To smaller scale and smaller width
+  // CHECK:   [[TMP12:%.*]] = load i32, i32* %a, align 4
+  // CHECK-NEXT:  [[TMP13:%.*]] = load i8, i8* %sf, align 1
+  // CHECK-NEXT:  [[RESIZE6:%.*]] = sext i8 [[TMP13]] to i32
+  // CHECK-NEXT:  [[UPSCALE7:%.*]] = shl i32 [[RESIZE6]], 8
+  // CHECK-NEXT:  [[TMP14:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP12]], i32 [[UPSCALE7]], i32 15)
+  // CHECK-NEXT:  store i32 [[TMP14]], i32* %a, align 4
+  a = a * sf;
+
+  // To larger scale and same width
+  // CHECK:   [[TMP15:%.*]] = load i32, i32* %a, align 4
+  // CHECK-NEXT:  [[TMP16:%.*]] = load i32, i32* %lf, align 4
+  // CHECK-NEXT:  [[RESIZE8:%.*]] = sext i32 [[TMP15]] to i48
+  // CHECK-NEXT:  [[UPSCALE9:%.*]] = shl i48 [[RESIZE8]], 16
+  // CHECK-NEXT:  [[RESIZE10:%.*]] = sext i32 [[TMP16]] to i48
+  // CHECK-NEXT:  [[TMP17:%.*]] = call i48 @llvm.smul.fix.i48(i48 [[UPSCALE9]], i48 [[RESIZE10]], i32 31)
+  // CHECK-NEXT:  [[DOWNSCALE11:%.*]] = ashr i48 [[TMP17]], 16
+  // CHECK-NEXT:  [[RESIZE12:%.*]] = trunc i48 [[DOWNSCALE11]] to i32
+  // CHECK-NEXT:  store i32 [[RESIZE12]], i32* %a, align 4
+  a = a * lf;
+
+  // With corresponding unsigned type
+  // CHECK:[[TMP18:%.*]] = load i16, i16* %sa, align 2
+  // CHECK-NEXT:   [[TMP19:%.*]] = load i16, i16* %usa, align 2
+  // SIGNED-NEXT:  [[RESIZE13:%.*]] = sext i16 [[TMP18]] to i17
+  // SIGNED-NEXT:  [[UPSCALE14:%.*]] = shl i17 [[RESIZE13]], 1
+  // SIGNED-NEXT:  [[RESIZE15:%.*]] = zext i16 [[TMP19]] to i17
+  // SIGNED-NEXT:  [[TMP20:%.*]] = call i17 @llvm.smul.fix.i17(i17 [[UPSCALE14]], i17 [[RESIZE15]], i32 8)
+  // SIGNED-NEXT:  [[DOWNSCALE16:%.*]] = ashr i17 [[TMP20]], 1
+  // SIGNED-NEXT:  [[RESIZE17:%.*]] = trunc i17 [[DOWNSCALE16]] to i16
+  // SIGNED-NEXT:  store i16 [[RESIZE17]], i16* %sa, align 2
+  // UNSIGNED-NEXT:[[TMP20:%.*]] = call i16 

[PATCH] D73189: [AST] Fix certain consteval assignment and comma operator issues with fixed-point types.

2020-04-08 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 255979.
ebevhan added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73189/new/

https://reviews.llvm.org/D73189

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/Frontend/fixed_point_crash.c


Index: clang/test/Frontend/fixed_point_crash.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_crash.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+union a {
+  _Accum x;
+  int i;
+};
+
+int fn1() {
+  union a m;
+  m.x = 5.6k;
+  return m.i;
+}
+
+int fn2() {
+  union a m;
+  m.x = 7, 5.6k; // expected-warning {{expression result unused}}
+  return m.x, m.i; // expected-warning {{expression result unused}}
+}
+
+_Accum acc = (0.5r, 6.9k); // expected-warning {{expression result unused}}
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -12695,6 +12695,9 @@
 }
 
 bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
+return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
+
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
   FixedPointSemantics ResultFXSema =


Index: clang/test/Frontend/fixed_point_crash.c
===
--- /dev/null
+++ clang/test/Frontend/fixed_point_crash.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+union a {
+  _Accum x;
+  int i;
+};
+
+int fn1() {
+  union a m;
+  m.x = 5.6k;
+  return m.i;
+}
+
+int fn2() {
+  union a m;
+  m.x = 7, 5.6k; // expected-warning {{expression result unused}}
+  return m.x, m.i; // expected-warning {{expression result unused}}
+}
+
+_Accum acc = (0.5r, 6.9k); // expected-warning {{expression result unused}}
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -12695,6 +12695,9 @@
 }
 
 bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+  if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
+return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
+
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
   FixedPointSemantics ResultFXSema =
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   >