[clang] 44ebc2c - Refactor most of the fixed-point tests.
Bevin Hansson via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 20 01:31:18 PDT 2020
Author: Bevin Hansson
Date: 2020-08-20T10:30:05+02:00
New Revision: 44ebc2c8ebc8cdbd4f45e50a529faf8a990732e5
URL: https://github.com/llvm/llvm-project/commit/44ebc2c8ebc8cdbd4f45e50a529faf8a990732e5
DIFF: https://github.com/llvm/llvm-project/commit/44ebc2c8ebc8cdbd4f45e50a529faf8a990732e5.diff
LOG: Refactor most of the fixed-point tests.
The tests were not written with update_cc_test_checks
in mind, which make them difficult to update. Fix this.
Also, some of the consteval tests were outright broken,
since the CHECK lines were wrong.
Other than this, the semantics of the tests are preserved.
Added:
clang/test/Frontend/fixed_point_add_const.c
clang/test/Frontend/fixed_point_div_const.c
clang/test/Frontend/fixed_point_mul_const.c
clang/test/Frontend/fixed_point_sub_const.c
Modified:
clang/test/Frontend/fixed_point_add.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
Removed:
################################################################################
diff --git a/clang/test/Frontend/fixed_point_add.c b/clang/test/Frontend/fixed_point_add.c
index 078976503ecd..15132cfb712a 100644
--- a/clang/test/Frontend/fixed_point_add.c
+++ b/clang/test/Frontend/fixed_point_add.c
@@ -1,433 +1,581 @@
+// 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 -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
-// Addition between
diff erent fixed point types
-short _Accum sa_const = 1.0hk + 2.0hk; // CHECK-DAG: @sa_const = {{.*}}global i16 384, align 2
-_Accum a_const = 1.0hk + 2.0k; // CHECK-DAG: @a_const = {{.*}}global i32 98304, align 4
-long _Accum la_const = 1.0hk + 2.0lk; // CHECK-DAG: @la_const = {{.*}}global i64 6442450944, align 8
-short _Accum sa_const2 = 0.5hr + 2.0hk; // CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
-short _Accum sa_const3 = 0.5r + 2.0hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
-short _Accum sa_const4 = 0.5lr + 2.0hk; // CHECK-DAG: @sa_const4 = {{.*}}global i16 320, align 2
-
-// Unsigned addition
-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 = 1.0uhk + 2.0hk;
-// CHECK-DAG: @sa_const5 = {{.*}}global i16 384, align 2
-
-// Addition with negative number
-short _Accum sa_const6 = 0.5hr + (-2.0hk);
-// CHECK-DAG: @sa_const6 = {{.*}}global i16 -192, align 2
-
-// Int addition
-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_const7 = 2 + (-0.5hk); // CHECK-DAG: @sa_const7 = {{.*}}global i16 192, align 2
-short _Accum sa_const8 = 257 + (-2.0hk); // CHECK-DAG: @sa_const8 = {{.*}}global i16 32640, align 2
-long _Fract lf_const = -0.5lr + 1; // CHECK-DAG: @lf_const = {{.*}}global i32 1073741824, align 4
-
-// Saturated addition
-_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
-
-void SignedAddition() {
- // CHECK-LABEL: SignedAddition
- 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: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SA2:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[SA2]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+short _Accum sa;
+_Accum a, a2, a3, a4;
+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;
+
+_Sat short _Accum sa_sat;
+_Sat _Accum a_sat;
+_Sat long _Accum la_sat;
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned _Accum ua_sat;
+_Sat unsigned long _Accum ula_sat;
+_Sat unsigned _Fract uf_sat;
+
+int i;
+unsigned int ui;
+_Bool b;
+
+// CHECK-LABEL: @sadd_sasasa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void sadd_sasasa() {
sa = sa + sa;
+}
- // To larger scale and larger width
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
- // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[SA]], [[A]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+// CHECK-LABEL: @sadd_asaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = add i32 [[UPSCALE]], [[TMP1]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sadd_asaa() {
a = sa + a;
+}
- // To same scale and smaller width
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
- // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i16
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[EXT_SF]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+// CHECK-LABEL: @sadd_sasasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i16
+// CHECK-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], [[RESIZE]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void sadd_sasasf() {
sa = sa + sf;
+}
- // To smaller scale and same width.
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[F:%[0-9]+]] = load i16, i16* %f, align 2
- // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i24
- // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i24 [[EXT_SA]], 8
- // CHECK-NEXT: [[EXT_F:%[a-z0-9]+]] = sext i16 [[F]] to i24
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i24 [[SA]], [[EXT_F]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i24 [[SUM]], 8
- // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
- // CHECK-NEXT: store i16 [[TRUNC_RES]], i16* %sa, align 2
+// CHECK-LABEL: @sadd_sasaf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i24
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i16 [[TMP1]] to i24
+// CHECK-NEXT: [[TMP2:%.*]] = add i24 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i24 [[TMP2]], 8
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void sadd_sasaf() {
sa = sa + f;
+}
- // To smaller scale and smaller width
- // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
- // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i32
- // CHECK-NEXT: [[SF:%[a-z0-9]+]] = shl i32 [[EXT_SF]], 8
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[A]], [[SF]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+// CHECK-LABEL: @sadd_aasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP0]], [[UPSCALE]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sadd_aasf() {
a = a + sf;
+}
- // To larger scale and same width
- // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
- // CHECK-NEXT: [[EXT_A:%[a-z0-9]+]] = sext i32 [[A]] to i48
- // CHECK-NEXT: [[A:%[a-z0-9]+]] = shl i48 [[EXT_A]], 16
- // CHECK-NEXT: [[EXT_LF:%[a-z0-9]+]] = sext i32 [[LF]] to i48
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i48 [[A]], [[EXT_LF]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i48 [[SUM]], 16
- // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i48 [[RES]] to i32
- // CHECK-NEXT: store i32 [[TRUNC_RES]], i32* %a, align 4
+// CHECK-LABEL: @sadd_aalf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i48
+// CHECK-NEXT: [[TMP2:%.*]] = add i48 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i48 [[TMP2]], 16
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i48 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sadd_aalf() {
a = a + lf;
+}
- // With corresponding unsigned type
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i17
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i17 [[SA]], [[USA_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
- // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[USA]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+// SIGNED-LABEL: @sadd_sasausa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = add i17 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sadd_sasausa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], [[TMP1]]
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sadd_sasausa() {
sa = sa + usa;
+}
- // With unsigned of larger scale
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i32, i32* %ua, align 4
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i33
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i33 [[SA_EXT]], 9
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i32 [[USA]] to i33
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i33 [[SA]], [[USA_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i33 [[SUM]], 1
- // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i33 [[RESULT]] to i32
- // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
- // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i32 [[SA]], [[USA]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+// SIGNED-LABEL: @sadd_asaua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 9
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = add i33 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sadd_asaua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i32 [[UPSCALE]], [[TMP1]]
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sadd_asaua() {
a = sa + ua;
+}
- // With unsigned of smaller width
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
- // SIGNED-NEXT: [[USF_EXT:%[a-z0-9]+]] = zext i8 [[USF]] to i17
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i17 [[SA]], [[USF_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
- // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
- // UNSIGNED-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[EXT_USF]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+// SIGNED-LABEL: @sadd_sasausf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i8 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = add i17 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sadd_sasausf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], [[RESIZE]]
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sadd_sasausf() {
sa = sa + usf;
+}
- // With unsigned of larger width and smaller scale
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[ULF:%[0-9]+]] = load i32, i32* %ulf, align 4
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i41
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i41 [[SA_EXT]], 25
- // SIGNED-NEXT: [[ULF_EXT:%[a-z0-9]+]] = zext i32 [[ULF]] to i41
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i41 [[SA]], [[ULF_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i41 [[SUM]], 25
- // SIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i41 [[RESULT]] to i16
- // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i40
- // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i40 [[EXT_SA]], 24
- // UNSIGNED-NEXT: [[EXT_ULF:%[a-z0-9]+]] = zext i32 [[ULF]] to i40
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[SA]], [[EXT_ULF]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = ashr i40 [[SUM]], 24
- // UNSIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i40 [[RES]] to i16
- // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %sa, align 2
+// SIGNED-LABEL: @sadd_sasaulf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i41
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i41 [[RESIZE]], 25
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i41
+// SIGNED-NEXT: [[TMP2:%.*]] = add i41 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i41 [[TMP2]], 25
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i41 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sadd_sasaulf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 24
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i40 [[UPSCALE]], [[RESIZE1]]
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i40 [[TMP2]], 24
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[DOWNSCALE]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sadd_sasaulf() {
sa = sa + ulf;
-
- // Chained additions of the same signed type should result in the same
- // semantics width.
- // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[B:%[0-9]+]] = load i32, i32* %b, align 4
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[A]], [[B]]
- // CHECK-NEXT: [[C:%[0-9]+]] = load i32, i32* %c, align 4
- // CHECK-NEXT: [[SUM2:%[0-9]+]] = add i32 [[SUM]], [[C]]
- // CHECK-NEXT: [[D:%[0-9]+]] = load i32, i32* %d, align 4
- // CHECK-NEXT: [[SUM3:%[0-9]+]] = add i32 [[SUM2]], [[D]]
- // CHECK-NEXT: store i32 [[SUM3]], i32* %a, align 4
- a = a + b + c + d;
}
-void UnsignedAddition() {
- // CHECK-LABEL: UnsignedAddition
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
+// CHECK-LABEL: @sadd_aaaaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a2, align 4
+// CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* @a3, align 4
+// CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP2]], [[TMP3]]
+// CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* @a4, align 4
+// CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP4]], [[TMP5]]
+// CHECK-NEXT: store i32 [[TMP6]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sadd_aaaaa() {
+ a = a + a2 + a3 + a4;
+}
- unsigned short _Fract usf;
- unsigned _Fract uf;
- unsigned long _Fract ulf;
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USA2:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[USA]], [[USA2]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+// CHECK-LABEL: @uadd_usausausa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void uadd_usausausa() {
usa = usa + usa;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[EXT_USA:%[a-z0-9]+]] = zext i16 [[USA]] to i32
- // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[EXT_USA]], 8
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[USA]], [[UA]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %ua, align 4
+// CHECK-LABEL: @uadd_uausaua(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = add i32 [[UPSCALE]], [[TMP1]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @ua, align 4
+// CHECK-NEXT: ret void
+//
+void uadd_uausaua() {
ua = usa + ua;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
- // CHECK-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[USA]], [[EXT_USF]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+// CHECK-LABEL: @uadd_usausausf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// CHECK-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], [[RESIZE]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void uadd_usausausf() {
usa = usa + usf;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[UF:%[0-9]+]] = load i16, i16* %uf, align 2
- // CHECK-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i24
- // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i24 [[USA_EXT]], 8
- // CHECK-NEXT: [[UF_EXT:%[a-z0-9]+]] = zext i16 [[UF]] to i24
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i24 [[USA]], [[UF_EXT]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = lshr i24 [[SUM]], 8
- // CHECK-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
- // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %usa, align 2
+// CHECK-LABEL: @uadd_usausauf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i24
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i24
+// CHECK-NEXT: [[TMP2:%.*]] = add i24 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP2]], 8
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void uadd_usausauf() {
usa = usa + uf;
}
-void IntAddition() {
- // CHECK-LABEL: IntAddition
- short _Accum sa;
- _Accum a;
- unsigned short _Accum usa;
- _Sat short _Accum sa_sat;
- int i;
- unsigned int ui;
- long _Fract lf;
- _Bool b;
-
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i39
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i39 [[SA_EXT]], [[I]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+
+// CHECK-LABEL: @int_sasai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = add i39 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasai() {
sa = sa + i;
+}
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i40
- // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i40
- // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i40 [[UI_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i40 [[SA_EXT]], [[UI]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+// CHECK-LABEL: @int_sasaui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = add i40 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasaui() {
sa = sa + ui;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i40
- // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[USA_EXT]], [[I]]
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i39 [[USA_EXT]], [[I]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usausai(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = add i40 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausai(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i39 [[RESIZE]], [[UPSCALE]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausai() {
usa = usa + i;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[USA_EXT]], [[I]]
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
- // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i39 [[USA_EXT]], [[I]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usausaui(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = add i40 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausaui(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i39 [[RESIZE]], [[UPSCALE]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausaui() {
usa = usa + ui;
+}
- // CHECK: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
- // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[LF_EXT:%[a-z0-9]+]] = sext i32 [[LF]] to i64
- // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i64
- // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i64 [[UI_EXT]], 31
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i64 [[LF_EXT]], [[UI]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i64 [[SUM]] to i32
- // CHECK-NEXT: store i32 [[RES]], i32* %lf, align 4
+// CHECK-LABEL: @int_lflfui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i64
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE1]], 31
+// CHECK-NEXT: [[TMP2:%.*]] = add i64 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i64 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @lf, align 4
+// CHECK-NEXT: ret void
+//
+void int_lflfui() {
lf = lf + ui;
+}
- // CHECK: [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[BOOL:%[0-9]+]] = load i8, i8* %b, align 1
- // CHECK-NEXT: [[AS_BOOL:%[a-z0-9]+]] = trunc i8 [[BOOL]] to i1
- // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = zext i1 [[AS_BOOL]] to i32
- // CHECK-NEXT: [[ACCUM_EXT:%[a-z0-9]+]] = sext i32 [[ACCUM]] to i47
- // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = sext i32 [[BOOL_EXT]] to i47
- // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = shl i47 [[BOOL]], 15
- // CHECK-NEXT: [[SUM:%[0-9]+]] = add i47 [[ACCUM_EXT]], [[BOOL_EXT]]
- // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i47 [[SUM]] to i32
- // CHECK-NEXT: store i32 [[RESULT]], i32* %a, align 4
+// CHECK-LABEL: @int_aab(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @b, align 1
+// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = add i47 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void int_aab() {
a = a + b;
}
-void SaturatedAddition() {
- // CHECK-LABEL: SaturatedAddition
- short _Accum sa;
- _Accum a;
- long _Accum la;
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
-
- _Sat short _Accum sa_sat;
- _Sat _Accum a_sat;
- _Sat long _Accum la_sat;
- _Sat unsigned short _Accum usa_sat;
- _Sat unsigned _Accum ua_sat;
- _Sat unsigned long _Accum ula_sat;
- _Sat unsigned _Fract uf_sat;
-
- int i;
- unsigned int ui;
-
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.sadd.sat.i16(i16 [[SA]], i16
- // [[SA_SAT]])
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa_sat, align 2
+
+// CHECK-LABEL: @sat_sassasas(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP0]], i16 [[TMP1]])
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasas() {
sa_sat = sa + sa_sat;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.uadd.sat.i16(i16 [[USA]], i16 [[USA_SAT]])
- // SIGNED-NEXT: store i16 [[SUM]], i16* %usa_sat, align 2
- // UNSIGNED-NEXT: [[USA_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA]] to i15
- // UNSIGNED-NEXT: [[USA_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA_SAT]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.uadd.sat.i15(i15 [[USA_TRUNC]], i15 [[USA_SAT_TRUNC]])
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP0]], i16 [[TMP1]])
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusausas() {
usa_sat = usa + usa_sat;
+}
- // CHECK: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i32
- // SIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[USA_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i32 @llvm.uadd.sat.i32(i32 [[UA]], i32 [[USA]])
- // SIGNED-NEXT: store i32 [[SUM]], i32* %ua_sat, align 4
- // UNSIGNED-NEXT: [[UA_TRUNC:%[a-z0-9]+]] = trunc i32 [[UA]] to i31
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i31
- // UNSIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i31 [[USA_EXT]], 8
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i31 @llvm.uadd.sat.i31(i31 [[UA_TRUNC]], i31 [[USA]])
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i31 [[SUM]] to i32
- // UNSIGNED-NEXT: store i32 [[SUM_EXT]], i32* %ua_sat, align 4
+// SIGNED-LABEL: @sat_uasuausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP0]], i32 [[UPSCALE]])
+// SIGNED-NEXT: store i32 [[TMP2]], i32* @ua_sat, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_uasuausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i31
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i31 [[RESIZE1]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i31 @llvm.uadd.sat.i31(i31 [[RESIZE]], i31 [[UPSCALE]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i31 [[TMP2]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE2]], i32* @ua_sat, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sat_uasuausas() {
ua_sat = ua + usa_sat;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i39
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.sadd.sat.i39(i39 [[SA_SAT_EXT]], i39 [[I]])
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i39 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasi(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.sadd.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 -32768, i39 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasi() {
sa_sat = sa_sat + i;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i40
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.sadd.sat.i40(i40 [[SA_SAT_EXT]], i40 [[I]])
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 32767, i40 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 -32768, i40 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i40 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.sadd.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 32767, i40 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 -32768, i40 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasui() {
sa_sat = sa_sat + ui;
+}
- // CHECK: [[UF_SAT:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // CHECK-NEXT: [[UF_SAT2:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.uadd.sat.i16(i16 [[UF_SAT]], i16 [[UF_SAT2]])
- // SIGNED-NEXT: store i16 [[SUM]], i16* %uf_sat, align 2
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[UF_SAT]] to i15
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC2:%[a-z0-9]+]] = trunc i16 [[UF_SAT2]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.uadd.sat.i15(i15 [[UF_SAT_TRUNC]], i15 [[UF_SAT_TRUNC2]])
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %uf_sat, align 2
+// SIGNED-LABEL: @sat_ufsufsufs(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP0]], i16 [[TMP1]])
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @uf_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_ufsufsufs(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.uadd.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @uf_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_ufsufsufs() {
uf_sat = uf_sat + uf_sat;
+}
- // CHECK: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // 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.sadd.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
- // SIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[RESULT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i40 [[RESULT2]] to i16
- // 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.sadd.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
- // UNSIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[RESULT]]
- // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i39 [[RESULT2]] to i16
- // CHECK-NEXT: store i16 [[RESULT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusasi(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.sadd.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]])
+// SIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 65535, i40 [[TMP2]]
+// SIGNED-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 0, i40 [[SATMAX]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusasi(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.sadd.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]])
+// UNSIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// UNSIGNED-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 0, i39 [[SATMAX]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusasi() {
usa_sat = usa_sat + i;
}
diff --git a/clang/test/Frontend/fixed_point_add_const.c b/clang/test/Frontend/fixed_point_add_const.c
new file mode 100644
index 000000000000..6c8c7cb86b5d
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_add_const.c
@@ -0,0 +1,54 @@
+// 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
+
+// Addition between
diff erent fixed point types
+short _Accum sa_const = 1.0hk + 2.0hk;
+// CHECK-DAG: @sa_const = {{.*}}global i16 384, align 2
+_Accum a_const = 1.0hk + 2.0k;
+// CHECK-DAG: @a_const = {{.*}}global i32 98304, align 4
+long _Accum la_const = 1.0hk + 2.0lk;
+// CHECK-DAG: @la_const = {{.*}}global i64 6442450944, align 8
+short _Accum sa_const2 = 0.5hr + 2.0hk;
+// CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const3 = 0.5r + 2.0hk;
+// CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
+short _Accum sa_const4 = 0.5lr + 2.0hk;
+// CHECK-DAG: @sa_const4 = {{.*}}global i16 320, align 2
+
+// Unsigned addition
+unsigned short _Accum usa_const = 1.0uhk + 2.0uhk;
+// SIGNED-DAG: @usa_const = {{.*}}global i16 768, align 2
+// UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2
+
+// Unsigned + signed
+short _Accum sa_const5 = 1.0uhk + 2.0hk;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 384, align 2
+
+// Addition with negative number
+short _Accum sa_const6 = 0.5hr + (-2.0hk);
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -192, align 2
+
+// Int addition
+unsigned short _Accum usa_const2 = 2 + 0.5uhk;
+// SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2
+// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const7 = 2 + (-0.5hk);
+// CHECK-DAG: @sa_const7 = {{.*}}global i16 192, align 2
+short _Accum sa_const8 = 257 + (-2.0hk);
+// CHECK-DAG: @sa_const8 = {{.*}}global i16 32640, align 2
+long _Fract lf_const = -0.5lr + 1;
+// CHECK-DAG: @lf_const = {{.*}}global i32 1073741824, align 4
+
+// Saturated addition
+_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;
+// SIGNED-DAG: @sat_usa_const = {{.*}}global i16 -1, align 2
+// 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;
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// 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
diff --git a/clang/test/Frontend/fixed_point_compound.c b/clang/test/Frontend/fixed_point_compound.c
index d470d5c22e80..4a44d0ae95a2 100644
--- a/clang/test/Frontend/fixed_point_compound.c
+++ b/clang/test/Frontend/fixed_point_compound.c
@@ -1,3 +1,4 @@
+// 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 -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
@@ -16,9 +17,9 @@ unsigned int u;
signed char c;
-// CHECK-LABEL: @Addition(
-void Addition() {
-// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-LABEL: @add_shfa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[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
@@ -26,349 +27,543 @@ void Addition() {
// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP2]], 8
// CHECK-NEXT: [[RESIZE1:%.*]] = trunc i32 [[DOWNSCALE]] to i8
// CHECK-NEXT: store i8 [[RESIZE1]], i8* @shf, align 1
+// CHECK-NEXT: ret void
+//
+void add_shfa() {
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
+// SIGNED-LABEL: @add_auf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = add i33 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_auf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], [[RESIZE]]
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void add_auf() {
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
+// CHECK-LABEL: @add_ufula(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @ula, align 8
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i64
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 16
+// CHECK-NEXT: [[TMP2:%.*]] = add i64 [[UPSCALE]], [[TMP0]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = lshr i64 [[TMP2]], 16
+// CHECK-NEXT: [[RESIZE1:%.*]] = trunc i64 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE1]], i16* @uf, align 2
+// CHECK-NEXT: ret void
+//
+void add_ufula() {
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
+// SIGNED-LABEL: @add_ulashf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @shf, align 1
+// SIGNED-NEXT: [[TMP1:%.*]] = load i64, i64* @ula, align 8
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i64 [[TMP1]] to i65
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i8 [[TMP0]] to i65
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i65 [[RESIZE1]], 25
+// SIGNED-NEXT: [[TMP2:%.*]] = add i65 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i65 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i65 [[DOWNSCALE]] to i64
+// SIGNED-NEXT: [[UPSCALE3:%.*]] = shl i64 [[RESIZE2]], 1
+// SIGNED-NEXT: store i64 [[UPSCALE3]], i64* @ula, align 8
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_ulashf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @shf, align 1
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i64, i64* @ula, align 8
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i64
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 24
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[UPSCALE]]
+// UNSIGNED-NEXT: store i64 [[TMP2]], i64* @ula, align 8
+// UNSIGNED-NEXT: ret void
+//
+void add_ulashf() {
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
+// SIGNED-LABEL: @add_ufshf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @shf, align 1
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i17
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i8 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE1]], 9
+// SIGNED-NEXT: [[TMP2:%.*]] = add i17 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: [[UPSCALE3:%.*]] = shl i16 [[RESIZE2]], 1
+// SIGNED-NEXT: store i16 [[UPSCALE3]], i16* @uf, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_ufshf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @shf, align 1
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i16
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i16 [[TMP1]], [[UPSCALE]]
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @uf, align 2
+// UNSIGNED-NEXT: ret void
+//
+void add_ufshf() {
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: [[UPSCALE24:%.*]] = shl i32 [[RESIZE23]], 8
-// CHECK-NEXT: [[TMP17:%.*]] = add i32 [[TMP16]], [[UPSCALE24]]
-// CHECK-NEXT: store i32 [[TMP17]], i32* @a, align 4
+// CHECK-LABEL: @add_ashf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* @shf, align 1
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], [[UPSCALE]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void add_ashf() {
a += shf;
+}
-// CHECK: [[TMP18:%.*]] = load i32, i32* @i, align 4
-// CHECK-NEXT: [[TMP19:%.*]] = load i32, i32* @a, align 4
-// CHECK-NEXT: [[RESIZE25:%.*]] = sext i32 [[TMP19]] to i47
-// CHECK-NEXT: [[RESIZE26:%.*]] = sext i32 [[TMP18]] to i47
-// CHECK-NEXT: [[UPSCALE27:%.*]] = shl i47 [[RESIZE26]], 15
-// CHECK-NEXT: [[TMP20:%.*]] = add i47 [[RESIZE25]], [[UPSCALE27]]
-// CHECK-NEXT: [[RESIZE28:%.*]] = trunc i47 [[TMP20]] to i32
-// CHECK-NEXT: store i32 [[RESIZE28]], i32* @a, align 4
+// CHECK-LABEL: @add_ai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = add i47 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void add_ai() {
a += i;
+}
-// CHECK: [[TMP21:%.*]] = load i32, i32* @u, align 4
-// CHECK-NEXT: [[TMP22:%.*]] = load i32, i32* @a, align 4
-// CHECK-NEXT: [[RESIZE29:%.*]] = sext i32 [[TMP22]] to i48
-// CHECK-NEXT: [[RESIZE30:%.*]] = zext i32 [[TMP21]] to i48
-// CHECK-NEXT: [[UPSCALE31:%.*]] = shl i48 [[RESIZE30]], 15
-// CHECK-NEXT: [[TMP23:%.*]] = add i48 [[RESIZE29]], [[UPSCALE31]]
-// CHECK-NEXT: [[RESIZE32:%.*]] = trunc i48 [[TMP23]] to i32
-// CHECK-NEXT: store i32 [[RESIZE32]], i32* @a, align 4
+// CHECK-LABEL: @add_au(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @u, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i48
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP0]] to i48
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = add i48 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i48 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void add_au() {
a += u;
+}
-// CHECK: [[TMP24:%.*]] = load i32, i32* @i, align 4
-// CHECK-NEXT: [[TMP25:%.*]] = load i64, i64* @ula, align 8
-// SIGNED-NEXT: [[RESIZE33:%.*]] = zext i64 [[TMP25]] to i65
-// SIGNED-NEXT: [[RESIZE34:%.*]] = sext i32 [[TMP24]] to i65
-// SIGNED-NEXT: [[UPSCALE35:%.*]] = shl i65 [[RESIZE34]], 32
-// SIGNED-NEXT: [[TMP26:%.*]] = add i65 [[RESIZE33]], [[UPSCALE35]]
-// SIGNED-NEXT: [[RESIZE36:%.*]] = trunc i65 [[TMP26]] to i64
-// SIGNED-NEXT: store i64 [[RESIZE36]], i64* @ula, align 8
-// UNSIGNED-NEXT: [[RESIZE21:%.*]] = sext i32 [[TMP24]] to i64
-// UNSIGNED-NEXT: [[UPSCALE22:%.*]] = shl i64 [[RESIZE21]], 31
-// UNSIGNED-NEXT: [[TMP26:%.*]] = add i64 [[TMP25]], [[UPSCALE22]]
-// UNSIGNED-NEXT: store i64 [[TMP26]], i64* @ula, align 8
+// SIGNED-LABEL: @add_ulai(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i64, i64* @ula, align 8
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i64 [[TMP1]] to i65
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i65
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i65 [[RESIZE1]], 32
+// SIGNED-NEXT: [[TMP2:%.*]] = add i65 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i65 [[TMP2]] to i64
+// SIGNED-NEXT: store i64 [[RESIZE2]], i64* @ula, align 8
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_ulai(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i64, i64* @ula, align 8
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 31
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[UPSCALE]]
+// UNSIGNED-NEXT: store i64 [[TMP2]], i64* @ula, align 8
+// UNSIGNED-NEXT: ret void
+//
+void add_ulai() {
ula += i;
+}
-// CHECK: [[TMP27:%.*]] = load i64, i64* @ula, align 8
-// CHECK-NEXT: [[TMP28:%.*]] = load i32, i32* @i, align 4
-// SIGNED-NEXT: [[RESIZE37:%.*]] = sext i32 [[TMP28]] to i65
-// SIGNED-NEXT: [[UPSCALE38:%.*]] = shl i65 [[RESIZE37]], 32
-// SIGNED-NEXT: [[RESIZE39:%.*]] = zext i64 [[TMP27]] to i65
-// SIGNED-NEXT: [[TMP29:%.*]] = add i65 [[UPSCALE38]], [[RESIZE39]]
-// SIGNED-NEXT: [[RESIZE40:%.*]] = trunc i65 [[TMP29]] to i64
-// SIGNED-NEXT: [[DOWNSCALE41:%.*]] = lshr i64 [[RESIZE40]], 32
-// SIGNED-NEXT: [[RESIZE42:%.*]] = trunc i64 [[DOWNSCALE41]] to i32
-// SIGNED-NEXT: store i32 [[RESIZE42]], i32* @i, align 4
-// UNSIGNED-NEXT: [[RESIZE23:%.*]] = sext i32 [[TMP28]] to i64
-// UNSIGNED-NEXT: [[UPSCALE24:%.*]] = shl i64 [[RESIZE23]], 31
-// UNSIGNED-NEXT: [[TMP29:%.*]] = add i64 [[UPSCALE24]], [[TMP27]]
-// UNSIGNED-NEXT: [[DOWNSCALE25:%.*]] = lshr i64 [[TMP29]], 31
-// UNSIGNED-NEXT: [[RESIZE26:%.*]] = trunc i64 [[DOWNSCALE25]] to i32
-// UNSIGNED-NEXT: store i32 [[RESIZE26]], i32* @i, align 4
+// SIGNED-LABEL: @add_iula(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i64, i64* @ula, align 8
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i65
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i65 [[RESIZE]], 32
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i64 [[TMP0]] to i65
+// SIGNED-NEXT: [[TMP2:%.*]] = add i65 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i65 [[TMP2]] to i64
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i64 [[RESIZE2]], 32
+// SIGNED-NEXT: [[RESIZE3:%.*]] = trunc i64 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE3]], i32* @i, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_iula(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i64, i64* @ula, align 8
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i64
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 31
+// UNSIGNED-NEXT: [[TMP2:%.*]] = add i64 [[UPSCALE]], [[TMP0]]
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i64 [[TMP2]], 31
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i64 [[DOWNSCALE]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE1]], i32* @i, align 4
+// UNSIGNED-NEXT: ret void
+//
+void add_iula() {
i += ula;
+}
-// CHECK: [[TMP30:%.*]] = load i32, i32* @a, align 4
-// CHECK-NEXT: [[TMP31:%.*]] = load i8, i8* @c, align 1
-// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP31]] to i32
-// CHECK-NEXT: [[RESIZE43:%.*]] = sext i32 [[CONV]] to i47
-// CHECK-NEXT: [[UPSCALE44:%.*]] = shl i47 [[RESIZE43]], 15
-// CHECK-NEXT: [[RESIZE45:%.*]] = sext i32 [[TMP30]] to i47
-// CHECK-NEXT: [[TMP32:%.*]] = add i47 [[UPSCALE44]], [[RESIZE45]]
-// CHECK-NEXT: [[RESIZE46:%.*]] = trunc i47 [[TMP32]] to i32
-// CHECK-NEXT: [[TMP33:%.*]] = icmp slt i32 [[RESIZE46]], 0
-// CHECK-NEXT: [[TMP34:%.*]] = add i32 [[RESIZE46]], 32767
-// CHECK-NEXT: [[TMP35:%.*]] = select i1 [[TMP33]], i32 [[TMP34]], i32 [[RESIZE46]]
-// CHECK-NEXT: [[DOWNSCALE47:%.*]] = ashr i32 [[TMP35]], 15
-// CHECK-NEXT: [[RESIZE48:%.*]] = trunc i32 [[DOWNSCALE47]] to i8
-// CHECK-NEXT: store i8 [[RESIZE48]], i8* @c, align 1
+// CHECK-LABEL: @add_ca(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @c, align 1
+// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = add i47 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[RESIZE2]], 0
+// CHECK-NEXT: [[TMP4:%.*]] = add i32 [[RESIZE2]], 32767
+// CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], i32 [[TMP4]], i32 [[RESIZE2]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP5]], 15
+// CHECK-NEXT: [[RESIZE3:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT: store i8 [[RESIZE3]], i8* @c, align 1
+// CHECK-NEXT: ret void
+//
+void add_ca() {
c += a;
+}
-// CHECK: [[TMP36:%.*]] = load i32, i32* @i, align 4
-// CHECK-NEXT: [[TMP37:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[RESIZE47:%.*]] = sext i32 [[TMP37]] to i47
-// CHECK-NEXT: [[RESIZE48:%.*]] = sext i32 [[TMP36]] to i47
-// CHECK-NEXT: [[UPSCALE49:%.*]] = shl i47 [[RESIZE48]], 15
-// CHECK-NEXT: [[TMP38:%.*]] = call i47 @llvm.sadd.sat.i47(i47 [[RESIZE47]], i47 [[UPSCALE49]])
-// CHECK-NEXT: [[TMP39:%.*]] = icmp sgt i47 [[TMP38]], 2147483647
-// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP39]], i47 2147483647, i47 [[TMP38]]
-// CHECK-NEXT: [[TMP40:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
-// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP40]], i47 -2147483648, i47 [[SATMAX]]
-// CHECK-NEXT: [[RESIZE50:%.*]] = trunc i47 [[SATMIN]] to i32
-// CHECK-NEXT: store i32 [[RESIZE50]], i32* @sa, align 4
+// CHECK-LABEL: @add_sai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.sadd.sat.i47(i47 [[RESIZE]], i47 [[UPSCALE]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i47 [[TMP2]], 2147483647
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i47 2147483647, i47 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i47 -2147483648, i47 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[SATMIN]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @sa, align 4
+// CHECK-NEXT: ret void
+//
+void add_sai() {
sa += i;
+}
-// CHECK: [[TMP41:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[TMP42:%.*]] = load i8, i8* @c, align 1
-// CHECK-NEXT: [[CONV53:%.*]] = sext i8 [[TMP42]] to i32
-// CHECK-NEXT: [[RESIZE54:%.*]] = sext i32 [[CONV53]] to i47
-// CHECK-NEXT: [[UPSCALE55:%.*]] = shl i47 [[RESIZE54]], 15
-// CHECK-NEXT: [[RESIZE56:%.*]] = sext i32 [[TMP41]] to i47
-// CHECK-NEXT: [[TMP43:%.*]] = call i47 @llvm.sadd.sat.i47(i47 [[UPSCALE55]], i47 [[RESIZE56]])
-// CHECK-NEXT: [[TMP44:%.*]] = icmp sgt i47 [[TMP43]], 2147483647
-// CHECK-NEXT: [[SATMAX57:%.*]] = select i1 [[TMP44]], i47 2147483647, i47 [[TMP43]]
-// CHECK-NEXT: [[TMP45:%.*]] = icmp slt i47 [[SATMAX57]], -2147483648
-// CHECK-NEXT: [[SATMIN58:%.*]] = select i1 [[TMP45]], i47 -2147483648, i47 [[SATMAX57]]
-// CHECK-NEXT: [[RESIZE59:%.*]] = trunc i47 [[SATMIN58]] to i32
-// CHECK-NEXT: [[TMP46:%.*]] = icmp slt i32 [[RESIZE59]], 0
-// CHECK-NEXT: [[TMP47:%.*]] = add i32 [[RESIZE59]], 32767
-// CHECK-NEXT: [[TMP48:%.*]] = select i1 [[TMP46]], i32 [[TMP47]], i32 [[RESIZE59]]
-// CHECK-NEXT: [[DOWNSCALE60:%.*]] = ashr i32 [[TMP48]], 15
-// CHECK-NEXT: [[RESIZE61:%.*]] = trunc i32 [[DOWNSCALE60]] to i8
-// CHECK-NEXT: store i8 [[RESIZE61]], i8* @c, align 1
+// CHECK-LABEL: @add_csa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @c, align 1
+// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.sadd.sat.i47(i47 [[UPSCALE]], i47 [[RESIZE1]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i47 [[TMP2]], 2147483647
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i47 2147483647, i47 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i47 -2147483648, i47 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[SATMIN]] to i32
+// CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[RESIZE2]], 0
+// CHECK-NEXT: [[TMP6:%.*]] = add i32 [[RESIZE2]], 32767
+// CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP5]], i32 [[TMP6]], i32 [[RESIZE2]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP7]], 15
+// CHECK-NEXT: [[RESIZE3:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT: store i8 [[RESIZE3]], i8* @c, align 1
+// CHECK-NEXT: ret void
+//
+void add_csa() {
c += sa;
+}
-// CHECK: [[TMP47:%.*]] = load i32, i32* @u, align 4
-// CHECK-NEXT: [[TMP48:%.*]] = load i64, i64* @sula, align 8
-// SIGNED-NEXT: [[RESIZE55:%.*]] = zext i32 [[TMP47]] to i64
-// SIGNED-NEXT: [[UPSCALE56:%.*]] = shl i64 [[RESIZE55]], 32
-// SIGNED-NEXT: [[TMP49:%.*]] = call i64 @llvm.uadd.sat.i64(i64 [[TMP48]], i64 [[UPSCALE56]])
-// SIGNED-NEXT: store i64 [[TMP49]], i64* @sula, align 8
-// UNSIGNED-NEXT: [[RESIZE39:%.*]] = trunc i64 [[TMP48]] to i63
-// UNSIGNED-NEXT: [[RESIZE40:%.*]] = zext i32 [[TMP47]] to i63
-// UNSIGNED-NEXT: [[UPSCALE41:%.*]] = shl i63 [[RESIZE40]], 31
-// UNSIGNED-NEXT: [[TMP49:%.*]] = call i63 @llvm.uadd.sat.i63(i63 [[RESIZE39]], i63 [[UPSCALE41]])
-// UNSIGNED-NEXT: [[RESIZE42:%.*]] = zext i63 [[TMP49]] to i64
-// UNSIGNED-NEXT: store i64 [[RESIZE42]], i64* @sula, align 8
+// SIGNED-LABEL: @add_sulau(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @u, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i64, i64* @sula, align 8
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i64
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 32
+// SIGNED-NEXT: [[TMP2:%.*]] = call i64 @llvm.uadd.sat.i64(i64 [[TMP1]], i64 [[UPSCALE]])
+// SIGNED-NEXT: store i64 [[TMP2]], i64* @sula, align 8
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_sulau(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @u, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i64, i64* @sula, align 8
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i64 [[TMP1]] to i63
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP0]] to i63
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i63 [[RESIZE1]], 31
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i63 @llvm.uadd.sat.i63(i63 [[RESIZE]], i63 [[UPSCALE]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i63 [[TMP2]] to i64
+// UNSIGNED-NEXT: store i64 [[RESIZE2]], i64* @sula, align 8
+// UNSIGNED-NEXT: ret void
+//
+void add_sulau() {
sula += u;
+}
-// CHECK: [[TMP50:%.*]] = load i16, i16* @suf, align 2
-// CHECK-NEXT: [[TMP51:%.*]] = load i8, i8* @sshf, align 1
-// SIGNED-NEXT: [[RESIZE57:%.*]] = sext i8 [[TMP51]] to i17
-// SIGNED-NEXT: [[UPSCALE58:%.*]] = shl i17 [[RESIZE57]], 9
-// SIGNED-NEXT: [[RESIZE59:%.*]] = zext i16 [[TMP50]] to i17
-// SIGNED-NEXT: [[TMP52:%.*]] = call i17 @llvm.sadd.sat.i17(i17 [[UPSCALE58]], i17 [[RESIZE59]])
-// SIGNED-NEXT: [[DOWNSCALE60:%.*]] = ashr i17 [[TMP52]], 1
-// SIGNED-NEXT: [[RESIZE61:%.*]] = trunc i17 [[DOWNSCALE60]] to i16
-// SIGNED-NEXT: [[DOWNSCALE62:%.*]] = ashr i16 [[RESIZE61]], 8
-// SIGNED-NEXT: [[RESIZE63:%.*]] = trunc i16 [[DOWNSCALE62]] to i8
-// SIGNED-NEXT: store i8 [[RESIZE63]], i8* @sshf, align 1
-// UNSIGNED-NEXT: [[RESIZE43:%.*]] = sext i8 [[TMP51]] to i16
-// UNSIGNED-NEXT: [[UPSCALE44:%.*]] = shl i16 [[RESIZE43]], 8
-// UNSIGNED-NEXT: [[TMP52:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[UPSCALE44]], i16 [[TMP50]])
-// UNSIGNED-NEXT: [[DOWNSCALE45:%.*]] = ashr i16 [[TMP52]], 8
-// UNSIGNED-NEXT: [[RESIZE46:%.*]] = trunc i16 [[DOWNSCALE45]] to i8
-// UNSIGNED-NEXT: store i8 [[RESIZE46]], i8* @sshf, align 1
+// SIGNED-LABEL: @add_sshsuf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @suf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @sshf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 9
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = call i17 @llvm.sadd.sat.i17(i17 [[UPSCALE]], i17 [[RESIZE1]])
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: [[DOWNSCALE3:%.*]] = ashr i16 [[RESIZE2]], 8
+// SIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[DOWNSCALE3]] to i8
+// SIGNED-NEXT: store i8 [[RESIZE4]], i8* @sshf, align 1
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @add_sshsuf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @suf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @sshf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[UPSCALE]], i16 [[TMP0]])
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i16 [[TMP2]], 8
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[DOWNSCALE]] to i8
+// UNSIGNED-NEXT: store i8 [[RESIZE1]], i8* @sshf, align 1
+// UNSIGNED-NEXT: ret void
+//
+void add_sshsuf() {
sshf += suf;
}
// Subtraction, multiplication and division should work about the same, so
// just make sure we can do them.
-// CHECK-LABEL: @Subtraction(
-void Subtraction() {
-// CHECK: [[TMP0:%.*]] = load i16, i16* @uf, align 2
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
-// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
-// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
-// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
-// SIGNED-NEXT: [[TMP2:%.*]] = sub i33 [[UPSCALE]], [[RESIZE1]]
-// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
-// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
-// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
-// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[RESIZE]]
-// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// SIGNED-LABEL: @sub_auf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i33 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sub_auf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[RESIZE]]
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sub_auf() {
a -= uf;
+}
-// CHECK: [[TMP3:%.*]] = load i32, i32* @i, align 4
-// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* @a, align 4
-// CHECK-NEXT: [[RESIZE3:%.*]] = sext i32 [[TMP4]] to i47
-// CHECK-NEXT: [[RESIZE4:%.*]] = sext i32 [[TMP3]] to i47
-// CHECK-NEXT: [[UPSCALE5:%.*]] = shl i47 [[RESIZE4]], 15
-// CHECK-NEXT: [[TMP5:%.*]] = sub i47 [[RESIZE3]], [[UPSCALE5]]
-// CHECK-NEXT: [[RESIZE6:%.*]] = trunc i47 [[TMP5]] to i32
-// CHECK-NEXT: store i32 [[RESIZE6]], i32* @a, align 4
+// CHECK-LABEL: @sub_ai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = sub i47 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sub_ai() {
a -= i;
+}
-// CHECK: [[TMP6:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* @c, align 1
-// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP7]] to i32
-// CHECK-NEXT: [[RESIZE7:%.*]] = sext i32 [[CONV]] to i47
-// CHECK-NEXT: [[UPSCALE8:%.*]] = shl i47 [[RESIZE7]], 15
-// CHECK-NEXT: [[RESIZE9:%.*]] = sext i32 [[TMP6]] to i47
-// CHECK-NEXT: [[TMP8:%.*]] = call i47 @llvm.ssub.sat.i47(i47 [[UPSCALE8]], i47 [[RESIZE9]])
-// CHECK-NEXT: [[TMP9:%.*]] = icmp sgt i47 [[TMP8]], 2147483647
-// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP9]], i47 2147483647, i47 [[TMP8]]
-// CHECK-NEXT: [[TMP10:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
-// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP10]], i47 -2147483648, i47 [[SATMAX]]
-// CHECK-NEXT: [[RESIZE10:%.*]] = trunc i47 [[SATMIN]] to i32
-// CHECK-NEXT: [[TMP11:%.*]] = icmp slt i32 [[RESIZE10]], 0
-// CHECK-NEXT: [[TMP12:%.*]] = add i32 [[RESIZE10]], 32767
-// CHECK-NEXT: [[TMP13:%.*]] = select i1 [[TMP11]], i32 [[TMP12]], i32 [[RESIZE10]]
-// CHECK-NEXT: [[DOWNSCALE11:%.*]] = ashr i32 [[TMP13]], 15
-// CHECK-NEXT: [[RESIZE12:%.*]] = trunc i32 [[DOWNSCALE11]] to i8
-// CHECK-NEXT: store i8 [[RESIZE12]], i8* @c, align 1
+// CHECK-LABEL: @sub_csa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @c, align 1
+// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.ssub.sat.i47(i47 [[UPSCALE]], i47 [[RESIZE1]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i47 [[TMP2]], 2147483647
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i47 2147483647, i47 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i47 -2147483648, i47 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[SATMIN]] to i32
+// CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[RESIZE2]], 0
+// CHECK-NEXT: [[TMP6:%.*]] = add i32 [[RESIZE2]], 32767
+// CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP5]], i32 [[TMP6]], i32 [[RESIZE2]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP7]], 15
+// CHECK-NEXT: [[RESIZE3:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT: store i8 [[RESIZE3]], i8* @c, align 1
+// CHECK-NEXT: ret void
+//
+void sub_csa() {
c -= sa;
}
-// CHECK-LABEL: @Multiplication(
-void Multiplication() {
-// CHECK: [[TMP0:%.*]] = load i16, i16* @uf, align 2
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
-// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
-// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
-// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
-// SIGNED-NEXT: [[TMP2:%.*]] = call i33 @llvm.smul.fix.i33(i33 [[UPSCALE]], i33 [[RESIZE1]], i32 16)
-// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
-// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
-// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
-// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP1]], i32 [[RESIZE]], i32 15)
-// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+
+// SIGNED-LABEL: @mul_auf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = call i33 @llvm.smul.fix.i33(i33 [[UPSCALE]], i33 [[RESIZE1]], i32 16)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @mul_auf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP1]], i32 [[RESIZE]], i32 15)
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void mul_auf() {
a *= uf;
+}
-// CHECK: [[TMP3:%.*]] = load i32, i32* @i, align 4
-// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* @a, align 4
-// CHECK-NEXT: [[RESIZE3:%.*]] = sext i32 [[TMP4]] to i47
-// CHECK-NEXT: [[RESIZE4:%.*]] = sext i32 [[TMP3]] to i47
-// CHECK-NEXT: [[UPSCALE5:%.*]] = shl i47 [[RESIZE4]], 15
-// CHECK-NEXT: [[TMP5:%.*]] = call i47 @llvm.smul.fix.i47(i47 [[RESIZE3]], i47 [[UPSCALE5]], i32 15)
-// CHECK-NEXT: [[RESIZE6:%.*]] = trunc i47 [[TMP5]] to i32
-// CHECK-NEXT: store i32 [[RESIZE6]], i32* @a, align 4
+// CHECK-LABEL: @mul_ai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.smul.fix.i47(i47 [[RESIZE]], i47 [[UPSCALE]], i32 15)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void mul_ai() {
a *= i;
+}
-// CHECK: [[TMP6:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* @c, align 1
-// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP7]] to i32
-// CHECK-NEXT: [[RESIZE7:%.*]] = sext i32 [[CONV]] to i47
-// CHECK-NEXT: [[UPSCALE8:%.*]] = shl i47 [[RESIZE7]], 15
-// CHECK-NEXT: [[RESIZE9:%.*]] = sext i32 [[TMP6]] to i47
-// CHECK-NEXT: [[TMP8:%.*]] = call i47 @llvm.smul.fix.sat.i47(i47 [[UPSCALE8]], i47 [[RESIZE9]], i32 15)
-// CHECK-NEXT: [[TMP9:%.*]] = icmp sgt i47 [[TMP8]], 2147483647
-// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP9]], i47 2147483647, i47 [[TMP8]]
-// CHECK-NEXT: [[TMP10:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
-// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP10]], i47 -2147483648, i47 [[SATMAX]]
-// CHECK-NEXT: [[RESIZE10:%.*]] = trunc i47 [[SATMIN]] to i32
-// CHECK-NEXT: [[TMP11:%.*]] = icmp slt i32 [[RESIZE10]], 0
-// CHECK-NEXT: [[TMP12:%.*]] = add i32 [[RESIZE10]], 32767
-// CHECK-NEXT: [[TMP13:%.*]] = select i1 [[TMP11]], i32 [[TMP12]], i32 [[RESIZE10]]
-// CHECK-NEXT: [[DOWNSCALE11:%.*]] = ashr i32 [[TMP13]], 15
-// CHECK-NEXT: [[RESIZE12:%.*]] = trunc i32 [[DOWNSCALE11]] to i8
-// CHECK-NEXT: store i8 [[RESIZE12]], i8* @c, align 1
+// CHECK-LABEL: @mul_csa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @c, align 1
+// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.smul.fix.sat.i47(i47 [[UPSCALE]], i47 [[RESIZE1]], i32 15)
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i47 [[TMP2]], 2147483647
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i47 2147483647, i47 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i47 -2147483648, i47 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[SATMIN]] to i32
+// CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[RESIZE2]], 0
+// CHECK-NEXT: [[TMP6:%.*]] = add i32 [[RESIZE2]], 32767
+// CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP5]], i32 [[TMP6]], i32 [[RESIZE2]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP7]], 15
+// CHECK-NEXT: [[RESIZE3:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT: store i8 [[RESIZE3]], i8* @c, align 1
+// CHECK-NEXT: ret void
+//
+void mul_csa() {
c *= sa;
}
-// CHECK-LABEL: @Division(
-void Division() {
-// CHECK: [[TMP0:%.*]] = load i16, i16* @uf, align 2
-// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
-// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
-// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
-// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
-// SIGNED-NEXT: [[TMP2:%.*]] = call i33 @llvm.sdiv.fix.i33(i33 [[UPSCALE]], i33 [[RESIZE1]], i32 16)
-// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
-// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
-// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
-// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP1]], i32 [[RESIZE]], i32 15)
-// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+
+// SIGNED-LABEL: @div_auf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = call i33 @llvm.sdiv.fix.i33(i33 [[UPSCALE]], i33 [[RESIZE1]], i32 16)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @div_auf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP1]], i32 [[RESIZE]], i32 15)
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void div_auf() {
a /= uf;
+}
-// CHECK: [[TMP3:%.*]] = load i32, i32* @i, align 4
-// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* @a, align 4
-// CHECK-NEXT: [[RESIZE3:%.*]] = sext i32 [[TMP4]] to i47
-// CHECK-NEXT: [[RESIZE4:%.*]] = sext i32 [[TMP3]] to i47
-// CHECK-NEXT: [[UPSCALE5:%.*]] = shl i47 [[RESIZE4]], 15
-// CHECK-NEXT: [[TMP5:%.*]] = call i47 @llvm.sdiv.fix.i47(i47 [[RESIZE3]], i47 [[UPSCALE5]], i32 15)
-// CHECK-NEXT: [[RESIZE6:%.*]] = trunc i47 [[TMP5]] to i32
-// CHECK-NEXT: store i32 [[RESIZE6]], i32* @a, align 4
+// CHECK-LABEL: @div_ai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.sdiv.fix.i47(i47 [[RESIZE]], i47 [[UPSCALE]], i32 15)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void div_ai() {
a /= i;
+}
-// CHECK: [[TMP6:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* @c, align 1
-// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP7]] to i32
-// CHECK-NEXT: [[RESIZE7:%.*]] = sext i32 [[CONV]] to i47
-// CHECK-NEXT: [[UPSCALE8:%.*]] = shl i47 [[RESIZE7]], 15
-// CHECK-NEXT: [[RESIZE9:%.*]] = sext i32 [[TMP6]] to i47
-// CHECK-NEXT: [[TMP8:%.*]] = call i47 @llvm.sdiv.fix.sat.i47(i47 [[UPSCALE8]], i47 [[RESIZE9]], i32 15)
-// CHECK-NEXT: [[TMP9:%.*]] = icmp sgt i47 [[TMP8]], 2147483647
-// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP9]], i47 2147483647, i47 [[TMP8]]
-// CHECK-NEXT: [[TMP10:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
-// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP10]], i47 -2147483648, i47 [[SATMAX]]
-// CHECK-NEXT: [[RESIZE10:%.*]] = trunc i47 [[SATMIN]] to i32
-// CHECK-NEXT: [[TMP11:%.*]] = icmp slt i32 [[RESIZE10]], 0
-// CHECK-NEXT: [[TMP12:%.*]] = add i32 [[RESIZE10]], 32767
-// CHECK-NEXT: [[TMP13:%.*]] = select i1 [[TMP11]], i32 [[TMP12]], i32 [[RESIZE10]]
-// CHECK-NEXT: [[DOWNSCALE11:%.*]] = ashr i32 [[TMP13]], 15
-// CHECK-NEXT: [[RESIZE12:%.*]] = trunc i32 [[DOWNSCALE11]] to i8
-// CHECK-NEXT: store i8 [[RESIZE12]], i8* @c, align 1
+// CHECK-LABEL: @div_csa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @c, align 1
+// CHECK-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.sdiv.fix.sat.i47(i47 [[UPSCALE]], i47 [[RESIZE1]], i32 15)
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i47 [[TMP2]], 2147483647
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i47 2147483647, i47 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i47 [[SATMAX]], -2147483648
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i47 -2147483648, i47 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[SATMIN]] to i32
+// CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[RESIZE2]], 0
+// CHECK-NEXT: [[TMP6:%.*]] = add i32 [[RESIZE2]], 32767
+// CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP5]], i32 [[TMP6]], i32 [[RESIZE2]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP7]], 15
+// CHECK-NEXT: [[RESIZE3:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT: store i8 [[RESIZE3]], i8* @c, align 1
+// CHECK-NEXT: ret void
+//
+void div_csa() {
c /= sa;
}
diff --git a/clang/test/Frontend/fixed_point_div.c b/clang/test/Frontend/fixed_point_div.c
index b18ba59ae735..b77a13cafb3f 100644
--- a/clang/test/Frontend/fixed_point_div.c
+++ b/clang/test/Frontend/fixed_point_div.c
@@ -1,497 +1,681 @@
+// 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 -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
-// Division between
diff erent 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
-short _Accum sa_const15 = -0.0078125hk / 255.28125hk;
-// CHECK-DAG: @sa_const15 = {{.*}}global i16 -1, align 2
-
-void SignedDivision() {
- // CHECK-LABEL: SignedDivision
- 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.sdiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
- // CHECK-NEXT: store i16 [[TMP2]], i16* %sa, align 2
+short _Accum sa;
+_Accum a, a2, a3, a4;
+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;
+
+_Sat short _Accum sa_sat;
+_Sat _Accum a_sat;
+_Sat long _Accum la_sat;
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned _Accum ua_sat;
+_Sat unsigned long _Accum ula_sat;
+_Sat unsigned _Fract uf_sat;
+
+int i;
+unsigned int ui;
+_Bool b;
+
+// CHECK-LABEL: @sdiv_sasasa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.sdiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void sdiv_sasasa() {
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.sdiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP4]], i32 15)
- // CHECK-NEXT: store i32 [[TMP5]], i32* %a, align 4
+// CHECK-LABEL: @sdiv_asaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 15)
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sdiv_asaa() {
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.sdiv.fix.i16(i16 [[TMP6]], i16 [[RESIZE1]], i32 7)
- // CHECK-NEXT: store i16 [[TMP8]], i16* %sa, align 2
+// CHECK-LABEL: @sdiv_sasasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i16
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.sdiv.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 7)
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void sdiv_sasasf() {
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.sdiv.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
+// CHECK-LABEL: @sdiv_sasaf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i24
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i16 [[TMP1]] to i24
+// CHECK-NEXT: [[TMP2:%.*]] = call i24 @llvm.sdiv.fix.i24(i24 [[UPSCALE]], i24 [[RESIZE1]], i32 15)
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i24 [[TMP2]], 8
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void sdiv_sasaf() {
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.sdiv.fix.i32(i32 [[TMP12]], i32 [[UPSCALE7]], i32 15)
- // CHECK-NEXT: store i32 [[TMP14]], i32* %a, align 4
+// CHECK-LABEL: @sdiv_aasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP0]], i32 [[UPSCALE]], i32 15)
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sdiv_aasf() {
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.sdiv.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
+// CHECK-LABEL: @sdiv_aalf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i48
+// CHECK-NEXT: [[TMP2:%.*]] = call i48 @llvm.sdiv.fix.i48(i48 [[UPSCALE]], i48 [[RESIZE1]], i32 31)
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i48 [[TMP2]], 16
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i48 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sdiv_aalf() {
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.sdiv.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 @llvm.sdiv.fix.i16(i16 [[TMP18]], i16 [[TMP19]], i32 7)
- // UNSIGNED-NEXT:store i16 [[TMP20]], i16* %sa, align 2
+// SIGNED-LABEL: @sdiv_sasausa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = call i17 @llvm.sdiv.fix.i17(i17 [[UPSCALE]], i17 [[RESIZE1]], i32 8)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sdiv_sasausa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.sdiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sdiv_sasausa() {
sa = sa / usa;
+}
- // With unsigned of larger scale
- // CHECK: [[TMP21:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP22:%.*]] = load i32, i32* %ua, align 4
- // SIGNED-NEXT: [[RESIZE18:%.*]] = sext i16 [[TMP21]] to i33
- // SIGNED-NEXT: [[UPSCALE19:%.*]] = shl i33 [[RESIZE18]], 9
- // SIGNED-NEXT: [[RESIZE20:%.*]] = zext i32 [[TMP22]] to i33
- // SIGNED-NEXT: [[TMP23:%.*]] = call i33 @llvm.sdiv.fix.i33(i33 [[UPSCALE19]], i33 [[RESIZE20]], i32 16)
- // SIGNED-NEXT: [[DOWNSCALE21:%.*]] = ashr i33 [[TMP23]], 1
- // SIGNED-NEXT: [[RESIZE22:%.*]] = trunc i33 [[DOWNSCALE21]] to i32
- // SIGNED-NEXT: store i32 [[RESIZE22]], i32* %a, align 4
- // UNSIGNED-NEXT:[[RESIZE13:%.*]] = sext i16 [[TMP21]] to i32
- // UNSIGNED-NEXT:[[UPSCALE14:%.*]] = shl i32 [[RESIZE13]], 8
- // UNSIGNED-NEXT:[[TMP23:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[UPSCALE14]], i32 [[TMP22]], i32 15)
- // UNSIGNED-NEXT:store i32 [[TMP23]], i32* %a, align 4
+// SIGNED-LABEL: @sdiv_asaua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 9
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = call i33 @llvm.sdiv.fix.i33(i33 [[UPSCALE]], i33 [[RESIZE1]], i32 16)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sdiv_asaua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 15)
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sdiv_asaua() {
a = sa / ua;
+}
- // With unsigned of smaller width
- // CHECK: [[TMP24:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP25:%.*]] = load i8, i8* %usf, align 1
- // SIGNED-NEXT: [[RESIZE23:%.*]] = sext i16 [[TMP24]] to i17
- // SIGNED-NEXT: [[UPSCALE24:%.*]] = shl i17 [[RESIZE23]], 1
- // SIGNED-NEXT: [[RESIZE25:%.*]] = zext i8 [[TMP25]] to i17
- // SIGNED-NEXT: [[TMP26:%.*]] = call i17 @llvm.sdiv.fix.i17(i17 [[UPSCALE24]], i17 [[RESIZE25]], i32 8)
- // SIGNED-NEXT: [[DOWNSCALE26:%.*]] = ashr i17 [[TMP26]], 1
- // SIGNED-NEXT: [[RESIZE27:%.*]] = trunc i17 [[DOWNSCALE26]] to i16
- // SIGNED-NEXT: store i16 [[RESIZE27]], i16* %sa, align 2
- // UNSIGNED-NEXT:[[RESIZE15:%.*]] = zext i8 [[TMP25]] to i16
- // UNSIGNED-NEXT:[[TMP26:%.*]] = call i16 @llvm.sdiv.fix.i16(i16 [[TMP24]], i16 [[RESIZE15]], i32 7)
- // UNSIGNED-NEXT:store i16 [[TMP26]], i16* %sa, align 2
+// SIGNED-LABEL: @sdiv_sasausf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i8 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = call i17 @llvm.sdiv.fix.i17(i17 [[UPSCALE]], i17 [[RESIZE1]], i32 8)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sdiv_sasausf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.sdiv.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sdiv_sasausf() {
sa = sa / usf;
+}
- // With unsigned of larger width and smaller scale
- // CHECK: [[TMP27:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP28:%.*]] = load i32, i32* %ulf, align 4
- // SIGNED-NEXT: [[RESIZE28:%.*]] = sext i16 [[TMP27]] to i41
- // SIGNED-NEXT: [[UPSCALE29:%.*]] = shl i41 [[RESIZE28]], 25
- // SIGNED-NEXT: [[RESIZE30:%.*]] = zext i32 [[TMP28]] to i41
- // SIGNED-NEXT: [[TMP29:%.*]] = call i41 @llvm.sdiv.fix.i41(i41 [[UPSCALE29]], i41 [[RESIZE30]], i32 32)
- // SIGNED-NEXT: [[DOWNSCALE31:%.*]] = ashr i41 [[TMP29]], 25
- // SIGNED-NEXT: [[RESIZE32:%.*]] = trunc i41 [[DOWNSCALE31]] to i16
- // SIGNED-NEXT: store i16 [[RESIZE32]], i16* %sa, align 2
- // UNSIGNED-NEXT:[[RESIZE16:%.*]] = sext i16 [[TMP27]] to i40
- // UNSIGNED-NEXT:[[UPSCALE17:%.*]] = shl i40 [[RESIZE16]], 24
- // UNSIGNED-NEXT:[[RESIZE18:%.*]] = zext i32 [[TMP28]] to i40
- // UNSIGNED-NEXT:[[TMP29:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[UPSCALE17]], i40 [[RESIZE18]], i32 31)
- // UNSIGNED-NEXT:[[DOWNSCALE19:%.*]] = ashr i40 [[TMP29]], 24
- // UNSIGNED-NEXT:[[RESIZE20:%.*]] = trunc i40 [[DOWNSCALE19]] to i16
- // UNSIGNED-NEXT:store i16 [[RESIZE20]], i16* %sa, align 2
+// SIGNED-LABEL: @sdiv_sasaulf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i41
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i41 [[RESIZE]], 25
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i41
+// SIGNED-NEXT: [[TMP2:%.*]] = call i41 @llvm.sdiv.fix.i41(i41 [[UPSCALE]], i41 [[RESIZE1]], i32 32)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i41 [[TMP2]], 25
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i41 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sdiv_sasaulf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 24
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[UPSCALE]], i40 [[RESIZE1]], i32 31)
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i40 [[TMP2]], 24
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[DOWNSCALE]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sdiv_sasaulf() {
sa = sa / ulf;
-
- // Chained divisions of the same signed type should result in the same
- // CHECK: [[TMP30:%.*]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[TMP31:%.*]] = load i32, i32* %b, align 4
- // CHECK-NEXT: [[TMP32:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP30]], i32 [[TMP31]], i32 15)
- // CHECK-NEXT: [[TMP33:%.*]] = load i32, i32* %c, align 4
- // CHECK-NEXT: [[TMP34:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP32]], i32 [[TMP33]], i32 15)
- // CHECK-NEXT: [[TMP35:%.*]] = load i32, i32* %d, align 4
- // CHECK-NEXT: [[TMP36:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP34]], i32 [[TMP35]], i32 15)
- // CHECK-NEXT: store i32 [[TMP36]], i32* %a, align 4
- a = a / b / c / d;
}
+// CHECK-LABEL: @sdiv_aaaaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a2, align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP0]], i32 [[TMP1]], i32 15)
+// CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* @a3, align 4
+// CHECK-NEXT: [[TMP4:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP2]], i32 [[TMP3]], i32 15)
+// CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* @a4, align 4
+// CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.sdiv.fix.i32(i32 [[TMP4]], i32 [[TMP5]], i32 15)
+// CHECK-NEXT: store i32 [[TMP6]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void sdiv_aaaaa() {
+ a = a / a2 / a3 / a4;
+}
-void UnsignedDivision() {
- // CHECK-LABEL: UnsignedDivision
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
-
- unsigned short _Fract usf;
- unsigned _Fract uf;
- unsigned long _Fract ulf;
- // CHECK: [[TMP0:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 8)
- // UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
- // CHECK-NEXT: store i16 [[TMP2]], i16* %usa, align 2
+// SIGNED-LABEL: @udiv_usausausa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 8)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @udiv_usausausa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void udiv_usausausa() {
usa = usa / usa;
+}
- // CHECK: [[TMP3:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP3]] to i32
- // CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
- // SIGNED-NEXT: [[TMP5:%.*]] = call i32 @llvm.udiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP4]], i32 16)
- // UNSIGNED-NEXT: [[TMP5:%.*]] = call i32 @llvm.udiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP4]], i32 15)
- // CHECK-NEXT: store i32 [[TMP5]], i32* %ua, align 4
+// SIGNED-LABEL: @udiv_uausaua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.udiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 16)
+// SIGNED-NEXT: store i32 [[TMP2]], i32* @ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @udiv_uausaua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.udiv.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 15)
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void udiv_uausaua() {
ua = usa / ua;
+}
- // CHECK: [[TMP6:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* %usf, align 1
- // CHECK-NEXT: [[RESIZE1:%.*]] = zext i8 [[TMP7]] to i16
- // SIGNED-NEXT: [[TMP8:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP6]], i16 [[RESIZE1]], i32 8)
- // UNSIGNED-NEXT: [[TMP8:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP6]], i16 [[RESIZE1]], i32 7)
- // CHECK-NEXT: store i16 [[TMP8]], i16* %usa, align 2
+// SIGNED-LABEL: @udiv_usausausf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 8)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @udiv_usausausf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void udiv_usausausf() {
usa = usa / usf;
+}
- // CHECK: [[TMP9:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP10:%.*]] = load i16, i16* %uf, align 2
- // CHECK-NEXT: [[RESIZE2:%.*]] = zext i16 [[TMP9]] to i24
- // CHECK-NEXT: [[UPSCALE3:%.*]] = shl i24 [[RESIZE2]], 8
- // CHECK-NEXT: [[RESIZE4:%.*]] = zext i16 [[TMP10]] to i24
- // SIGNED-NEXT: [[TMP11:%.*]] = call i24 @llvm.udiv.fix.i24(i24 [[UPSCALE3]], i24 [[RESIZE4]], i32 16)
- // UNSIGNED-NEXT: [[TMP11:%.*]] = call i24 @llvm.udiv.fix.i24(i24 [[UPSCALE3]], i24 [[RESIZE4]], i32 15)
- // CHECK-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP11]], 8
- // CHECK-NEXT: [[RESIZE5:%.*]] = trunc i24 [[DOWNSCALE]] to i16
- // CHECK-NEXT: store i16 [[RESIZE5]], i16* %usa, align 2
+// SIGNED-LABEL: @udiv_usausauf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i24
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i24
+// SIGNED-NEXT: [[TMP2:%.*]] = call i24 @llvm.udiv.fix.i24(i24 [[UPSCALE]], i24 [[RESIZE1]], i32 16)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP2]], 8
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @udiv_usausauf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i24
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i24
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i24 @llvm.udiv.fix.i24(i24 [[UPSCALE]], i24 [[RESIZE1]], i32 15)
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP2]], 8
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void udiv_usausauf() {
usa = usa / uf;
}
-void IntDivision() {
- // CHECK-LABEL: IntDivision
- short _Accum sa;
- _Accum a;
- unsigned short _Accum usa;
- int i;
- unsigned int ui;
- long _Fract lf;
- _Bool b;
-
- // CHECK: [[TMP0:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
- // CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
- // CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
- // CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.sdiv.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
- // CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
- // CHECK-NEXT: store i16 [[RESIZE2]], i16* %sa, align 2
+
+// CHECK-LABEL: @int_sasai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.sdiv.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasai() {
sa = sa / i;
+}
- // CHECK: [[TMP3:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[RESIZE3:%.*]] = sext i16 [[TMP3]] to i40
- // CHECK-NEXT: [[RESIZE4:%.*]] = zext i32 [[TMP4]] to i40
- // CHECK-NEXT: [[UPSCALE5:%.*]] = shl i40 [[RESIZE4]], 7
- // CHECK-NEXT: [[TMP5:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[RESIZE3]], i40 [[UPSCALE5]], i32 7)
- // CHECK-NEXT: [[RESIZE6:%.*]] = trunc i40 [[TMP5]] to i16
- // CHECK-NEXT: store i16 [[RESIZE6]], i16* %sa, align 2
+// CHECK-LABEL: @int_sasaui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasaui() {
sa = sa / ui;
+}
- // CHECK: [[TMP6:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* %i, align 4
- // 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.sdiv.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.sdiv.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
+// SIGNED-LABEL: @int_usausai(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 8)
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausai(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.sdiv.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausai() {
usa = usa / i;
+}
- // CHECK: [[TMP9:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* %ui, align 4
- // SIGNED-NEXT: [[RESIZE11:%.*]] = zext i16 [[TMP9]] to i40
- // SIGNED-NEXT: [[RESIZE12:%.*]] = zext i32 [[TMP10]] to i40
- // SIGNED-NEXT: [[UPSCALE13:%.*]] = shl i40 [[RESIZE12]], 8
- // SIGNED-NEXT: [[TMP11:%.*]] = call i40 @llvm.udiv.fix.i40(i40 [[RESIZE11]], i40 [[UPSCALE13]], i32 8)
- // SIGNED-NEXT: [[RESIZE14:%.*]] = trunc i40 [[TMP11]] to i16
- // UNSIGNED-NEXT: [[RESIZE11:%.*]] = zext i16 [[TMP9]] to i39
- // UNSIGNED-NEXT: [[RESIZE12:%.*]] = zext i32 [[TMP10]] to i39
- // UNSIGNED-NEXT: [[UPSCALE13:%.*]] = shl i39 [[RESIZE12]], 7
- // UNSIGNED-NEXT: [[TMP11:%.*]] = call i39 @llvm.udiv.fix.i39(i39 [[RESIZE11]], i39 [[UPSCALE13]], i32 7)
- // UNSIGNED-NEXT: [[RESIZE14:%.*]] = trunc i39 [[TMP11]] to i16
- // CHECK-NEXT: store i16 [[RESIZE14]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usausaui(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.udiv.fix.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 8)
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausaui(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.udiv.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausaui() {
usa = usa / ui;
+}
- // CHECK: [[TMP12:%.*]] = load i32, i32* %lf, align 4
- // CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[RESIZE15:%.*]] = sext i32 [[TMP12]] to i64
- // CHECK-NEXT: [[RESIZE16:%.*]] = zext i32 [[TMP13]] to i64
- // CHECK-NEXT: [[UPSCALE17:%.*]] = shl i64 [[RESIZE16]], 31
- // CHECK-NEXT: [[TMP14:%.*]] = call i64 @llvm.sdiv.fix.i64(i64 [[RESIZE15]], i64 [[UPSCALE17]], i32 31)
- // CHECK-NEXT: [[RESIZE18:%.*]] = trunc i64 [[TMP14]] to i32
- // CHECK-NEXT: store i32 [[RESIZE18]], i32* %lf, align 4
+// CHECK-LABEL: @int_lflfui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i64
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE1]], 31
+// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.sdiv.fix.i64(i64 [[RESIZE]], i64 [[UPSCALE]], i32 31)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i64 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @lf, align 4
+// CHECK-NEXT: ret void
+//
+void int_lflfui() {
lf = lf / ui;
+}
- // CHECK: [[TMP15:%.*]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[TMP16:%.*]] = load i8, i8* %b, align 1
- // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP16]] to i1
- // CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32
- // CHECK-NEXT: [[RESIZE19:%.*]] = sext i32 [[TMP15]] to i47
- // CHECK-NEXT: [[RESIZE20:%.*]] = sext i32 [[CONV]] to i47
- // CHECK-NEXT: [[UPSCALE21:%.*]] = shl i47 [[RESIZE20]], 15
- // CHECK-NEXT: [[TMP17:%.*]] = call i47 @llvm.sdiv.fix.i47(i47 [[RESIZE19]], i47 [[UPSCALE21]], i32 15)
- // CHECK-NEXT: [[RESIZE22:%.*]] = trunc i47 [[TMP17]] to i32
- // CHECK-NEXT: store i32 [[RESIZE22]], i32* %a, align 4
+// CHECK-LABEL: @int_aab(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @b, align 1
+// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.sdiv.fix.i47(i47 [[RESIZE]], i47 [[UPSCALE]], i32 15)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void int_aab() {
a = a / b;
+}
- // CHECK: [[TMP18:%.*]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[TMP19:%.*]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[RESIZE23:%.*]] = sext i32 [[TMP18]] to i47
- // CHECK-NEXT: [[UPSCALE24:%.*]] = shl i47 [[RESIZE23]], 15
- // CHECK-NEXT: [[RESIZE25:%.*]] = sext i32 [[TMP19]] to i47
- // CHECK-NEXT: [[TMP20:%.*]] = call i47 @llvm.sdiv.fix.i47(i47 [[UPSCALE24]], i47 [[RESIZE25]], i32 15)
- // CHECK-NEXT: [[RESIZE26:%.*]] = trunc i47 [[TMP20]] to i32
- // CHECK-NEXT: store i32 [[RESIZE26]], i32* %a, align 4
+// CHECK-LABEL: @int_aia(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.sdiv.fix.i47(i47 [[UPSCALE]], i47 [[RESIZE1]], i32 15)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void int_aia() {
a = i / a;
+}
- // CHECK: [[TMP21:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[TMP22:%.*]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[RESIZE27:%.*]] = zext i32 [[TMP21]] to i40
- // SIGNED-NEXT: [[UPSCALE28:%.*]] = shl i40 [[RESIZE27]], 8
- // SIGNED-NEXT: [[RESIZE29:%.*]] = zext i16 [[TMP22]] to i40
- // SIGNED-NEXT: [[TMP23:%.*]] = call i40 @llvm.udiv.fix.i40(i40 [[UPSCALE28]], i40 [[RESIZE29]], i32 8)
- // SIGNED-NEXT: [[RESIZE30:%.*]] = trunc i40 [[TMP23]] to i16
- // UNSIGNED-NEXT: [[RESIZE27:%.*]] = zext i32 [[TMP21]] to i39
- // UNSIGNED-NEXT: [[UPSCALE28:%.*]] = shl i39 [[RESIZE27]], 7
- // UNSIGNED-NEXT: [[RESIZE29:%.*]] = zext i16 [[TMP22]] to i39
- // UNSIGNED-NEXT: [[TMP23:%.*]] = call i39 @llvm.udiv.fix.i39(i39 [[UPSCALE28]], i39 [[RESIZE29]], i32 7)
- // UNSIGNED-NEXT: [[RESIZE30:%.*]] = trunc i39 [[TMP23]] to i16
- // CHECK-NEXT: store i16 [[RESIZE30]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usauiusa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i40
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.udiv.fix.i40(i40 [[UPSCALE]], i40 [[RESIZE1]], i32 8)
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usauiusa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.udiv.fix.i39(i39 [[UPSCALE]], i39 [[RESIZE1]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usauiusa() {
usa = ui / usa;
+}
- // CHECK: [[TMP27:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[TMP28:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[RESIZE33:%.*]] = zext i32 [[TMP27]] to i40
- // CHECK-NEXT: [[UPSCALE34:%.*]] = shl i40 [[RESIZE33]], 7
- // CHECK-NEXT: [[RESIZE35:%.*]] = sext i16 [[TMP28]] to i40
- // CHECK-NEXT: [[TMP29:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[UPSCALE34]], i40 [[RESIZE35]], i32 7)
- // CHECK-NEXT: [[RESIZE36:%.*]] = trunc i40 [[TMP29]] to i16
- // CHECK-NEXT: store i16 [[RESIZE36]], i16* %sa, align 2
+// CHECK-LABEL: @int_sauisa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 7
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i16 [[TMP1]] to i40
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.sdiv.fix.i40(i40 [[UPSCALE]], i40 [[RESIZE1]], i32 7)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sauisa() {
sa = ui / sa;
}
-void SaturatedDivision() {
- // CHECK-LABEL: SaturatedDivision
- short _Accum sa;
- _Accum a;
- long _Accum la;
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
-
- _Sat short _Accum sa_sat;
- _Sat _Accum a_sat;
- _Sat long _Accum la_sat;
- _Sat unsigned short _Accum usa_sat;
- _Sat unsigned _Accum ua_sat;
- _Sat unsigned long _Accum ula_sat;
- _Sat unsigned _Fract uf_sat;
-
- int i;
- unsigned int ui;
-
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.sdiv.fix.sat.i16(i16 [[SA]], i16 [[SA_SAT]], i32 7)
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa_sat, align 2
+
+// CHECK-LABEL: @sat_sassasas(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.sdiv.fix.sat.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasas() {
sa_sat = sa / sa_sat;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.udiv.fix.sat.i16(i16 [[USA]], i16 [[USA_SAT]], i32 8)
- // SIGNED-NEXT: store i16 [[SUM]], i16* %usa_sat, align 2
- // UNSIGNED-NEXT: [[USA_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA]] to i15
- // UNSIGNED-NEXT: [[USA_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA_SAT]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.udiv.fix.sat.i15(i15 [[USA_TRUNC]], i15 [[USA_SAT_TRUNC]], i32 7)
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.sat.i16(i16 [[TMP0]], i16 [[TMP1]], i32 8)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.udiv.fix.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusausas() {
usa_sat = usa / usa_sat;
+}
- // CHECK: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i32
- // SIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[USA_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i32 @llvm.udiv.fix.sat.i32(i32 [[UA]], i32 [[USA]], i32 16)
- // SIGNED-NEXT: store i32 [[SUM]], i32* %ua_sat, align 4
- // UNSIGNED-NEXT: [[UA_TRUNC:%[a-z0-9]+]] = trunc i32 [[UA]] to i31
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i31
- // UNSIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i31 [[USA_EXT]], 8
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i31 @llvm.udiv.fix.sat.i31(i31 [[UA_TRUNC]], i31 [[USA]], i32 15)
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i31 [[SUM]] to i32
- // UNSIGNED-NEXT: store i32 [[SUM_EXT]], i32* %ua_sat, align 4
+// SIGNED-LABEL: @sat_uasuausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.udiv.fix.sat.i32(i32 [[TMP0]], i32 [[UPSCALE]], i32 16)
+// SIGNED-NEXT: store i32 [[TMP2]], i32* @ua_sat, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_uasuausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i31
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i31 [[RESIZE1]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i31 @llvm.udiv.fix.sat.i31(i31 [[RESIZE]], i31 [[UPSCALE]], i32 15)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i31 [[TMP2]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE2]], i32* @ua_sat, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sat_uasuausas() {
ua_sat = ua / usa_sat;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i39
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.sdiv.fix.sat.i39(i39 [[SA_SAT_EXT]], i39 [[I]], i32 7)
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i39 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasi(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.sdiv.fix.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 -32768, i39 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasi() {
sa_sat = sa_sat / i;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i40
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.sdiv.fix.sat.i40(i40 [[SA_SAT_EXT]], i40 [[I]], i32 7)
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 32767, i40 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 -32768, i40 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i40 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.sdiv.fix.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 32767, i40 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 -32768, i40 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasui() {
sa_sat = sa_sat / ui;
+}
- // CHECK: [[UF_SAT:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // CHECK-NEXT: [[UF_SAT2:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.udiv.fix.sat.i16(i16 [[UF_SAT]], i16 [[UF_SAT2]], i32 16)
- // SIGNED-NEXT: store i16 [[SUM]], i16* %uf_sat, align 2
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[UF_SAT]] to i15
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC2:%[a-z0-9]+]] = trunc i16 [[UF_SAT2]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.udiv.fix.sat.i15(i15 [[UF_SAT_TRUNC]], i15 [[UF_SAT_TRUNC2]], i32 15)
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %uf_sat, align 2
+// SIGNED-LABEL: @sat_ufsufsufs(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.udiv.fix.sat.i16(i16 [[TMP0]], i16 [[TMP1]], i32 16)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @uf_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_ufsufsufs(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.udiv.fix.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]], i32 15)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @uf_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_ufsufsufs() {
uf_sat = uf_sat / uf_sat;
+}
- // CHECK: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // 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.sdiv.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
- // SIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[RESULT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i40 [[RESULT2]] to i16
- // 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.sdiv.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
- // UNSIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[RESULT]]
- // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i39 [[RESULT2]] to i16
- // CHECK-NEXT: store i16 [[RESULT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusasi(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.sdiv.fix.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 8)
+// SIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 65535, i40 [[TMP2]]
+// SIGNED-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 0, i40 [[SATMAX]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusasi(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.sdiv.fix.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// UNSIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// UNSIGNED-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 0, i39 [[SATMAX]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusasi() {
usa_sat = usa_sat / i;
}
diff --git a/clang/test/Frontend/fixed_point_div_const.c b/clang/test/Frontend/fixed_point_div_const.c
new file mode 100644
index 000000000000..0f89605e7939
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_div_const.c
@@ -0,0 +1,77 @@
+// 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
diff erent 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;
+// SIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2
+// UNSIGNED-DAG: @usa_const = {{.*}}global i16 192, 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;
+// SIGNED-DAG: @usa_const2 = {{.*}}global i16 1024, align 2
+// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 512, 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);
+// SIGNED-DAG: @sat_usa_const = {{.*}}global i16 -1, align 2
+// 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-DAG: @sat_usa_const2 = {{.*}}global i16 0, 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
+short _Accum sa_const15 = -0.0078125hk / 255.28125hk;
+// CHECK-DAG: @sa_const15 = {{.*}}global i16 -1, align 2
diff --git a/clang/test/Frontend/fixed_point_mul.c b/clang/test/Frontend/fixed_point_mul.c
index 5e4741de1fe7..05d3f77d5a12 100644
--- a/clang/test/Frontend/fixed_point_mul.c
+++ b/clang/test/Frontend/fixed_point_mul.c
@@ -1,474 +1,681 @@
-// 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
diff erent 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;
- _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
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// 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;
+_Accum a, a2, a3, a4;
+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;
+
+_Sat short _Accum sa_sat;
+_Sat _Accum a_sat;
+_Sat long _Accum la_sat;
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned _Accum ua_sat;
+_Sat unsigned long _Accum ula_sat;
+_Sat unsigned _Fract uf_sat;
+
+int i;
+unsigned int ui;
+_Bool b;
+
+// CHECK-LABEL: @smul_sasasa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[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
+// CHECK-NEXT: ret void
+//
+void smul_sasasa() {
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
+// CHECK-LABEL: @smul_asaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 15)
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void smul_asaa() {
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
+// CHECK-LABEL: @smul_sasasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i16
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 7)
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void smul_sasasf() {
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
+// CHECK-LABEL: @smul_sasaf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i24
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i16 [[TMP1]] to i24
+// CHECK-NEXT: [[TMP2:%.*]] = call i24 @llvm.smul.fix.i24(i24 [[UPSCALE]], i24 [[RESIZE1]], i32 15)
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i24 [[TMP2]], 8
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void smul_sasaf() {
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
+// CHECK-LABEL: @smul_aasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP0]], i32 [[UPSCALE]], i32 15)
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void smul_aasf() {
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
+// CHECK-LABEL: @smul_aalf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i48
+// CHECK-NEXT: [[TMP2:%.*]] = call i48 @llvm.smul.fix.i48(i48 [[UPSCALE]], i48 [[RESIZE1]], i32 31)
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i48 [[TMP2]], 16
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i48 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void smul_aalf() {
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 @llvm.smul.fix.i16(i16 [[TMP18]], i16 [[TMP19]], i32 7)
- // UNSIGNED-NEXT:store i16 [[TMP20]], i16* %sa, align 2
+// SIGNED-LABEL: @smul_sasausa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = call i17 @llvm.smul.fix.i17(i17 [[UPSCALE]], i17 [[RESIZE1]], i32 8)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @smul_sasausa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void smul_sasausa() {
sa = sa * usa;
+}
- // With unsigned of larger scale
- // CHECK: [[TMP21:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP22:%.*]] = load i32, i32* %ua, align 4
- // SIGNED-NEXT: [[RESIZE18:%.*]] = sext i16 [[TMP21]] to i33
- // SIGNED-NEXT: [[UPSCALE19:%.*]] = shl i33 [[RESIZE18]], 9
- // SIGNED-NEXT: [[RESIZE20:%.*]] = zext i32 [[TMP22]] to i33
- // SIGNED-NEXT: [[TMP23:%.*]] = call i33 @llvm.smul.fix.i33(i33 [[UPSCALE19]], i33 [[RESIZE20]], i32 16)
- // SIGNED-NEXT: [[DOWNSCALE21:%.*]] = ashr i33 [[TMP23]], 1
- // SIGNED-NEXT: [[RESIZE22:%.*]] = trunc i33 [[DOWNSCALE21]] to i32
- // SIGNED-NEXT: store i32 [[RESIZE22]], i32* %a, align 4
- // UNSIGNED-NEXT:[[RESIZE13:%.*]] = sext i16 [[TMP21]] to i32
- // UNSIGNED-NEXT:[[UPSCALE14:%.*]] = shl i32 [[RESIZE13]], 8
- // UNSIGNED-NEXT:[[TMP23:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[UPSCALE14]], i32 [[TMP22]], i32 15)
- // UNSIGNED-NEXT:store i32 [[TMP23]], i32* %a, align 4
+// SIGNED-LABEL: @smul_asaua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 9
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = call i33 @llvm.smul.fix.i33(i33 [[UPSCALE]], i33 [[RESIZE1]], i32 16)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @smul_asaua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 15)
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void smul_asaua() {
a = sa * ua;
+}
- // With unsigned of smaller width
- // CHECK: [[TMP24:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP25:%.*]] = load i8, i8* %usf, align 1
- // SIGNED-NEXT: [[RESIZE23:%.*]] = sext i16 [[TMP24]] to i17
- // SIGNED-NEXT: [[UPSCALE24:%.*]] = shl i17 [[RESIZE23]], 1
- // SIGNED-NEXT: [[RESIZE25:%.*]] = zext i8 [[TMP25]] to i17
- // SIGNED-NEXT: [[TMP26:%.*]] = call i17 @llvm.smul.fix.i17(i17 [[UPSCALE24]], i17 [[RESIZE25]], i32 8)
- // SIGNED-NEXT: [[DOWNSCALE26:%.*]] = ashr i17 [[TMP26]], 1
- // SIGNED-NEXT: [[RESIZE27:%.*]] = trunc i17 [[DOWNSCALE26]] to i16
- // SIGNED-NEXT: store i16 [[RESIZE27]], i16* %sa, align 2
- // UNSIGNED-NEXT:[[RESIZE15:%.*]] = zext i8 [[TMP25]] to i16
- // UNSIGNED-NEXT:[[TMP26:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[TMP24]], i16 [[RESIZE15]], i32 7)
- // UNSIGNED-NEXT:store i16 [[TMP26]], i16* %sa, align 2
+// SIGNED-LABEL: @smul_sasausf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i8 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = call i17 @llvm.smul.fix.i17(i17 [[UPSCALE]], i17 [[RESIZE1]], i32 8)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @smul_sasausf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void smul_sasausf() {
sa = sa * usf;
+}
- // With unsigned of larger width and smaller scale
- // CHECK: [[TMP27:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP28:%.*]] = load i32, i32* %ulf, align 4
- // SIGNED-NEXT: [[RESIZE28:%.*]] = sext i16 [[TMP27]] to i41
- // SIGNED-NEXT: [[UPSCALE29:%.*]] = shl i41 [[RESIZE28]], 25
- // SIGNED-NEXT: [[RESIZE30:%.*]] = zext i32 [[TMP28]] to i41
- // SIGNED-NEXT: [[TMP29:%.*]] = call i41 @llvm.smul.fix.i41(i41 [[UPSCALE29]], i41 [[RESIZE30]], i32 32)
- // SIGNED-NEXT: [[DOWNSCALE31:%.*]] = ashr i41 [[TMP29]], 25
- // SIGNED-NEXT: [[RESIZE32:%.*]] = trunc i41 [[DOWNSCALE31]] to i16
- // SIGNED-NEXT: store i16 [[RESIZE32]], i16* %sa, align 2
- // UNSIGNED-NEXT:[[RESIZE16:%.*]] = sext i16 [[TMP27]] to i40
- // UNSIGNED-NEXT:[[UPSCALE17:%.*]] = shl i40 [[RESIZE16]], 24
- // UNSIGNED-NEXT:[[RESIZE18:%.*]] = zext i32 [[TMP28]] to i40
- // UNSIGNED-NEXT:[[TMP29:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[UPSCALE17]], i40 [[RESIZE18]], i32 31)
- // UNSIGNED-NEXT:[[DOWNSCALE19:%.*]] = ashr i40 [[TMP29]], 24
- // UNSIGNED-NEXT:[[RESIZE20:%.*]] = trunc i40 [[DOWNSCALE19]] to i16
- // UNSIGNED-NEXT:store i16 [[RESIZE20]], i16* %sa, align 2
+// SIGNED-LABEL: @smul_sasaulf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i41
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i41 [[RESIZE]], 25
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i41
+// SIGNED-NEXT: [[TMP2:%.*]] = call i41 @llvm.smul.fix.i41(i41 [[UPSCALE]], i41 [[RESIZE1]], i32 32)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i41 [[TMP2]], 25
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i41 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @smul_sasaulf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 24
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[UPSCALE]], i40 [[RESIZE1]], i32 31)
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i40 [[TMP2]], 24
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[DOWNSCALE]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void smul_sasaulf() {
sa = sa * ulf;
-
- // Chained multiplications of the same signed type should result in the same
- // CHECK: [[TMP30:%.*]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[TMP31:%.*]] = load i32, i32* %b, align 4
- // CHECK-NEXT: [[TMP32:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP30]], i32 [[TMP31]], i32 15)
- // CHECK-NEXT: [[TMP33:%.*]] = load i32, i32* %c, align 4
- // CHECK-NEXT: [[TMP34:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP32]], i32 [[TMP33]], i32 15)
- // CHECK-NEXT: [[TMP35:%.*]] = load i32, i32* %d, align 4
- // CHECK-NEXT: [[TMP36:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP34]], i32 [[TMP35]], i32 15)
- // CHECK-NEXT: store i32 [[TMP36]], i32* %a, align 4
- a = a * b * c * d;
}
+// CHECK-LABEL: @smul_aaaaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a2, align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP0]], i32 [[TMP1]], i32 15)
+// CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* @a3, align 4
+// CHECK-NEXT: [[TMP4:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP2]], i32 [[TMP3]], i32 15)
+// CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* @a4, align 4
+// CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.smul.fix.i32(i32 [[TMP4]], i32 [[TMP5]], i32 15)
+// CHECK-NEXT: store i32 [[TMP6]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void smul_aaaaa() {
+ a = a * a2 * a3 * a4;
+}
-void UnsignedMultiplication() {
- // CHECK-LABEL: UnsignedMultiplication
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
-
- unsigned short _Fract usf;
- unsigned _Fract uf;
- unsigned long _Fract ulf;
- // CHECK: [[TMP0:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 8)
- // UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
- // CHECK-NEXT: store i16 [[TMP2]], i16* %usa, align 2
+// SIGNED-LABEL: @umul_usausausa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 8)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @umul_usausausa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void umul_usausausa() {
usa = usa * usa;
+}
- // CHECK: [[TMP3:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP3]] to i32
- // CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
- // SIGNED-NEXT: [[TMP5:%.*]] = call i32 @llvm.umul.fix.i32(i32 [[UPSCALE]], i32 [[TMP4]], i32 16)
- // UNSIGNED-NEXT: [[TMP5:%.*]] = call i32 @llvm.umul.fix.i32(i32 [[UPSCALE]], i32 [[TMP4]], i32 15)
- // CHECK-NEXT: store i32 [[TMP5]], i32* %ua, align 4
+// SIGNED-LABEL: @umul_uausaua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.umul.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 16)
+// SIGNED-NEXT: store i32 [[TMP2]], i32* @ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @umul_uausaua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.umul.fix.i32(i32 [[UPSCALE]], i32 [[TMP1]], i32 15)
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void umul_uausaua() {
ua = usa * ua;
+}
- // CHECK: [[TMP6:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP7:%.*]] = load i8, i8* %usf, align 1
- // CHECK-NEXT: [[RESIZE1:%.*]] = zext i8 [[TMP7]] to i16
- // SIGNED-NEXT: [[TMP8:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP6]], i16 [[RESIZE1]], i32 8)
- // UNSIGNED-NEXT: [[TMP8:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP6]], i16 [[RESIZE1]], i32 7)
- // CHECK-NEXT: store i16 [[TMP8]], i16* %usa, align 2
+// SIGNED-LABEL: @umul_usausausf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 8)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @umul_usausausf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[TMP0]], i16 [[RESIZE]], i32 7)
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void umul_usausausf() {
usa = usa * usf;
+}
- // CHECK: [[TMP9:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP10:%.*]] = load i16, i16* %uf, align 2
- // CHECK-NEXT: [[RESIZE2:%.*]] = zext i16 [[TMP9]] to i24
- // CHECK-NEXT: [[UPSCALE3:%.*]] = shl i24 [[RESIZE2]], 8
- // CHECK-NEXT: [[RESIZE4:%.*]] = zext i16 [[TMP10]] to i24
- // SIGNED-NEXT: [[TMP11:%.*]] = call i24 @llvm.umul.fix.i24(i24 [[UPSCALE3]], i24 [[RESIZE4]], i32 16)
- // UNSIGNED-NEXT: [[TMP11:%.*]] = call i24 @llvm.umul.fix.i24(i24 [[UPSCALE3]], i24 [[RESIZE4]], i32 15)
- // CHECK-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP11]], 8
- // CHECK-NEXT: [[RESIZE5:%.*]] = trunc i24 [[DOWNSCALE]] to i16
- // CHECK-NEXT: store i16 [[RESIZE5]], i16* %usa, align 2
+// SIGNED-LABEL: @umul_usausauf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i24
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i24
+// SIGNED-NEXT: [[TMP2:%.*]] = call i24 @llvm.umul.fix.i24(i24 [[UPSCALE]], i24 [[RESIZE1]], i32 16)
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP2]], 8
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @umul_usausauf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i24
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i24
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i24 @llvm.umul.fix.i24(i24 [[UPSCALE]], i24 [[RESIZE1]], i32 15)
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP2]], 8
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void umul_usausauf() {
usa = usa * uf;
}
-void IntMultiplication() {
- // CHECK-LABEL: IntMultiplication
- short _Accum sa;
- _Accum a;
- unsigned short _Accum usa;
- int i;
- unsigned int ui;
- long _Fract lf;
- _Bool b;
-
- // CHECK: [[TMP0:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
- // CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
- // CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
- // CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.smul.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
- // CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
- // CHECK-NEXT: store i16 [[RESIZE2]], i16* %sa, align 2
+
+// CHECK-LABEL: @int_sasai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.smul.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasai() {
sa = sa * i;
+}
- // CHECK: [[TMP3:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[RESIZE3:%.*]] = sext i16 [[TMP3]] to i40
- // CHECK-NEXT: [[RESIZE4:%.*]] = zext i32 [[TMP4]] to i40
- // CHECK-NEXT: [[UPSCALE5:%.*]] = shl i40 [[RESIZE4]], 7
- // CHECK-NEXT: [[TMP5:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[RESIZE3]], i40 [[UPSCALE5]], i32 7)
- // CHECK-NEXT: [[RESIZE6:%.*]] = trunc i40 [[TMP5]] to i16
- // CHECK-NEXT: store i16 [[RESIZE6]], i16* %sa, align 2
+// CHECK-LABEL: @int_sasaui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasaui() {
sa = sa * ui;
+}
- // CHECK: [[TMP6:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* %i, align 4
- // 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.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.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
+// SIGNED-LABEL: @int_usausai(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 8)
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausai(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.smul.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausai() {
usa = usa * i;
+}
- // CHECK: [[TMP9:%.*]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* %ui, align 4
- // SIGNED-NEXT: [[RESIZE11:%.*]] = zext i16 [[TMP9]] to i40
- // SIGNED-NEXT: [[RESIZE12:%.*]] = zext i32 [[TMP10]] to i40
- // SIGNED-NEXT: [[UPSCALE13:%.*]] = shl i40 [[RESIZE12]], 8
- // SIGNED-NEXT: [[TMP11:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[RESIZE11]], i40 [[UPSCALE13]], i32 8)
- // SIGNED-NEXT: [[RESIZE14:%.*]] = trunc i40 [[TMP11]] to i16
- // UNSIGNED-NEXT: [[RESIZE11:%.*]] = zext i16 [[TMP9]] to i39
- // UNSIGNED-NEXT: [[RESIZE12:%.*]] = zext i32 [[TMP10]] to i39
- // UNSIGNED-NEXT: [[UPSCALE13:%.*]] = shl i39 [[RESIZE12]], 7
- // UNSIGNED-NEXT: [[TMP11:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[RESIZE11]], i39 [[UPSCALE13]], i32 7)
- // UNSIGNED-NEXT: [[RESIZE14:%.*]] = trunc i39 [[TMP11]] to i16
- // CHECK-NEXT: store i16 [[RESIZE14]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usausaui(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 8)
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausaui(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausaui() {
usa = usa * ui;
+}
- // CHECK: [[TMP12:%.*]] = load i32, i32* %lf, align 4
- // CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[RESIZE15:%.*]] = sext i32 [[TMP12]] to i64
- // CHECK-NEXT: [[RESIZE16:%.*]] = zext i32 [[TMP13]] to i64
- // CHECK-NEXT: [[UPSCALE17:%.*]] = shl i64 [[RESIZE16]], 31
- // CHECK-NEXT: [[TMP14:%.*]] = call i64 @llvm.smul.fix.i64(i64 [[RESIZE15]], i64 [[UPSCALE17]], i32 31)
- // CHECK-NEXT: [[RESIZE18:%.*]] = trunc i64 [[TMP14]] to i32
- // CHECK-NEXT: store i32 [[RESIZE18]], i32* %lf, align 4
+// CHECK-LABEL: @int_lflfui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i64
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE1]], 31
+// CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.smul.fix.i64(i64 [[RESIZE]], i64 [[UPSCALE]], i32 31)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i64 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @lf, align 4
+// CHECK-NEXT: ret void
+//
+void int_lflfui() {
lf = lf * ui;
+}
- // CHECK: [[TMP15:%.*]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[TMP16:%.*]] = load i8, i8* %b, align 1
- // CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP16]] to i1
- // CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32
- // CHECK-NEXT: [[RESIZE19:%.*]] = sext i32 [[TMP15]] to i47
- // CHECK-NEXT: [[RESIZE20:%.*]] = sext i32 [[CONV]] to i47
- // CHECK-NEXT: [[UPSCALE21:%.*]] = shl i47 [[RESIZE20]], 15
- // CHECK-NEXT: [[TMP17:%.*]] = call i47 @llvm.smul.fix.i47(i47 [[RESIZE19]], i47 [[UPSCALE21]], i32 15)
- // CHECK-NEXT: [[RESIZE22:%.*]] = trunc i47 [[TMP17]] to i32
- // CHECK-NEXT: store i32 [[RESIZE22]], i32* %a, align 4
+// CHECK-LABEL: @int_aab(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @b, align 1
+// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.smul.fix.i47(i47 [[RESIZE]], i47 [[UPSCALE]], i32 15)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void int_aab() {
a = a * b;
+}
- // CHECK: [[TMP18:%.*]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[TMP19:%.*]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[RESIZE23:%.*]] = sext i32 [[TMP18]] to i47
- // CHECK-NEXT: [[UPSCALE24:%.*]] = shl i47 [[RESIZE23]], 15
- // CHECK-NEXT: [[RESIZE25:%.*]] = sext i32 [[TMP19]] to i47
- // CHECK-NEXT: [[TMP20:%.*]] = call i47 @llvm.smul.fix.i47(i47 [[UPSCALE24]], i47 [[RESIZE25]], i32 15)
- // CHECK-NEXT: [[RESIZE26:%.*]] = trunc i47 [[TMP20]] to i32
- // CHECK-NEXT: store i32 [[RESIZE26]], i32* %a, align 4
+// CHECK-LABEL: @int_aia(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE]], 15
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i47
+// CHECK-NEXT: [[TMP2:%.*]] = call i47 @llvm.smul.fix.i47(i47 [[UPSCALE]], i47 [[RESIZE1]], i32 15)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void int_aia() {
a = i * a;
+}
- // CHECK: [[TMP21:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[TMP22:%.*]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[RESIZE27:%.*]] = zext i32 [[TMP21]] to i40
- // SIGNED-NEXT: [[UPSCALE28:%.*]] = shl i40 [[RESIZE27]], 8
- // SIGNED-NEXT: [[RESIZE29:%.*]] = zext i16 [[TMP22]] to i40
- // SIGNED-NEXT: [[TMP23:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[UPSCALE28]], i40 [[RESIZE29]], i32 8)
- // SIGNED-NEXT: [[RESIZE30:%.*]] = trunc i40 [[TMP23]] to i16
- // UNSIGNED-NEXT: [[RESIZE27:%.*]] = zext i32 [[TMP21]] to i39
- // UNSIGNED-NEXT: [[UPSCALE28:%.*]] = shl i39 [[RESIZE27]], 7
- // UNSIGNED-NEXT: [[RESIZE29:%.*]] = zext i16 [[TMP22]] to i39
- // UNSIGNED-NEXT: [[TMP23:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[UPSCALE28]], i39 [[RESIZE29]], i32 7)
- // UNSIGNED-NEXT: [[RESIZE30:%.*]] = trunc i39 [[TMP23]] to i16
- // CHECK-NEXT: store i16 [[RESIZE30]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usauiusa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i40
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.umul.fix.i40(i40 [[UPSCALE]], i40 [[RESIZE1]], i32 8)
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usauiusa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.umul.fix.i39(i39 [[UPSCALE]], i39 [[RESIZE1]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usauiusa() {
usa = ui * usa;
+}
- // CHECK: [[TMP27:%.*]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[TMP28:%.*]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[RESIZE33:%.*]] = zext i32 [[TMP27]] to i40
- // CHECK-NEXT: [[UPSCALE34:%.*]] = shl i40 [[RESIZE33]], 7
- // CHECK-NEXT: [[RESIZE35:%.*]] = sext i16 [[TMP28]] to i40
- // CHECK-NEXT: [[TMP29:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[UPSCALE34]], i40 [[RESIZE35]], i32 7)
- // CHECK-NEXT: [[RESIZE36:%.*]] = trunc i40 [[TMP29]] to i16
- // CHECK-NEXT: store i16 [[RESIZE36]], i16* %sa, align 2
+// CHECK-LABEL: @int_sauisa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 7
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i16 [[TMP1]] to i40
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.smul.fix.i40(i40 [[UPSCALE]], i40 [[RESIZE1]], i32 7)
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sauisa() {
sa = ui * sa;
}
-void SaturatedMultiplication() {
- // CHECK-LABEL: SaturatedMultiplication
- short _Accum sa;
- _Accum a;
- long _Accum la;
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
-
- _Sat short _Accum sa_sat;
- _Sat _Accum a_sat;
- _Sat long _Accum la_sat;
- _Sat unsigned short _Accum usa_sat;
- _Sat unsigned _Accum ua_sat;
- _Sat unsigned long _Accum ula_sat;
- _Sat unsigned _Fract uf_sat;
-
- int i;
- unsigned int ui;
-
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.smul.fix.sat.i16(i16 [[SA]], i16 [[SA_SAT]], i32 7)
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa_sat, align 2
+
+// CHECK-LABEL: @sat_sassasas(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.smul.fix.sat.i16(i16 [[TMP0]], i16 [[TMP1]], i32 7)
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasas() {
sa_sat = sa * sa_sat;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.umul.fix.sat.i16(i16 [[USA]], i16 [[USA_SAT]], i32 8)
- // SIGNED-NEXT: store i16 [[SUM]], i16* %usa_sat, align 2
- // UNSIGNED-NEXT: [[USA_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA]] to i15
- // UNSIGNED-NEXT: [[USA_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA_SAT]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.umul.fix.sat.i15(i15 [[USA_TRUNC]], i15 [[USA_SAT_TRUNC]], i32 7)
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.sat.i16(i16 [[TMP0]], i16 [[TMP1]], i32 8)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.umul.fix.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]], i32 7)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusausas() {
usa_sat = usa * usa_sat;
+}
- // CHECK: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i32
- // SIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[USA_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i32 @llvm.umul.fix.sat.i32(i32 [[UA]], i32 [[USA]], i32 16)
- // SIGNED-NEXT: store i32 [[SUM]], i32* %ua_sat, align 4
- // UNSIGNED-NEXT: [[UA_TRUNC:%[a-z0-9]+]] = trunc i32 [[UA]] to i31
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i31
- // UNSIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i31 [[USA_EXT]], 8
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i31 @llvm.umul.fix.sat.i31(i31 [[UA_TRUNC]], i31 [[USA]], i32 15)
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i31 [[SUM]] to i32
- // UNSIGNED-NEXT: store i32 [[SUM_EXT]], i32* %ua_sat, align 4
+// SIGNED-LABEL: @sat_uasuausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.umul.fix.sat.i32(i32 [[TMP0]], i32 [[UPSCALE]], i32 16)
+// SIGNED-NEXT: store i32 [[TMP2]], i32* @ua_sat, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_uasuausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i31
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i31 [[RESIZE1]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i31 @llvm.umul.fix.sat.i31(i31 [[RESIZE]], i31 [[UPSCALE]], i32 15)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i31 [[TMP2]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE2]], i32* @ua_sat, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sat_uasuausas() {
ua_sat = ua * usa_sat;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i39
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.smul.fix.sat.i39(i39 [[SA_SAT_EXT]], i39 [[I]], i32 7)
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i39 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasi(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.smul.fix.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 -32768, i39 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasi() {
sa_sat = sa_sat * i;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i40
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.smul.fix.sat.i40(i40 [[SA_SAT_EXT]], i40 [[I]], i32 7)
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 32767, i40 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 -32768, i40 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i40 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.smul.fix.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 7)
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 32767, i40 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 -32768, i40 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasui() {
sa_sat = sa_sat * ui;
+}
- // CHECK: [[UF_SAT:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // CHECK-NEXT: [[UF_SAT2:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.umul.fix.sat.i16(i16 [[UF_SAT]], i16 [[UF_SAT2]], i32 16)
- // SIGNED-NEXT: store i16 [[SUM]], i16* %uf_sat, align 2
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[UF_SAT]] to i15
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC2:%[a-z0-9]+]] = trunc i16 [[UF_SAT2]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.umul.fix.sat.i15(i15 [[UF_SAT_TRUNC]], i15 [[UF_SAT_TRUNC2]], i32 15)
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %uf_sat, align 2
+// SIGNED-LABEL: @sat_ufsufsufs(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.umul.fix.sat.i16(i16 [[TMP0]], i16 [[TMP1]], i32 16)
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @uf_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_ufsufsufs(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.umul.fix.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]], i32 15)
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @uf_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_ufsufsufs() {
uf_sat = uf_sat * uf_sat;
+}
- // CHECK: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // 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.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
- // SIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[RESULT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i40 [[RESULT2]] to i16
- // 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.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
- // UNSIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[RESULT]]
- // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i39 [[RESULT2]] to i16
- // CHECK-NEXT: store i16 [[RESULT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusasi(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.smul.fix.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]], i32 8)
+// SIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 65535, i40 [[TMP2]]
+// SIGNED-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 0, i40 [[SATMAX]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusasi(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.smul.fix.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]], i32 7)
+// UNSIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// UNSIGNED-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 0, i39 [[SATMAX]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusasi() {
usa_sat = usa_sat * i;
}
diff --git a/clang/test/Frontend/fixed_point_mul_const.c b/clang/test/Frontend/fixed_point_mul_const.c
new file mode 100644
index 000000000000..c5c863692897
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_mul_const.c
@@ -0,0 +1,54 @@
+// 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
diff erent 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;
+// SIGNED-DAG: @usa_const = {{.*}}global i16 512, align 2
+// UNSIGNED-DAG: @usa_const = {{.*}}global i16 256, 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;
+// SIGNED-DAG: @usa_const2 = {{.*}}global i16 13440, align 2
+// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 6720, 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;
+// SIGNED-DAG: @sat_usa_const = {{.*}}global i16 -1, align 2
+// 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;
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// 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
diff --git a/clang/test/Frontend/fixed_point_sub.c b/clang/test/Frontend/fixed_point_sub.c
index b30825e555be..4e97f5d1ec58 100644
--- a/clang/test/Frontend/fixed_point_sub.c
+++ b/clang/test/Frontend/fixed_point_sub.c
@@ -1,439 +1,581 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// 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
diff erent 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;
- _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: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SA2:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[SA2]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+short _Accum sa;
+_Accum a, a2, a3, a4;
+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;
+
+_Sat short _Accum sa_sat;
+_Sat _Accum a_sat;
+_Sat long _Accum la_sat;
+_Sat unsigned short _Accum usa_sat;
+_Sat unsigned _Accum ua_sat;
+_Sat unsigned long _Accum ula_sat;
+_Sat unsigned _Fract uf_sat;
+
+int i;
+unsigned int ui;
+_Bool b;
+
+// CHECK-LABEL: @ssub_sasasa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void ssub_sasasa() {
sa = sa - sa;
+}
- // To larger scale and larger width
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
- // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[SA]], [[A]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+// CHECK-LABEL: @ssub_asaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[UPSCALE]], [[TMP1]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void ssub_asaa() {
a = sa - a;
+}
- // To same scale and smaller width
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
- // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i16
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[EXT_SF]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+// CHECK-LABEL: @ssub_sasasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i16
+// CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[RESIZE]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void ssub_sasasf() {
sa = sa - sf;
+}
- // To smaller scale and same width.
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[F:%[0-9]+]] = load i16, i16* %f, align 2
- // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i24
- // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i24 [[EXT_SA]], 8
- // CHECK-NEXT: [[EXT_F:%[a-z0-9]+]] = sext i16 [[F]] to i24
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i24 [[SA]], [[EXT_F]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i24 [[SUM]], 8
- // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
- // CHECK-NEXT: store i16 [[TRUNC_RES]], i16* %sa, align 2
+// CHECK-LABEL: @ssub_sasaf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i24
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i16 [[TMP1]] to i24
+// CHECK-NEXT: [[TMP2:%.*]] = sub i24 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i24 [[TMP2]], 8
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void ssub_sasaf() {
sa = sa - f;
+}
- // To smaller scale and smaller width
- // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
- // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i32
- // CHECK-NEXT: [[SF:%[a-z0-9]+]] = shl i32 [[EXT_SF]], 8
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[A]], [[SF]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+// CHECK-LABEL: @ssub_aasf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[TMP0]], [[UPSCALE]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void ssub_aasf() {
a = a - sf;
+}
- // To larger scale and same width
- // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
- // CHECK-NEXT: [[EXT_A:%[a-z0-9]+]] = sext i32 [[A]] to i48
- // CHECK-NEXT: [[A:%[a-z0-9]+]] = shl i48 [[EXT_A]], 16
- // CHECK-NEXT: [[EXT_LF:%[a-z0-9]+]] = sext i32 [[LF]] to i48
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i48 [[A]], [[EXT_LF]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i48 [[SUM]], 16
- // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i48 [[RES]] to i32
- // CHECK-NEXT: store i32 [[TRUNC_RES]], i32* %a, align 4
+// CHECK-LABEL: @ssub_aalf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i48
+// CHECK-NEXT: [[TMP2:%.*]] = sub i48 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i48 [[TMP2]], 16
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i48 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void ssub_aalf() {
a = a - lf;
+}
- // With corresponding unsigned type
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i17
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i17 [[SA]], [[USA_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
- // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[USA]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+// SIGNED-LABEL: @ssub_sasausa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i17 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @ssub_sasausa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[TMP1]]
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void ssub_sasausa() {
sa = sa - usa;
+}
- // With unsigned of larger scale
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i32, i32* %ua, align 4
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i33
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i33 [[SA_EXT]], 9
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i32 [[USA]] to i33
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i33 [[SA]], [[USA_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i33 [[SUM]], 1
- // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i33 [[RESULT]] to i32
- // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
- // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i32 [[SA]], [[USA]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+// SIGNED-LABEL: @ssub_asaua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 9
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i33
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i33 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i33 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i33 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @ssub_asaua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i32 [[UPSCALE]], [[TMP1]]
+// UNSIGNED-NEXT: store i32 [[TMP2]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void ssub_asaua() {
a = sa - ua;
+}
- // With unsigned of smaller width
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
- // SIGNED-NEXT: [[USF_EXT:%[a-z0-9]+]] = zext i8 [[USF]] to i17
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i17 [[SA]], [[USF_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
- // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
- // UNSIGNED-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[EXT_USF]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+// SIGNED-LABEL: @ssub_sasausf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i17
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i17 [[RESIZE]], 1
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i8 [[TMP1]] to i17
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i17 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i17 [[TMP2]], 1
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i17 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @ssub_sasausf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[RESIZE]]
+// UNSIGNED-NEXT: store i16 [[TMP2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void ssub_sasausf() {
sa = sa - usf;
+}
- // With unsigned of larger width and smaller scale
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[ULF:%[0-9]+]] = load i32, i32* %ulf, align 4
- // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i41
- // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i41 [[SA_EXT]], 25
- // SIGNED-NEXT: [[ULF_EXT:%[a-z0-9]+]] = zext i32 [[ULF]] to i41
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i41 [[SA]], [[ULF_EXT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i41 [[SUM]], 25
- // SIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i41 [[RESULT]] to i16
- // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i40
- // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i40 [[EXT_SA]], 24
- // UNSIGNED-NEXT: [[EXT_ULF:%[a-z0-9]+]] = zext i32 [[ULF]] to i40
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i40 [[SA]], [[EXT_ULF]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = ashr i40 [[SUM]], 24
- // UNSIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i40 [[RES]] to i16
- // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %sa, align 2
+// SIGNED-LABEL: @ssub_sasaulf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i41
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i41 [[RESIZE]], 25
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i41
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i41 [[UPSCALE]], [[RESIZE1]]
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i41 [[TMP2]], 25
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i41 [[DOWNSCALE]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @ssub_sasaulf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ulf, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 24
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i40 [[UPSCALE]], [[RESIZE1]]
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i40 [[TMP2]], 24
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[DOWNSCALE]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void ssub_sasaulf() {
sa = sa - ulf;
-
- // Chained additions of the same signed type should result in the same
- // semantics width.
- // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[B:%[0-9]+]] = load i32, i32* %b, align 4
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[A]], [[B]]
- // CHECK-NEXT: [[C:%[0-9]+]] = load i32, i32* %c, align 4
- // CHECK-NEXT: [[SUM2:%[0-9]+]] = sub i32 [[SUM]], [[C]]
- // CHECK-NEXT: [[D:%[0-9]+]] = load i32, i32* %d, align 4
- // CHECK-NEXT: [[SUM3:%[0-9]+]] = sub i32 [[SUM2]], [[D]]
- // CHECK-NEXT: store i32 [[SUM3]], i32* %a, align 4
- a = a - b - c - d;
}
-void UnsignedSubtraction() {
- // CHECK-LABEL: UnsignedSubtraction
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
+// CHECK-LABEL: @ssub_aaaaa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @a2, align 4
+// CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* @a3, align 4
+// CHECK-NEXT: [[TMP4:%.*]] = sub i32 [[TMP2]], [[TMP3]]
+// CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* @a4, align 4
+// CHECK-NEXT: [[TMP6:%.*]] = sub i32 [[TMP4]], [[TMP5]]
+// CHECK-NEXT: store i32 [[TMP6]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void ssub_aaaaa() {
+ a = a - a2 - a3 - a4;
+}
- unsigned short _Fract usf;
- unsigned _Fract uf;
- unsigned long _Fract ulf;
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USA2:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[USA]], [[USA2]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+// CHECK-LABEL: @usub_usausausa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void usub_usausausa() {
usa = usa - usa;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[EXT_USA:%[a-z0-9]+]] = zext i16 [[USA]] to i32
- // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[EXT_USA]], 8
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[USA]], [[UA]]
- // CHECK-NEXT: store i32 [[SUM]], i32* %ua, align 4
+// CHECK-LABEL: @usub_uausaua(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ua, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[UPSCALE]], [[TMP1]]
+// CHECK-NEXT: store i32 [[TMP2]], i32* @ua, align 4
+// CHECK-NEXT: ret void
+//
+void usub_uausaua() {
ua = usa - ua;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
- // CHECK-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[USA]], [[EXT_USF]]
- // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+// CHECK-LABEL: @usub_usausausf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @usf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16
+// CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[RESIZE]]
+// CHECK-NEXT: store i16 [[TMP2]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void usub_usausausf() {
usa = usa - usf;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[UF:%[0-9]+]] = load i16, i16* %uf, align 2
- // CHECK-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i24
- // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i24 [[USA_EXT]], 8
- // CHECK-NEXT: [[UF_EXT:%[a-z0-9]+]] = zext i16 [[UF]] to i24
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i24 [[USA]], [[UF_EXT]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = lshr i24 [[SUM]], 8
- // CHECK-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
- // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %usa, align 2
+// CHECK-LABEL: @usub_usausauf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i24
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i24 [[RESIZE]], 8
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i24
+// CHECK-NEXT: [[TMP2:%.*]] = sub i24 [[UPSCALE]], [[RESIZE1]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = lshr i24 [[TMP2]], 8
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i24 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void usub_usausauf() {
usa = usa - uf;
}
-void IntSubtraction() {
- // CHECK-LABEL: IntSubtraction
- short _Accum sa;
- _Accum a;
- unsigned short _Accum usa;
- _Sat short _Accum sa_sat;
- int i;
- unsigned int ui;
- long _Fract lf;
- _Bool b;
-
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i39
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i39 [[SA_EXT]], [[I]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+
+// CHECK-LABEL: @int_sasai(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = sub i39 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasai() {
sa = sa - i;
+}
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i40
- // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i40
- // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i40 [[UI_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i40 [[SA_EXT]], [[UI]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+// CHECK-LABEL: @int_sasaui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = sub i40 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sasaui() {
sa = sa - ui;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i40
- // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i40 [[USA_EXT]], [[I]]
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i39 [[USA_EXT]], [[I]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usausai(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i40 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausai(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i39 [[RESIZE]], [[UPSCALE]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausai() {
usa = usa - i;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i40 [[USA_EXT]], [[I]]
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
- // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i39 [[USA_EXT]], [[I]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+// SIGNED-LABEL: @int_usausaui(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = sub i40 [[RESIZE]], [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[TMP2]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_usausaui(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = sub i39 [[RESIZE]], [[UPSCALE]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_usausaui() {
usa = usa - ui;
+}
- // CHECK: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
- // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[LF_EXT:%[a-z0-9]+]] = sext i32 [[LF]] to i64
- // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i64
- // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i64 [[UI_EXT]], 31
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i64 [[LF_EXT]], [[UI]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i64 [[SUM]] to i32
- // CHECK-NEXT: store i32 [[RES]], i32* %lf, align 4
+// CHECK-LABEL: @int_lflfui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i64
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE1]], 31
+// CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i64 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @lf, align 4
+// CHECK-NEXT: ret void
+//
+void int_lflfui() {
lf = lf - ui;
+}
- // CHECK: [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[BOOL:%[0-9]+]] = load i8, i8* %b, align 1
- // CHECK-NEXT: [[AS_BOOL:%[a-z0-9]+]] = trunc i8 [[BOOL]] to i1
- // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = zext i1 [[AS_BOOL]] to i32
- // CHECK-NEXT: [[ACCUM_EXT:%[a-z0-9]+]] = sext i32 [[ACCUM]] to i47
- // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = sext i32 [[BOOL_EXT]] to i47
- // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = shl i47 [[BOOL]], 15
- // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i47 [[ACCUM_EXT]], [[BOOL_EXT]]
- // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i47 [[SUM]] to i32
- // CHECK-NEXT: store i32 [[RESULT]], i32* %a, align 4
+// CHECK-LABEL: @int_aab(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* @b, align 1
+// CHECK-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP1]] to i1
+// CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i47
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[CONV]] to i47
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i47 [[RESIZE1]], 15
+// CHECK-NEXT: [[TMP2:%.*]] = sub i47 [[RESIZE]], [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i47 [[TMP2]] to i32
+// CHECK-NEXT: store i32 [[RESIZE2]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void int_aab() {
a = a - b;
}
-void SaturatedSubtraction() {
- // CHECK-LABEL: SaturatedSubtraction
- short _Accum sa;
- _Accum a;
- long _Accum la;
- unsigned short _Accum usa;
- unsigned _Accum ua;
- unsigned long _Accum ula;
-
- _Sat short _Accum sa_sat;
- _Sat _Accum a_sat;
- _Sat long _Accum la_sat;
- _Sat unsigned short _Accum usa_sat;
- _Sat unsigned _Accum ua_sat;
- _Sat unsigned long _Accum ula_sat;
- _Sat unsigned _Fract uf_sat;
-
- int i;
- unsigned int ui;
-
- // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.ssub.sat.i16(i16 [[SA]], i16
- // [[SA_SAT]])
- // CHECK-NEXT: store i16 [[SUM]], i16* %sa_sat, align 2
+
+// CHECK-LABEL: @sat_sassasas(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 [[TMP1]])
+// CHECK-NEXT: store i16 [[TMP2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasas() {
sa_sat = sa - sa_sat;
+}
- // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
- // CHECK-NEXT: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.usub.sat.i16(i16 [[USA]], i16 [[USA_SAT]])
- // SIGNED-NEXT: store i16 [[SUM]], i16* %usa_sat, align 2
- // UNSIGNED-NEXT: [[USA_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA]] to i15
- // UNSIGNED-NEXT: [[USA_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA_SAT]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.usub.sat.i15(i15 [[USA_TRUNC]], i15 [[USA_SAT_TRUNC]])
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP0]], i16 [[TMP1]])
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusausas() {
usa_sat = usa - usa_sat;
+}
- // CHECK: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i32
- // SIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[USA_EXT]], 8
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i32 @llvm.usub.sat.i32(i32 [[UA]], i32 [[USA]])
- // SIGNED-NEXT: store i32 [[SUM]], i32* %ua_sat, align 4
- // UNSIGNED-NEXT: [[UA_TRUNC:%[a-z0-9]+]] = trunc i32 [[UA]] to i31
- // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i31
- // UNSIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i31 [[USA_EXT]], 8
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i31 @llvm.usub.sat.i31(i31 [[UA_TRUNC]], i31 [[USA]])
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i31 [[SUM]] to i32
- // UNSIGNED-NEXT: store i32 [[SUM_EXT]], i32* %ua_sat, align 4
+// SIGNED-LABEL: @sat_uasuausas(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[TMP0]], i32 [[UPSCALE]])
+// SIGNED-NEXT: store i32 [[TMP2]], i32* @ua_sat, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_uasuausas(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i31
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i16 [[TMP1]] to i31
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i31 [[RESIZE1]], 8
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i31 @llvm.usub.sat.i31(i31 [[RESIZE]], i31 [[UPSCALE]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i31 [[TMP2]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE2]], i32* @ua_sat, align 4
+// UNSIGNED-NEXT: ret void
+//
+void sat_uasuausas() {
ua_sat = ua - usa_sat;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i39
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.ssub.sat.i39(i39 [[SA_SAT_EXT]], i39 [[I]])
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i39 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasi(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i39
+// CHECK-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i39 @llvm.ssub.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 -32768, i39 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasi() {
sa_sat = sa_sat - i;
+}
- // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i40
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
- // CHECK-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.ssub.sat.i40(i40 [[SA_SAT_EXT]], i40 [[I]])
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 32767
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 32767, i40 [[SUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RES]], -32768
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 -32768, i40 [[RES]]
- // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i40 [[RES2]] to i16
- // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+// CHECK-LABEL: @sat_sassasui(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa_sat, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i40
+// CHECK-NEXT: [[RESIZE1:%.*]] = zext i32 [[TMP1]] to i40
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 7
+// CHECK-NEXT: [[TMP2:%.*]] = call i40 @llvm.ssub.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]])
+// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 32767, i40 [[TMP2]]
+// CHECK-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 -32768, i40 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE2]], i16* @sa_sat, align 2
+// CHECK-NEXT: ret void
+//
+void sat_sassasui() {
sa_sat = sa_sat - ui;
+}
- // CHECK: [[UF_SAT:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // CHECK-NEXT: [[UF_SAT2:%[0-9]+]] = load i16, i16* %uf_sat, align 2
- // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.usub.sat.i16(i16 [[UF_SAT]], i16 [[UF_SAT2]])
- // SIGNED-NEXT: store i16 [[SUM]], i16* %uf_sat, align 2
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[UF_SAT]] to i15
- // UNSIGNED-NEXT: [[UF_SAT_TRUNC2:%[a-z0-9]+]] = trunc i16 [[UF_SAT2]] to i15
- // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.usub.sat.i15(i15 [[UF_SAT_TRUNC]], i15 [[UF_SAT_TRUNC2]])
- // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
- // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %uf_sat, align 2
+// SIGNED-LABEL: @sat_ufsufsufs(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP0]], i16 [[TMP1]])
+// SIGNED-NEXT: store i16 [[TMP2]], i16* @uf_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_ufsufsufs(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, i16* @uf_sat, align 2
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP0]] to i15
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i16 [[TMP1]] to i15
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE]], i15 [[RESIZE1]])
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i15 [[TMP2]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @uf_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_ufsufsufs() {
uf_sat = uf_sat - uf_sat;
+}
- // CHECK: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
- // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // 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.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
- // SIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[RESULT]]
- // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i40 [[RESULT2]] to i16
- // 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.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
- // UNSIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[RESULT]]
- // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i39 [[RESULT2]] to i16
- // CHECK-NEXT: store i16 [[RESULT]], i16* %usa_sat, align 2
+// SIGNED-LABEL: @sat_usasusasi(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i40
+// SIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE1]], 8
+// SIGNED-NEXT: [[TMP2:%.*]] = call i40 @llvm.ssub.sat.i40(i40 [[RESIZE]], i40 [[UPSCALE]])
+// SIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i40 [[TMP2]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i40 65535, i40 [[TMP2]]
+// SIGNED-NEXT: [[TMP4:%.*]] = icmp slt i40 [[SATMAX]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i40 0, i40 [[SATMAX]]
+// SIGNED-NEXT: [[RESIZE2:%.*]] = trunc i40 [[SATMIN]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @sat_usasusasi(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa_sat, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = sext i32 [[TMP1]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE1]], 7
+// UNSIGNED-NEXT: [[TMP2:%.*]] = call i39 @llvm.ssub.sat.i39(i39 [[RESIZE]], i39 [[UPSCALE]])
+// UNSIGNED-NEXT: [[TMP3:%.*]] = icmp sgt i39 [[TMP2]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP3]], i39 32767, i39 [[TMP2]]
+// UNSIGNED-NEXT: [[TMP4:%.*]] = icmp slt i39 [[SATMAX]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP4]], i39 0, i39 [[SATMAX]]
+// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i39 [[SATMIN]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE2]], i16* @usa_sat, align 2
+// UNSIGNED-NEXT: ret void
+//
+void sat_usasusasi() {
usa_sat = usa_sat - i;
}
diff --git a/clang/test/Frontend/fixed_point_sub_const.c b/clang/test/Frontend/fixed_point_sub_const.c
new file mode 100644
index 000000000000..219ce5a411c1
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_sub_const.c
@@ -0,0 +1,59 @@
+// 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
diff erent 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;
+// SIGNED-DAG: @usa_const = {{.*}}global i16 256, align 2
+// UNSIGNED-DAG: @usa_const = {{.*}}global i16 128, 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;
+// SIGNED-DAG: @usa_const2 = {{.*}}global i16 384, align 2
+// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 192, 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-DAG: @sat_usa_const = {{.*}}global i16 0, 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);
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// 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
diff --git a/clang/test/Frontend/fixed_point_unary.c b/clang/test/Frontend/fixed_point_unary.c
index 6b2a572dd821..84c6654fe7af 100644
--- a/clang/test/Frontend/fixed_point_unary.c
+++ b/clang/test/Frontend/fixed_point_unary.c
@@ -1,3 +1,4 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
@@ -15,250 +16,543 @@ _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
+int i;
+
+// CHECK-LABEL: @inc_a(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
// CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], -32768
// CHECK-NEXT: store i32 [[TMP1]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void inc_a() {
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
+// CHECK-LABEL: @inc_f(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = sub i16 [[TMP0]], -32768
+// CHECK-NEXT: store i16 [[TMP1]], i16* @f, align 2
+// CHECK-NEXT: ret void
+//
+void inc_f() {
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
+// CHECK-LABEL: @inc_lf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], -2147483648
+// CHECK-NEXT: store i32 [[TMP1]], i32* @lf, align 4
+// CHECK-NEXT: ret void
+//
+void inc_lf() {
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
+// SIGNED-LABEL: @inc_ua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 65536
+// SIGNED-NEXT: store i32 [[TMP1]], i32* @ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @inc_ua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 32768
+// UNSIGNED-NEXT: store i32 [[TMP1]], i32* @ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void inc_ua() {
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
+// SIGNED-LABEL: @inc_usa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], 256
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @inc_usa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], 128
+// UNSIGNED-NEXT: store i16 [[TMP1]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void inc_usa() {
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
+// SIGNED-LABEL: @inc_uf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], undef
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @uf, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @inc_uf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], -32768
+// UNSIGNED-NEXT: store i16 [[TMP1]], i16* @uf, align 2
+// UNSIGNED-NEXT: ret void
+//
+void inc_uf() {
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
+// CHECK-LABEL: @inc_sa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP0]], i32 -32768)
+// CHECK-NEXT: store i32 [[TMP1]], i32* @sa, align 4
+// CHECK-NEXT: ret void
+//
+void inc_sa() {
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
+// CHECK-LABEL: @inc_sf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sf, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 -32768)
+// CHECK-NEXT: store i16 [[TMP1]], i16* @sf, align 2
+// CHECK-NEXT: ret void
+//
+void inc_sf() {
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
+// CHECK-LABEL: @inc_slf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @slf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP0]], i32 -2147483648)
+// CHECK-NEXT: store i32 [[TMP1]], i32* @slf, align 4
+// CHECK-NEXT: ret void
+//
+void inc_slf() {
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
+// SIGNED-LABEL: @inc_sua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[TMP0]], i32 65536)
+// SIGNED-NEXT: store i32 [[TMP1]], i32* @sua, align 4
+// SIGNED-NEXT: ret void
+//
+// 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: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void inc_sua() {
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
+// SIGNED-LABEL: @inc_susa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @susa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP0]], i16 256)
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @susa, align 2
+// SIGNED-NEXT: ret void
+//
+// 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: store i16 [[RESIZE1]], i16* @susa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void inc_susa() {
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
+// SIGNED-LABEL: @inc_suf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @suf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[TMP0]], i16 -1)
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @suf, align 2
+// SIGNED-NEXT: ret void
+//
+// 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: store i16 [[RESIZE1]], i16* @suf, align 2
+// UNSIGNED-NEXT: ret void
+//
+void inc_suf() {
suf++;
}
-// CHECK-LABEL: @Decrement(
-void Decrement() {
-// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+
+// CHECK-LABEL: @dec_a(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], -32768
// CHECK-NEXT: store i32 [[TMP1]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void dec_a() {
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
+// CHECK-LABEL: @dec_f(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], -32768
+// CHECK-NEXT: store i16 [[TMP1]], i16* @f, align 2
+// CHECK-NEXT: ret void
+//
+void dec_f() {
f--;
+}
-// CHECK: [[TMP4:%.*]] = load i32, i32* @lf, align 4
-// CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], -2147483648
-// CHECK-NEXT: store i32 [[TMP5]], i32* @lf, align 4
+// CHECK-LABEL: @dec_lf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @lf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], -2147483648
+// CHECK-NEXT: store i32 [[TMP1]], i32* @lf, align 4
+// CHECK-NEXT: ret void
+//
+void dec_lf() {
lf--;
+}
-// CHECK: [[TMP6:%.*]] = load i32, i32* @ua, align 4
-// SIGNED-NEXT: [[TMP7:%.*]] = sub i32 [[TMP6]], 65536
-// UNSIGNED-NEXT: [[TMP7:%.*]] = sub i32 [[TMP6]], 32768
-// CHECK-NEXT: store i32 [[TMP7]], i32* @ua, align 4
+// SIGNED-LABEL: @dec_ua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], 65536
+// SIGNED-NEXT: store i32 [[TMP1]], i32* @ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @dec_ua(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], 32768
+// UNSIGNED-NEXT: store i32 [[TMP1]], i32* @ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void dec_ua() {
ua--;
+}
-// CHECK: [[TMP8:%.*]] = load i16, i16* @usa, align 2
-// SIGNED-NEXT: [[TMP9:%.*]] = sub i16 [[TMP8]], 256
-// UNSIGNED-NEXT: [[TMP9:%.*]] = sub i16 [[TMP8]], 128
-// CHECK-NEXT: store i16 [[TMP9]], i16* @usa, align 2
+// SIGNED-LABEL: @dec_usa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = sub i16 [[TMP0]], 256
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @dec_usa(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = sub i16 [[TMP0]], 128
+// UNSIGNED-NEXT: store i16 [[TMP1]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void dec_usa() {
usa--;
+}
-// CHECK: [[TMP10:%.*]] = load i16, i16* @uf, align 2
-// SIGNED-NEXT: [[TMP11:%.*]] = sub i16 [[TMP10]], undef
-// UNSIGNED-NEXT: [[TMP11:%.*]] = sub i16 [[TMP10]], -32768
-// CHECK-NEXT: store i16 [[TMP11]], i16* @uf, align 2
+// SIGNED-LABEL: @dec_uf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = sub i16 [[TMP0]], undef
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @uf, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @dec_uf(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// UNSIGNED-NEXT: [[TMP1:%.*]] = sub i16 [[TMP0]], -32768
+// UNSIGNED-NEXT: store i16 [[TMP1]], i16* @uf, align 2
+// UNSIGNED-NEXT: ret void
+//
+void dec_uf() {
uf--;
+}
-// CHECK: [[TMP12:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[TMP13:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP12]], i32 -32768)
-// CHECK-NEXT: store i32 [[TMP13]], i32* @sa, align 4
+// CHECK-LABEL: @dec_sa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 -32768)
+// CHECK-NEXT: store i32 [[TMP1]], i32* @sa, align 4
+// CHECK-NEXT: ret void
+//
+void dec_sa() {
sa--;
+}
-// CHECK: [[TMP14:%.*]] = load i16, i16* @sf, align 2
-// CHECK-NEXT: [[TMP15:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP14]], i16 -32768)
-// CHECK-NEXT: store i16 [[TMP15]], i16* @sf, align 2
+// CHECK-LABEL: @dec_sf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sf, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[TMP0]], i16 -32768)
+// CHECK-NEXT: store i16 [[TMP1]], i16* @sf, align 2
+// CHECK-NEXT: ret void
+//
+void dec_sf() {
sf--;
+}
-// CHECK: [[TMP16:%.*]] = load i32, i32* @slf, align 4
-// CHECK-NEXT: [[TMP17:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP16]], i32 -2147483648)
-// CHECK-NEXT: store i32 [[TMP17]], i32* @slf, align 4
+// CHECK-LABEL: @dec_slf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @slf, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[TMP0]], i32 -2147483648)
+// CHECK-NEXT: store i32 [[TMP1]], i32* @slf, align 4
+// CHECK-NEXT: ret void
+//
+void dec_slf() {
slf--;
+}
-// 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
+// SIGNED-LABEL: @dec_sua(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sua, align 4
+// SIGNED-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[TMP0]], i32 65536)
+// SIGNED-NEXT: store i32 [[TMP1]], i32* @sua, align 4
+// SIGNED-NEXT: ret void
+//
+// 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: store i32 [[RESIZE1]], i32* @sua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void dec_sua() {
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
+// SIGNED-LABEL: @dec_susa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @susa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP0]], i16 256)
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @susa, align 2
+// SIGNED-NEXT: ret void
+//
+// 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: store i16 [[RESIZE1]], i16* @susa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void dec_susa() {
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]], i16* @suf, align 2
-// UNSIGNED-NEXT: [[RESIZE4:%.*]] = trunc i16 [[TMP22]] to i15
-// UNSIGNED-NEXT: [[TMP23:%.*]] = call i15 @llvm.usub.sat.i15(i15 [[RESIZE4]], i15 -1)
-// UNSIGNED-NEXT: [[RESIZE5:%.*]] = zext i15 [[TMP23]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE5]], i16* @suf, align 2
+// SIGNED-LABEL: @dec_suf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @suf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP0]], i16 -1)
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @suf, align 2
+// SIGNED-NEXT: ret void
+//
+// 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: store i16 [[RESIZE1]], i16* @suf, align 2
+// UNSIGNED-NEXT: ret void
+//
+void dec_suf() {
suf--;
}
-// CHECK-LABEL: @Minus(
-void Minus() {
-// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+
+// CHECK-LABEL: @neg_a(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
// CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[TMP0]]
// CHECK-NEXT: store i32 [[TMP1]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void neg_a() {
a = -a;
+}
-// CHECK: [[TMP2:%.*]] = load i16, i16* @f, align 2
-// CHECK-NEXT: [[TMP3:%.*]] = sub i16 0, [[TMP2]]
-// CHECK-NEXT: store i16 [[TMP3]], i16* @f, align 2
+// CHECK-LABEL: @neg_f(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = sub i16 0, [[TMP0]]
+// CHECK-NEXT: store i16 [[TMP1]], i16* @f, align 2
+// CHECK-NEXT: ret void
+//
+void neg_f() {
f = -f;
+}
-// CHECK: [[TMP4:%.*]] = load i16, i16* @usa, align 2
-// CHECK-NEXT: [[TMP5:%.*]] = sub i16 0, [[TMP4]]
-// CHECK-NEXT: store i16 [[TMP5]], i16* @usa, align 2
+// CHECK-LABEL: @neg_usa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = sub i16 0, [[TMP0]]
+// CHECK-NEXT: store i16 [[TMP1]], i16* @usa, align 2
+// CHECK-NEXT: ret void
+//
+void neg_usa() {
usa = -usa;
+}
-// CHECK: [[TMP6:%.*]] = load i16, i16* @uf, align 2
-// CHECK-NEXT: [[TMP7:%.*]] = sub i16 0, [[TMP6]]
-// CHECK-NEXT: store i16 [[TMP7]], i16* @uf, align 2
+// CHECK-LABEL: @neg_uf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = sub i16 0, [[TMP0]]
+// CHECK-NEXT: store i16 [[TMP1]], i16* @uf, align 2
+// CHECK-NEXT: ret void
+//
+void neg_uf() {
uf = -uf;
+}
-// CHECK: [[TMP8:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: [[TMP9:%.*]] = call i32 @llvm.ssub.sat.i32(i32 0, i32 [[TMP8]])
-// CHECK-NEXT: store i32 [[TMP9]], i32* @sa, align 4
+// CHECK-LABEL: @neg_sa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ssub.sat.i32(i32 0, i32 [[TMP0]])
+// CHECK-NEXT: store i32 [[TMP1]], i32* @sa, align 4
+// CHECK-NEXT: ret void
+//
+void neg_sa() {
sa = -sa;
+}
-// CHECK: [[TMP10:%.*]] = load i16, i16* @sf, align 2
-// CHECK-NEXT: [[TMP11:%.*]] = call i16 @llvm.ssub.sat.i16(i16 0, i16 [[TMP10]])
-// CHECK-NEXT: store i16 [[TMP11]], i16* @sf, align 2
+// CHECK-LABEL: @neg_sf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sf, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.ssub.sat.i16(i16 0, i16 [[TMP0]])
+// CHECK-NEXT: store i16 [[TMP1]], i16* @sf, align 2
+// CHECK-NEXT: ret void
+//
+void neg_sf() {
sf = -sf;
+}
-// CHECK: [[TMP12:%.*]] = load i16, i16* @susa, align 2
-// SIGNED-NEXT: [[TMP13:%.*]] = call i16 @llvm.usub.sat.i16(i16 0, i16 [[TMP12]])
-// SIGNED-NEXT: store i16 [[TMP13]], i16* @susa, align 2
-// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[TMP12]] to i15
-// UNSIGNED-NEXT: [[TMP13:%.*]] = call i15 @llvm.usub.sat.i15(i15 0, i15 [[RESIZE]])
-// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i15 [[TMP13]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @susa, align 2
+// SIGNED-LABEL: @neg_susa(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @susa, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = call i16 @llvm.usub.sat.i16(i16 0, i16 [[TMP0]])
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @susa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @neg_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 0, i15 [[RESIZE]])
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @susa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void neg_susa() {
susa = -susa;
+}
-// CHECK: [[TMP14:%.*]] = load i16, i16* @suf, align 2
-// SIGNED-NEXT: [[TMP15:%.*]] = call i16 @llvm.usub.sat.i16(i16 0, i16 [[TMP14]])
-// SIGNED-NEXT: store i16 [[TMP15]], i16* @suf, align 2
-// UNSIGNED-NEXT: [[RESIZE2:%.*]] = trunc i16 [[TMP14]] to i15
-// UNSIGNED-NEXT: [[TMP15:%.*]] = call i15 @llvm.usub.sat.i15(i15 0, i15 [[RESIZE2]])
-// UNSIGNED-NEXT: [[RESIZE3:%.*]] = zext i15 [[TMP15]] to i16
-// UNSIGNED-NEXT: store i16 [[RESIZE3]], i16* @suf, align 2
+// SIGNED-LABEL: @neg_suf(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @suf, align 2
+// SIGNED-NEXT: [[TMP1:%.*]] = call i16 @llvm.usub.sat.i16(i16 0, i16 [[TMP0]])
+// SIGNED-NEXT: store i16 [[TMP1]], i16* @suf, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @neg_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 0, i15 [[RESIZE]])
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i15 [[TMP1]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @suf, align 2
+// UNSIGNED-NEXT: ret void
+//
+void neg_suf() {
suf = -suf;
}
-// CHECK-LABEL: @Plus(
-void Plus() {
-// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+
+// CHECK-LABEL: @plus_a(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
// CHECK-NEXT: store i32 [[TMP0]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void plus_a() {
a = +a;
+}
-// CHECK: [[TMP1:%.*]] = load i16, i16* @uf, align 2
-// CHECK-NEXT: store i16 [[TMP1]], i16* @uf, align 2
+// CHECK-LABEL: @plus_uf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: store i16 [[TMP0]], i16* @uf, align 2
+// CHECK-NEXT: ret void
+//
+void plus_uf() {
uf = +uf;
+}
-// CHECK: [[TMP2:%.*]] = load i32, i32* @sa, align 4
-// CHECK-NEXT: store i32 [[TMP2]], i32* @sa, align 4
+// CHECK-LABEL: @plus_sa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sa, align 4
+// CHECK-NEXT: store i32 [[TMP0]], i32* @sa, align 4
+// CHECK-NEXT: ret void
+//
+void plus_sa() {
sa = +sa;
}
-// CHECK-LABEL: @Not(
-void Not() {
- int i;
-// CHECK: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-LABEL: @not_a(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
// CHECK-NEXT: [[LNOT:%.*]] = xor i1 [[TOBOOL]], true
// CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[LNOT]] to i32
-// CHECK-NEXT: store i32 [[LNOT_EXT]], i32* %i, align 4
+// CHECK-NEXT: store i32 [[LNOT_EXT]], i32* @i, align 4
+// CHECK-NEXT: ret void
+//
+void not_a() {
i = !a;
+}
-// CHECK: [[TMP1:%.*]] = load i16, i16* @uf, align 2
-// CHECK-NEXT: [[TOBOOL1:%.*]] = icmp ne i16 [[TMP1]], 0
-// CHECK-NEXT: [[LNOT2:%.*]] = xor i1 [[TOBOOL1]], true
-// CHECK-NEXT: [[LNOT_EXT3:%.*]] = zext i1 [[LNOT2]] to i32
-// CHECK-NEXT: store i32 [[LNOT_EXT3]], i32* %i, align 4
+// CHECK-LABEL: @not_uf(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i16 [[TMP0]], 0
+// CHECK-NEXT: [[LNOT:%.*]] = xor i1 [[TOBOOL]], true
+// CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[LNOT]] to i32
+// CHECK-NEXT: store i32 [[LNOT_EXT]], i32* @i, align 4
+// CHECK-NEXT: ret void
+//
+void not_uf() {
i = !uf;
+}
-// CHECK: [[TMP2:%.*]] = load i16, i16* @susa, align 2
-// CHECK-NEXT: [[TOBOOL4:%.*]] = icmp ne i16 [[TMP2]], 0
-// CHECK-NEXT: [[LNOT5:%.*]] = xor i1 [[TOBOOL4]], true
-// CHECK-NEXT: [[LNOT_EXT6:%.*]] = zext i1 [[LNOT5]] to i32
-// CHECK-NEXT: store i32 [[LNOT_EXT6]], i32* %i, align 4
+// CHECK-LABEL: @not_susa(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @susa, align 2
+// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i16 [[TMP0]], 0
+// CHECK-NEXT: [[LNOT:%.*]] = xor i1 [[TOBOOL]], true
+// CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[LNOT]] to i32
+// CHECK-NEXT: store i32 [[LNOT_EXT]], i32* @i, align 4
+// CHECK-NEXT: ret void
+//
+void not_susa() {
i = !susa;
}
More information about the cfe-commits
mailing list