// 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 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, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[TMP1]] // CHECK-NEXT: store i16 [[TMP2]], ptr @sa, align 2 // CHECK-NEXT: ret void // void ssub_sasasa(void) { sa = sa - sa; } // CHECK-LABEL: @ssub_asaa( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @a, align 4 // CHECK-NEXT: ret void // void ssub_asaa(void) { a = sa - a; } // CHECK-LABEL: @ssub_sasasf( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @sf, align 1 // CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP1]] to i16 // CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[RESIZE]] // CHECK-NEXT: store i16 [[TMP2]], ptr @sa, align 2 // CHECK-NEXT: ret void // void ssub_sasasf(void) { sa = sa - sf; } // CHECK-LABEL: @ssub_sasaf( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr @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]], ptr @sa, align 2 // CHECK-NEXT: ret void // void ssub_sasaf(void) { sa = sa - f; } // CHECK-LABEL: @ssub_aasf( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @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]], ptr @a, align 4 // CHECK-NEXT: ret void // void ssub_aasf(void) { a = a - sf; } // CHECK-LABEL: @ssub_aalf( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @a, align 4 // CHECK-NEXT: ret void // void ssub_aalf(void) { a = a - lf; } // SIGNED-LABEL: @ssub_sasausa( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @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]], ptr @sa, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @ssub_sasausa( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @usa, align 2 // UNSIGNED-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[TMP1]] // UNSIGNED-NEXT: store i16 [[TMP2]], ptr @sa, align 2 // UNSIGNED-NEXT: ret void // void ssub_sasausa(void) { sa = sa - usa; } // SIGNED-LABEL: @ssub_asaua( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @a, align 4 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @ssub_asaua( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @a, align 4 // UNSIGNED-NEXT: ret void // void ssub_asaua(void) { a = sa - ua; } // SIGNED-LABEL: @ssub_sasausf( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i8, ptr @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]], ptr @sa, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @ssub_sasausf( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i8, ptr @usf, align 1 // UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16 // UNSIGNED-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[RESIZE]] // UNSIGNED-NEXT: store i16 [[TMP2]], ptr @sa, align 2 // UNSIGNED-NEXT: ret void // void ssub_sasausf(void) { sa = sa - usf; } // SIGNED-LABEL: @ssub_sasaulf( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @sa, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @ssub_sasaulf( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @sa, align 2 // UNSIGNED-NEXT: ret void // void ssub_sasaulf(void) { sa = sa - ulf; } // CHECK-LABEL: @ssub_aaaaa( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @a2, align 4 // CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @a3, align 4 // CHECK-NEXT: [[TMP4:%.*]] = sub i32 [[TMP2]], [[TMP3]] // CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr @a4, align 4 // CHECK-NEXT: [[TMP6:%.*]] = sub i32 [[TMP4]], [[TMP5]] // CHECK-NEXT: store i32 [[TMP6]], ptr @a, align 4 // CHECK-NEXT: ret void // void ssub_aaaaa(void) { a = a - a2 - a3 - a4; } // CHECK-LABEL: @usub_usausausa( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr @usa, align 2 // CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[TMP1]] // CHECK-NEXT: store i16 [[TMP2]], ptr @usa, align 2 // CHECK-NEXT: ret void // void usub_usausausa(void) { usa = usa - usa; } // CHECK-LABEL: @usub_uausaua( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @ua, align 4 // CHECK-NEXT: ret void // void usub_uausaua(void) { ua = usa - ua; } // CHECK-LABEL: @usub_usausausf( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @usf, align 1 // CHECK-NEXT: [[RESIZE:%.*]] = zext i8 [[TMP1]] to i16 // CHECK-NEXT: [[TMP2:%.*]] = sub i16 [[TMP0]], [[RESIZE]] // CHECK-NEXT: store i16 [[TMP2]], ptr @usa, align 2 // CHECK-NEXT: ret void // void usub_usausausf(void) { usa = usa - usf; } // CHECK-LABEL: @usub_usausauf( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr @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]], ptr @usa, align 2 // CHECK-NEXT: ret void // void usub_usausauf(void) { usa = usa - uf; } // CHECK-LABEL: @int_sasai( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @sa, align 2 // CHECK-NEXT: ret void // void int_sasai(void) { sa = sa - i; } // CHECK-LABEL: @int_sasaui( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @sa, align 2 // CHECK-NEXT: ret void // void int_sasaui(void) { sa = sa - ui; } // SIGNED-LABEL: @int_usausai( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @usa, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @int_usausai( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @usa, align 2 // UNSIGNED-NEXT: ret void // void int_usausai(void) { usa = usa - i; } // SIGNED-LABEL: @int_usausaui( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @usa, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @int_usausaui( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @usa, align 2 // UNSIGNED-NEXT: ret void // void int_usausaui(void) { usa = usa - ui; } // CHECK-LABEL: @int_lflfui( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @lf, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @lf, align 4 // CHECK-NEXT: ret void // void int_lflfui(void) { lf = lf - ui; } // CHECK-LABEL: @int_aab( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @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]], ptr @a, align 4 // CHECK-NEXT: ret void // void int_aab(void) { a = a - b; } // CHECK-LABEL: @sat_sassasas( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr @sa_sat, align 2 // CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 [[TMP1]]) // CHECK-NEXT: store i16 [[TMP2]], ptr @sa_sat, align 2 // CHECK-NEXT: ret void // void sat_sassasas(void) { sa_sat = sa - sa_sat; } // SIGNED-LABEL: @sat_usasusausas( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @usa_sat, align 2 // SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP0]], i16 [[TMP1]]) // SIGNED-NEXT: store i16 [[TMP2]], ptr @usa_sat, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @sat_usasusausas( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @usa_sat, align 2 // UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 [[TMP1]]) // UNSIGNED-NEXT: [[TMP3:%.*]] = icmp slt i16 [[TMP2]], 0 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP3]], i16 0, i16 [[TMP2]] // UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[SATMIN]] to i15 // UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16 // UNSIGNED-NEXT: store i16 [[RESIZE1]], ptr @usa_sat, align 2 // UNSIGNED-NEXT: ret void // void sat_usasusausas(void) { usa_sat = usa - usa_sat; } // SIGNED-LABEL: @sat_uasuausas( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i32, ptr @ua, align 4 // SIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @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]], ptr @ua_sat, align 4 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @sat_uasuausas( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, ptr @ua, align 4 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @usa_sat, align 2 // UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP1]] to i32 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8 // UNSIGNED-NEXT: [[TMP2:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[TMP0]], i32 [[UPSCALE]]) // UNSIGNED-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 0 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]] // UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i32 [[SATMIN]] to i31 // UNSIGNED-NEXT: [[RESIZE2:%.*]] = zext i31 [[RESIZE1]] to i32 // UNSIGNED-NEXT: store i32 [[RESIZE2]], ptr @ua_sat, align 4 // UNSIGNED-NEXT: ret void // void sat_uasuausas(void) { ua_sat = ua - usa_sat; } // CHECK-LABEL: @sat_sassasi( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa_sat, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @sa_sat, align 2 // CHECK-NEXT: ret void // void sat_sassasi(void) { sa_sat = sa_sat - i; } // CHECK-LABEL: @sat_sassasui( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr @sa_sat, align 2 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @sa_sat, align 2 // CHECK-NEXT: ret void // void sat_sassasui(void) { sa_sat = sa_sat - ui; } // SIGNED-LABEL: @sat_ufsufsufs( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @uf_sat, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @uf_sat, align 2 // SIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[TMP0]], i16 [[TMP1]]) // SIGNED-NEXT: store i16 [[TMP2]], ptr @uf_sat, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @sat_ufsufsufs( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @uf_sat, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i16, ptr @uf_sat, align 2 // UNSIGNED-NEXT: [[TMP2:%.*]] = call i16 @llvm.ssub.sat.i16(i16 [[TMP0]], i16 [[TMP1]]) // UNSIGNED-NEXT: [[TMP3:%.*]] = icmp slt i16 [[TMP2]], 0 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP3]], i16 0, i16 [[TMP2]] // UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i16 [[SATMIN]] to i15 // UNSIGNED-NEXT: [[RESIZE1:%.*]] = zext i15 [[RESIZE]] to i16 // UNSIGNED-NEXT: store i16 [[RESIZE1]], ptr @uf_sat, align 2 // UNSIGNED-NEXT: ret void // void sat_ufsufsufs(void) { uf_sat = uf_sat - uf_sat; } // SIGNED-LABEL: @sat_usasusasi( // SIGNED-NEXT: entry: // SIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa_sat, align 2 // SIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @usa_sat, align 2 // SIGNED-NEXT: ret void // // UNSIGNED-LABEL: @sat_usasusasi( // UNSIGNED-NEXT: entry: // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, ptr @usa_sat, align 2 // UNSIGNED-NEXT: [[TMP1:%.*]] = load i32, ptr @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]], ptr @usa_sat, align 2 // UNSIGNED-NEXT: ret void // void sat_usasusasi(void) { usa_sat = usa_sat - i; }