[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] D73183: [CodeGen] Emit IR for fixed-point unary operators.

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

Rebased.


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
+// CHECK-NEXT:store i16 [[TMP3]], i16* @f, align 2
+  f--;
+
+// CHECK: [[TMP4:%.*]] = load i32, 

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

2020-01-28 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

Please test prefix increment/decrement as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73183



___
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-01-23 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan updated this revision to Diff 239794.
ebevhan added a comment.

Rebased.


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
+// CHECK-NEXT:store i16 [[TMP3]], i16* @f, align 2
+  f--;
+
+// CHECK: [[TMP4:%.*]] = load i32, 

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

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

Repository:
  rG LLVM Github Monorepo

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
+// CHECK-NEXT:store i16 [[TMP3]], i16* @f, align 2
+  f--;
+
+// CHECK: [[TMP4:%.*]] = load