[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] 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] 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] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-07-09 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



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

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?



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]])

ebevhan wrote:
> 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.
Ah right I forgot that.



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

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
```


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] 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] D83294: [Fixed Point] Add codegen for fixed-point shifts.

2020-07-08 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan 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);
 

Could this instead be:

```
auto CommonFixedSema = IsShift ? LHSFixedSema : 
LHSFixedSema.getCommonSemantics(RHSFixedSema, true);
```





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]])

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.


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] 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