[clang] 9c26eb8 - Refactor fixed point conversion test.
Bevin Hansson via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 9 01:31:24 PDT 2020
Author: Bevin Hansson
Date: 2020-10-09T10:27:42+02:00
New Revision: 9c26eb8b915e5e20afa7d3e07996ea112c18ccc3
URL: https://github.com/llvm/llvm-project/commit/9c26eb8b915e5e20afa7d3e07996ea112c18ccc3
DIFF: https://github.com/llvm/llvm-project/commit/9c26eb8b915e5e20afa7d3e07996ea112c18ccc3.diff
LOG: Refactor fixed point conversion test.
Differential Revision: https://reviews.llvm.org/D88648
Added:
clang/test/Frontend/fixed_point_conversions_const.c
Modified:
clang/test/Frontend/fixed_point_conversions.c
Removed:
################################################################################
diff --git a/clang/test/Frontend/fixed_point_conversions.c b/clang/test/Frontend/fixed_point_conversions.c
index 86a687bdef93..dfe727c708f4 100644
--- a/clang/test/Frontend/fixed_point_conversions.c
+++ b/clang/test/Frontend/fixed_point_conversions.c
@@ -1,485 +1,697 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
-// Between
diff erent fixed point types
-short _Accum sa_const = 2.5hk; // CHECK-DAG: @sa_const = {{.*}}global i16 320, align 2
-_Accum a_const = 2.5hk; // CHECK-DAG: @a_const = {{.*}}global i32 81920, align 4
-short _Accum sa_const2 = 2.5k; // CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
-
-short _Accum sa_from_f_const = 0.5r; // CHECK-DAG: sa_from_f_const = {{.*}}global i16 64, align 2
-_Fract f_from_sa_const = 0.5hk; // CHECK-DAG: f_from_sa_const = {{.*}}global i16 16384, align 2
-
-unsigned short _Accum usa_const = 2.5uk;
-unsigned _Accum ua_const = 2.5uhk;
-// SIGNED-DAG: @usa_const = {{.*}}global i16 640, align 2
-// SIGNED-DAG: @ua_const = {{.*}}global i32 163840, align 4
-// UNSIGNED-DAG: @usa_const = {{.*}}global i16 320, align 2
-// UNSIGNED-DAG: @ua_const = {{.*}}global i32 81920, align 4
-
-// FixedPoint to integer
-int i_const = -128.0hk; // CHECK-DAG: @i_const = {{.*}}global i32 -128, align 4
-int i_const2 = 128.0hk; // CHECK-DAG: @i_const2 = {{.*}}global i32 128, align 4
-int i_const3 = -128.0k; // CHECK-DAG: @i_const3 = {{.*}}global i32 -128, align 4
-int i_const4 = 128.0k; // CHECK-DAG: @i_const4 = {{.*}}global i32 128, align 4
-short s_const = -128.0k; // CHECK-DAG: @s_const = {{.*}}global i16 -128, align 2
-short s_const2 = 128.0k; // CHECK-DAG: @s_const2 = {{.*}}global i16 128, align 2
-
-// Integer to fixed point
-short _Accum sa_const5 = 2; // CHECK-DAG: @sa_const5 = {{.*}}global i16 256, align 2
-short _Accum sa_const6 = -2; // CHECK-DAG: @sa_const6 = {{.*}}global i16 -256, align 2
-short _Accum sa_const7 = -256; // CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
-
-// Signedness
-unsigned short _Accum usa_const2 = 2.5hk;
-// SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2
-// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
-short _Accum sa_const3 = 2.5hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
-
-int i_const5 = 128.0uhk;
-unsigned int ui_const = 128.0hk;
-// CHECK-DAG: @i_const5 = {{.*}}global i32 128, align 4
-// CHECK-DAG: @ui_const = {{.*}}global i32 128, align 4
-
-short _Accum sa_const9 = 2u; // CHECK-DAG: @sa_const9 = {{.*}}global i16 256, align 2
-unsigned short _Accum usa_const3 = 2;
-// SIGNED-DAG: @usa_const3 = {{.*}}global i16 512, align 2
-// UNSIGNED-DAG: @usa_const3 = {{.*}}global i16 256, align 2
-
-// Overflow (this is undefined but allowed)
-short _Accum sa_const4 = 256.0k;
-unsigned int ui_const2 = -2.5hk;
-short _Accum sa_const8 = 256;
-unsigned short _Accum usa_const4 = -2;
-
-// Saturation
-_Sat short _Accum sat_sa_const = 2.5hk; // CHECK-DAG: @sat_sa_const = {{.*}}global i16 320, align 2
-_Sat short _Accum sat_sa_const2 = 256.0k; // CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
-_Sat unsigned short _Accum sat_usa_const = -1.0hk;
-// CHECK-DAG: @sat_usa_const = {{.*}}global i16 0, align 2
-_Sat unsigned short _Accum sat_usa_const2 = 256.0k;
-// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
-// UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
-
-_Sat short _Accum sat_sa_const3 = 256; // CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 32767, align 2
-_Sat short _Accum sat_sa_const4 = -257; // CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
-_Sat unsigned short _Accum sat_usa_const3 = -1;
-// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2
-_Sat unsigned short _Accum sat_usa_const4 = 256;
-// SIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 -1, align 2
-// UNSIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 32767, align 2
-
-void TestFixedPointCastSameType() {
- _Accum a = 2.5k;
- _Accum a2 = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
+short _Accum sa;
+_Accum a, a2;
+long _Accum la;
+
+unsigned short _Accum usa;
+unsigned _Accum ua;
+unsigned long _Accum ula;
+
+short _Fract sf;
+_Fract f;
+long _Fract lf;
+unsigned _Fract uf;
+
+_Sat short _Accum sat_sa;
+_Sat _Accum sat_a;
+_Sat long _Accum sat_la;
+
+_Sat unsigned short _Accum sat_usa;
+_Sat unsigned _Accum sat_ua;
+_Sat unsigned long _Accum sat_ula;
+
+_Sat short _Fract sat_sf;
+_Sat _Fract sat_f;
+_Sat long _Fract sat_lf;
+
+short s;
+int i;
+unsigned int ui;
+
+// CHECK-LABEL: @fix_same1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: store i32 [[TMP0]], i32* @a2, align 4
+// CHECK-NEXT: ret void
+//
+void fix_same1() {
+ a2 = a;
+}
+// CHECK-LABEL: @fix_same2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: store i32 [[TMP0]], i32* @a2, align 4
+// CHECK-NEXT: ret void
+//
+void fix_same2() {
a2 = (_Accum)a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
}
-void TestFixedPointCastDown() {
- long _Accum la = 2.5lk;
- _Accum a = la;
- // CHECK: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8
- // CHECK-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+// CHECK-LABEL: @fix_castdown1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_castdown1() {
+ a = la;
+}
+
+// CHECK-LABEL: @fix_castdown2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_castdown2() {
a = (_Accum)la;
- // CHECK: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8
- // CHECK-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
-
- short _Accum sa = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
- // CHECK-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
- // CHECK-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
-
- sa = (short _Accum)a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
- // CHECK-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
- // CHECK-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
-}
-
-void TestFixedPointCastUp() {
- short _Accum sa = 2.5hk;
- _Accum a = sa;
- // CHECK: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
-
- long _Accum la = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // CHECK-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16
- // CHECK-NEXT: store i64 [[LACCUM]], i64* %la, align 8
+}
+
+// CHECK-LABEL: @fix_castdown3(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void fix_castdown3() {
+ sa = a;
+}
+
+// CHECK-LABEL: @fix_castdown4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i16
+// CHECK-NEXT: store i16 [[RESIZE]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void fix_castdown4() {
+ sa = a;
+}
+
+
+// CHECK-LABEL: @fix_castup1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: store i32 [[UPSCALE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_castup1() {
+ a = sa;
+}
+// CHECK-LABEL: @fix_castup2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: store i32 [[UPSCALE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_castup2() {
a = (_Accum)sa;
- // CHECK: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
-
- la = (long _Accum)a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // CHECK-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16
- // CHECK-NEXT: store i64 [[LACCUM]], i64* %la, align 8
-}
-
-void TestFixedPointCastSignedness() {
- _Accum a = 2.5k;
- unsigned _Accum ua = a;
- // SIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // SIGNED-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1
- // SIGNED-NEXT: store i32 [[UACCUM]], i32* %ua, align 4
- // UNSIGNED: TestFixedPointCastSignedness
- // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // UNSIGNED-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
+}
+
+// CHECK-LABEL: @fix_castup3(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_castup3() {
+ a = la;
+}
+// CHECK-LABEL: @fix_castup4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_castup4() {
+ a = (long _Accum)la;
+}
+
+
+// SIGNED-LABEL: @fix_sign1(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[TMP0]], 1
+// SIGNED-NEXT: store i32 [[UPSCALE]], i32* @ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sign1(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: store i32 [[TMP0]], i32* @ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_sign1() {
+ ua = a;
+}
+
+// SIGNED-LABEL: @fix_sign2(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i32 [[TMP0]], 1
+// SIGNED-NEXT: store i32 [[DOWNSCALE]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sign2(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: store i32 [[TMP0]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_sign2() {
a = ua;
- // SIGNED: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1
- // SIGNED-NEXT: store i32 [[ACCUM]], i32* %a, align 4
- // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // UNSIGNED-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+}
+// SIGNED-LABEL: @fix_sign3(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[TMP0]], 1
+// SIGNED-NEXT: store i32 [[UPSCALE]], i32* @ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sign3(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: store i32 [[TMP0]], i32* @ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_sign3() {
ua = (unsigned _Accum)a;
- // SIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // SIGNED-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1
- // SIGNED-NEXT: store i32 [[UACCUM]], i32* %ua, align 4
- // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // UNSIGNED-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
+}
+// SIGNED-LABEL: @fix_sign4(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i32 [[TMP0]], 1
+// SIGNED-NEXT: store i32 [[DOWNSCALE]], i32* @a, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sign4(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// UNSIGNED-NEXT: store i32 [[TMP0]], i32* @a, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_sign4() {
a = (_Accum)ua;
- // SIGNED: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1
- // SIGNED-NEXT: store i32 [[ACCUM]], i32* %a, align 4
- // UNSIGNED: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // UNSIGNED-NEXT: store i32 [[UACCUM]], i32* %a, align 4
-
- _Accum a2;
- unsigned long _Accum ula = a2;
- // SIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4
- // SIGNED-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // SIGNED-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 17
- // SIGNED-NEXT: store i64 [[LACCUM]], i64* %ula, align 8
- // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4
- // UNSIGNED-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // UNSIGNED-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 16
- // UNSIGNED-NEXT: store i64 [[LACCUM]], i64* %ula, align 8
-}
-
-void TestFixedPointCastSaturation() {
- _Accum a;
- _Sat short _Accum sat_sa;
- _Sat _Accum sat_a;
- _Sat long _Accum sat_la;
- _Sat unsigned short _Accum sat_usa;
- _Sat unsigned _Accum sat_ua;
- _Sat unsigned long _Accum sat_ula;
- _Sat short _Fract sat_sf;
- _Sat _Fract sat_f;
- _Sat long _Fract sat_lf;
+}
+
+// SIGNED-LABEL: @fix_sign5(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 17
+// SIGNED-NEXT: store i64 [[UPSCALE]], i64* @ula, align 8
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sign5(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 16
+// UNSIGNED-NEXT: store i64 [[UPSCALE]], i64* @ula, align 8
+// UNSIGNED-NEXT: ret void
+//
+void fix_sign5() {
+ ula = a;
+}
+
+// CHECK-LABEL: @fix_sat1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
+// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[DOWNSCALE]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -32768, i32 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE]], i16* @sat_sa, align 2
+// CHECK-NEXT: ret void
+//
+void fix_sat1() {
// Casting down between types
sat_sa = sat_a;
- // CHECK: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
- // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
- // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768
- // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]]
- // CHECK-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // CHECK-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_sa, align 2
+}
+// CHECK-LABEL: @fix_sat2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
+// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 127
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 127, i32 [[DOWNSCALE]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -128
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -128, i32 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i8
+// CHECK-NEXT: store i8 [[RESIZE]], i8* @sat_sf, align 1
+// CHECK-NEXT: ret void
+//
+void fix_sat2() {
// Accum to Fract, decreasing scale
sat_sf = sat_a;
- // CHECK: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
- // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[FRACT]], 127
- // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 127, i32 [[FRACT]]
- // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -128
- // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -128, i32 [[RESULT]]
- // CHECK-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i8
- // CHECK-NEXT: store i8 [[RESULT_TRUNC]], i8* %sat_sf, align 1
+}
+// CHECK-LABEL: @fix_sat3(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[TMP0]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -32768, i32 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE]], i16* @sat_f, align 2
+// CHECK-NEXT: ret void
+//
+void fix_sat3() {
// Accum to Fract, same scale
sat_f = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
- // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
- // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768
- // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]]
- // CHECK-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // CHECK-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_f, align 2
+}
+// CHECK-LABEL: @fix_sat4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
+// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i48 [[UPSCALE]], 2147483647
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i48 2147483647, i48 [[UPSCALE]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp slt i48 [[SATMAX]], -2147483648
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i48 -2147483648, i48 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE1:%.*]] = trunc i48 [[SATMIN]] to i32
+// CHECK-NEXT: store i32 [[RESIZE1]], i32* @sat_lf, align 4
+// CHECK-NEXT: ret void
+//
+void fix_sat4() {
// Accum to Fract, increasing scale
sat_lf = sat_a;
- // CHECK: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // CHECK-NEXT: [[RESIZE:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i48
- // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = shl i48 [[RESIZE]], 16
- // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i48 [[FRACT]], 2147483647
- // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i48 2147483647, i48 [[FRACT]]
- // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i48 [[RESULT]], -2147483648
- // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i48 -2147483648, i48 [[RESULT]]
- // CHECK-NEXT: [[TRUNC:%[0-9a-z]+]] = trunc i48 [[RESULT2]] to i32
- // CHECK-NEXT: store i32 [[TRUNC]], i32* %sat_lf, align 4
+}
+// SIGNED-LABEL: @fix_sat5(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 7
+// SIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 65535, i32 [[DOWNSCALE]]
+// SIGNED-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[SATMAX]]
+// SIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE]], i16* @sat_usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sat5(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
+// UNSIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[DOWNSCALE]]
+// UNSIGNED-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[SATMAX]]
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE]], i16* @sat_usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void fix_sat5() {
// Signed to unsigned, decreasing scale
- _Sat _Accum sat_a2;
- sat_usa = sat_a2;
- // SIGNED: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4
- // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 7
- // SIGNED-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 65535
- // SIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 65535, i32 [[ACCUM]]
- // SIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0
- // SIGNED-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]]
- // SIGNED-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // SIGNED-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2
- // UNSIGNED: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4
- // UNSIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
- // UNSIGNED-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
- // UNSIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
- // UNSIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0
- // UNSIGNED-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]]
- // UNSIGNED-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // UNSIGNED-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2
+ sat_usa = sat_a;
+}
+// SIGNED-LABEL: @fix_sat6(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i33
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
+// SIGNED-NEXT: [[TMP1:%.*]] = icmp slt i33 [[UPSCALE]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i33 0, i33 [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE1:%.*]] = trunc i33 [[SATMIN]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE1]], i32* @sat_ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sat6(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// UNSIGNED-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[TMP0]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sat_ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_sat6() {
// Signed to unsigned, increasing scale
sat_ua = sat_a;
- // SIGNED: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // SIGNED-NEXT: [[RESIZE:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i33
- // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i33 [[RESIZE]], 1
- // SIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i33 [[ACCUM]], 0
- // SIGNED-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i33 0, i33 [[ACCUM]]
- // SIGNED-NEXT: [[TRUNC:%[0-9a-z]+]] = trunc i33 [[RESULT2]] to i32
- // SIGNED-NEXT: store i32 [[TRUNC]], i32* %sat_ua, align 4
- // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // UNSIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
- // UNSIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[ACCUM]]
- // UNSIGNED-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
+}
+// CHECK-LABEL: @fix_sat7(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: store i32 [[TMP0]], i32* @sat_a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_sat7() {
// Nothing when saturating to the same type and size
sat_a = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %sat_a, align 4
+}
+// CHECK-LABEL: @fix_sat8(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
+// CHECK-NEXT: store i32 [[TMP0]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_sat8() {
// Nothing when assigning back
a = sat_a;
- // CHECK: [[SAT_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // CHECK-NEXT: store i32 [[SAT_ACCUM]], i32* %a, align 4
+}
+// CHECK-LABEL: @fix_sat9(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sat_f, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @sat_a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_sat9() {
// No overflow when casting from fract to signed accum
sat_a = sat_f;
- // CHECK: [[FRACT:%[0-9a-z]+]] = load i16, i16* %sat_f, align 2
- // CHECK-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32
- // CHECK-NEXT: store i32 [[FRACT_EXT]], i32* %sat_a, align 4
+}
+// SIGNED-LABEL: @fix_sat10(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @sat_sf, align 1
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 9
+// SIGNED-NEXT: [[TMP1:%.*]] = icmp slt i32 [[UPSCALE]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[UPSCALE]]
+// SIGNED-NEXT: store i32 [[SATMIN]], i32* @sat_ua, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_sat10(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @sat_sf, align 1
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// UNSIGNED-NEXT: [[TMP1:%.*]] = icmp slt i32 [[UPSCALE]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[UPSCALE]]
+// UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sat_ua, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_sat10() {
// Only get overflow checking if signed fract to unsigned accum
sat_ua = sat_sf;
- // SIGNED: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1
- // SIGNED-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
- // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 9
- // SIGNED-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
- // SIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i32 0, i32 [[ACCUM]]
- // SIGNED-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
- // UNSIGNED: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1
- // UNSIGNED-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
- // UNSIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 8
- // UNSIGNED-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
- // UNSIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i32 0, i32 [[ACCUM]]
- // UNSIGNED-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
-}
-
-void TestFixedPointCastBetFractAccum() {
- short _Accum sa;
- _Accum a;
- long _Accum la;
- short _Fract sf;
- _Fract f;
- long _Fract lf;
- unsigned _Accum ua;
- unsigned _Fract uf;
+}
+
+// CHECK-LABEL: @fix_fract1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i8
+// CHECK-NEXT: store i8 [[RESIZE]], i8* @sf, align 1
+// CHECK-NEXT: ret void
+//
+void fix_fract1() {
// To lower scale
sf = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
- // CHECK-NEXT: [[FRACT_TRUNC:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i8
- // CHECK-NEXT: store i8 [[FRACT_TRUNC]], i8* %sf, align 1
+}
+// CHECK-LABEL: @fix_fract2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* @sf, align 1
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
+// CHECK-NEXT: store i32 [[UPSCALE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_fract2() {
// To higher scale
a = sf;
- // CHECK: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sf, align 1
- // CHECK-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 8
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+}
+// CHECK-LABEL: @fix_fract3(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// CHECK-NEXT: store i16 [[RESIZE]], i16* @f, align 2
+// CHECK-NEXT: ret void
+//
+void fix_fract3() {
// To same scale
f = a;
- // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = trunc i32 [[ACCUM]] to i16
- // CHECK-NEXT: store i16 [[FRACT]], i16* %f, align 2
+}
+// CHECK-LABEL: @fix_fract4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @f, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
+// CHECK-NEXT: ret void
+//
+void fix_fract4() {
a = f;
- // CHECK: [[FRACT:%[0-9a-z]+]] = load i16, i16* %f, align 2
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+}
+// CHECK-LABEL: @fix_fract5(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @ua, align 4
+// CHECK-NEXT: ret void
+//
+void fix_fract5() {
// To unsigned
ua = uf;
- // CHECK: [[FRACT:%[0-9a-z]+]] = load i16, i16* %uf, align 2
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = zext i16 [[FRACT]] to i32
- // CHECK-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
+}
+// CHECK-LABEL: @fix_fract6(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// CHECK-NEXT: store i16 [[RESIZE]], i16* @uf, align 2
+// CHECK-NEXT: ret void
+//
+void fix_fract6() {
uf = ua;
- // CHECK: [[FRACT:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i16
- // CHECK-NEXT: store i16 [[ACCUM]], i16* %uf, align 2
}
-void TestFixedPointToInt() {
- int i;
- short _Accum sa;
- unsigned short _Accum usa;
+// CHECK-LABEL: @fix_int1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
+// CHECK-NEXT: [[TMP1:%.*]] = icmp slt i16 [[TMP0]], 0
+// CHECK-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], 127
+// CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i16 [[TMP2]], i16 [[TMP0]]
+// CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i16 [[TMP3]], 7
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[DOWNSCALE]] to i32
+// CHECK-NEXT: store i32 [[RESIZE]], i32* @i, align 4
+// CHECK-NEXT: ret void
+//
+void fix_int1() {
// Will need to check for negative values
i = sa;
- // CHECK: [[FX:%[0-9]+]] = load i16, i16* %sa, align 2
- // CHECK-NEXT: [[NEG:%[0-9]+]] = icmp slt i16 [[FX]], 0
- // CHECK-NEXT: [[ROUNDED:%[0-9]+]] = add i16 [[FX]], 127
- // CHECK-NEXT: [[VAL:%[0-9]+]] = select i1 [[NEG]], i16 [[ROUNDED]], i16 [[FX]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i16 [[VAL]], 7
- // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = sext i16 [[RES]] to i32
- // CHECK-NEXT: store i32 [[RES2]], i32* %i, align 4
+}
+// SIGNED-LABEL: @fix_int2(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i16 [[TMP0]], 8
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[DOWNSCALE]] to i32
+// SIGNED-NEXT: store i32 [[RESIZE]], i32* @i, align 4
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @fix_int2(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
+// UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i16 [[TMP0]], 7
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[DOWNSCALE]] to i32
+// UNSIGNED-NEXT: store i32 [[RESIZE]], i32* @i, align 4
+// UNSIGNED-NEXT: ret void
+//
+void fix_int2() {
// No check needed for unsigned fixed points. Can just right shift.
i = usa;
- // SIGNED: [[FX:%[0-9]+]] = load i16, i16* %usa, align 2
- // SIGNED-NEXT: [[INT:%[a-z0-9]+]] = lshr i16 [[FX]], 8
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = zext i16 [[INT]] to i32
- // SIGNED-NEXT: store i32 [[RES]], i32* %i, align 4
- // UNSIGNED: [[FX:%[0-9]+]] = load i16, i16* %usa, align 2
- // UNSIGNED-NEXT: [[INT:%[a-z0-9]+]] = lshr i16 [[FX]], 7
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = zext i16 [[INT]] to i32
- // UNSIGNED-NEXT: store i32 [[RES]], i32* %i, align 4
-}
-
-void TestIntToFixedPoint() {
- short s;
- int i, i2;
- unsigned int ui;
- short _Accum sa;
- long _Accum la;
- unsigned short _Accum usa;
- _Sat short _Accum sat_sa;
- _Sat unsigned short _Accum sat_usa;
+}
+
+// CHECK-LABEL: @int_fix1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
+// CHECK-NEXT: store i16 [[UPSCALE]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_fix1() {
sa = i;
- // CHECK: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
- // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
- // CHECK-NEXT: store i16 [[FX]], i16* %sa, align 2
+}
+// CHECK-LABEL: @int_fix2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
+// CHECK-NEXT: store i16 [[UPSCALE]], i16* @sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_fix2() {
sa = ui;
- // CHECK: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
- // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
- // CHECK-NEXT: store i16 [[FX]], i16* %sa, align 2
-
- usa = i2;
- // SIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
- // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 8
- // SIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
- // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
- // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
- // UNSIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
+}
+// SIGNED-LABEL: @int_fix3(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
+// SIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_fix3(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
+// UNSIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_fix3() {
+ usa = i;
+}
+
+// SIGNED-LABEL: @int_fix4(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
+// SIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_fix4(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
+// UNSIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_fix4() {
usa = ui;
- // SIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
- // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 8
- // SIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
- // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
- // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
- // UNSIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
+}
+// CHECK-LABEL: @int_fix5(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @s, align 2
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i64
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 31
+// CHECK-NEXT: store i64 [[UPSCALE]], i64* @la, align 8
+// CHECK-NEXT: ret void
+//
+void int_fix5() {
la = s;
- // CHECK: [[I:%[0-9]+]] = load i16, i16* %s, align 2
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i16 [[I]] to i64
- // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i64 [[I_EXT]], 31
- // CHECK-NEXT: store i64 [[FX]], i64* %la, align 8
}
-void TestIntToSatFixedPoint() {
- int i, i2;
- unsigned int ui;
- _Sat short _Accum sat_sa;
- _Sat unsigned short _Accum sat_usa;
+// CHECK-LABEL: @int_sat1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
+// CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i39 [[UPSCALE]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
+// CHECK-NEXT: [[TMP2:%.*]] = icmp slt i39 [[SATMAX]], -32768
+// CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i39 -32768, i39 [[SATMAX]]
+// CHECK-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMIN]] to i16
+// CHECK-NEXT: store i16 [[RESIZE1]], i16* @sat_sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sat1() {
sat_sa = i;
- // CHECK: [[I:%[0-9]+]] = load i32, i32* %i, align 4
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[FX]], 32767
- // CHECK-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
- // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[SATMAX]], -32768
- // CHECK-NEXT: [[SATMIN:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[SATMAX]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMIN]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %sat_sa, align 2
+}
+// CHECK-LABEL: @int_sat2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// CHECK-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
+// CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
+// CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i39 [[UPSCALE]], 32767
+// CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
+// CHECK-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMAX]] to i16
+// CHECK-NEXT: store i16 [[RESIZE1]], i16* @sat_sa, align 2
+// CHECK-NEXT: ret void
+//
+void int_sat2() {
sat_sa = ui;
- // CHECK: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
- // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp ugt i39 [[FX]], 32767
- // CHECK-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
- // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMAX]] to i16
- // CHECK-NEXT: store i16 [[RES]], i16* %sat_sa, align 2
-
- sat_usa = i2;
- // SIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i40
- // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
- // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[FX]], 65535
- // SIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[FX]]
- // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[SATMAX]], 0
- // SIGNED-NEXT: [[SATMIN:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[SATMAX]]
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SATMIN]] to i16
- // SIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
- // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
- // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[FX]], 32767
- // UNSIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
- // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[SATMAX]], 0
- // UNSIGNED-NEXT: [[SATMIN:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[SATMAX]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMIN]] to i16
- // UNSIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
+}
+
+// SIGNED-LABEL: @int_sat3(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i40 [[UPSCALE]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i40 65535, i40 [[UPSCALE]]
+// SIGNED-NEXT: [[TMP2:%.*]] = icmp slt i40 [[SATMAX]], 0
+// SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i40 0, i40 [[SATMAX]]
+// SIGNED-NEXT: [[RESIZE1:%.*]] = trunc i40 [[SATMIN]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_sat3(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
+// UNSIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i39 [[UPSCALE]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
+// UNSIGNED-NEXT: [[TMP2:%.*]] = icmp slt i39 [[SATMAX]], 0
+// UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i39 0, i39 [[SATMAX]]
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMIN]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_sat3() {
+ sat_usa = i;
+}
+// SIGNED-LABEL: @int_sat4(
+// SIGNED-NEXT: entry:
+// SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// SIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
+// SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
+// SIGNED-NEXT: [[TMP1:%.*]] = icmp ugt i40 [[UPSCALE]], 65535
+// SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i40 65535, i40 [[UPSCALE]]
+// SIGNED-NEXT: [[RESIZE1:%.*]] = trunc i40 [[SATMAX]] to i16
+// SIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
+// SIGNED-NEXT: ret void
+//
+// UNSIGNED-LABEL: @int_sat4(
+// UNSIGNED-NEXT: entry:
+// UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
+// UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
+// UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
+// UNSIGNED-NEXT: [[TMP1:%.*]] = icmp ugt i39 [[UPSCALE]], 32767
+// UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
+// UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMAX]] to i16
+// UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
+// UNSIGNED-NEXT: ret void
+//
+void int_sat4() {
sat_usa = ui;
- // SIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
- // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
- // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp ugt i40 [[FX]], 65535
- // SIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[FX]]
- // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SATMAX]] to i16
- // SIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
- // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
- // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
- // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
- // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp ugt i39 [[FX]], 32767
- // UNSIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
- // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMAX]] to i16
- // UNSIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
}
diff --git a/clang/test/Frontend/fixed_point_conversions_const.c b/clang/test/Frontend/fixed_point_conversions_const.c
new file mode 100644
index 000000000000..7d63d4d63879
--- /dev/null
+++ b/clang/test/Frontend/fixed_point_conversions_const.c
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+// Between
diff erent fixed point types
+short _Accum sa_const = 2.5hk;
+// CHECK-DAG: @sa_const = {{.*}}global i16 320, align 2
+_Accum a_const = 2.5hk;
+// CHECK-DAG: @a_const = {{.*}}global i32 81920, align 4
+short _Accum sa_const2 = 2.5k;
+// CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
+
+short _Accum sa_from_f_const = 0.5r;
+// CHECK-DAG: sa_from_f_const = {{.*}}global i16 64, align 2
+_Fract f_from_sa_const = 0.5hk;
+// CHECK-DAG: f_from_sa_const = {{.*}}global i16 16384, align 2
+
+unsigned short _Accum usa_const = 2.5uk;
+unsigned _Accum ua_const = 2.5uhk;
+// SIGNED-DAG: @usa_const = {{.*}}global i16 640, align 2
+// SIGNED-DAG: @ua_const = {{.*}}global i32 163840, align 4
+// UNSIGNED-DAG: @usa_const = {{.*}}global i16 320, align 2
+// UNSIGNED-DAG: @ua_const = {{.*}}global i32 81920, align 4
+
+// FixedPoint to integer
+int i_const = -128.0hk;
+// CHECK-DAG: @i_const = {{.*}}global i32 -128, align 4
+int i_const2 = 128.0hk;
+// CHECK-DAG: @i_const2 = {{.*}}global i32 128, align 4
+int i_const3 = -128.0k;
+// CHECK-DAG: @i_const3 = {{.*}}global i32 -128, align 4
+int i_const4 = 128.0k;
+// CHECK-DAG: @i_const4 = {{.*}}global i32 128, align 4
+short s_const = -128.0k;
+// CHECK-DAG: @s_const = {{.*}}global i16 -128, align 2
+short s_const2 = 128.0k;
+// CHECK-DAG: @s_const2 = {{.*}}global i16 128, align 2
+
+// Integer to fixed point
+short _Accum sa_const5 = 2;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 256, align 2
+short _Accum sa_const6 = -2;
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -256, align 2
+short _Accum sa_const7 = -256;
+// CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
+
+// Signedness
+unsigned short _Accum usa_const2 = 2.5hk;
+// SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2
+// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const3 = 2.5hk;
+// CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
+
+int i_const5 = 128.0uhk;
+unsigned int ui_const = 128.0hk;
+// CHECK-DAG: @i_const5 = {{.*}}global i32 128, align 4
+// CHECK-DAG: @ui_const = {{.*}}global i32 128, align 4
+
+short _Accum sa_const9 = 2u;
+// CHECK-DAG: @sa_const9 = {{.*}}global i16 256, align 2
+unsigned short _Accum usa_const3 = 2;
+// SIGNED-DAG: @usa_const3 = {{.*}}global i16 512, align 2
+// UNSIGNED-DAG: @usa_const3 = {{.*}}global i16 256, align 2
+
+// Overflow (this is undefined but allowed)
+short _Accum sa_const4 = 256.0k;
+unsigned int ui_const2 = -2.5hk;
+short _Accum sa_const8 = 256;
+unsigned short _Accum usa_const4 = -2;
+
+// Saturation
+_Sat short _Accum sat_sa_const = 2.5hk;
+// CHECK-DAG: @sat_sa_const = {{.*}}global i16 320, align 2
+_Sat short _Accum sat_sa_const2 = 256.0k;
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = -1.0hk;
+// CHECK-DAG: @sat_usa_const = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const2 = 256.0k;
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
+
+_Sat short _Accum sat_sa_const3 = 256;
+// CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const4 = -257;
+// CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
+_Sat unsigned short _Accum sat_usa_const3 = -1;
+// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const4 = 256;
+// SIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 32767, align 2
More information about the cfe-commits
mailing list