blob: ab0231f57e93d86d3391a50b1fcf57d28d0eb905 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -mtriple=x86_64-- -passes='require<libcall-lowering-info>,expand-ir-insts' -expand-fp-convert-bits=0 < %s | FileCheck %s
; Test small bit widths that can be verified by alive2.
define i16 @fptosi_f16_i16(half %x) {
; CHECK-LABEL: define i16 @fptosi_f16_i16(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP13:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[TMP13]] to i16
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[TMP0]], -1
; CHECK-NEXT: [[SIGN:%.*]] = select i1 [[TMP1]], i16 1, i16 -1
; CHECK-NEXT: [[TMP2:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP2]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP6:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = mul i16 [[TMP7]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP9:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP10:%.*]] = shl i16 [[SIGNIFICAND]], [[TMP9]]
; CHECK-NEXT: [[TMP11:%.*]] = mul i16 [[TMP10]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP12:%.*]] = phi i16 [ [[TMP8]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP11]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i16 [[TMP12]]
;
%res = fptosi half %x to i16
ret i16 %res
}
define i16 @fptosi_f16_i16_noundef(half noundef %x) {
; CHECK-LABEL: define i16 @fptosi_f16_i16_noundef(
; CHECK-SAME: half noundef [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[X]] to i16
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[TMP0]], -1
; CHECK-NEXT: [[SIGN:%.*]] = select i1 [[TMP1]], i16 1, i16 -1
; CHECK-NEXT: [[TMP2:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP2]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP6:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = mul i16 [[TMP7]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP9:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP10:%.*]] = shl i16 [[SIGNIFICAND]], [[TMP9]]
; CHECK-NEXT: [[TMP11:%.*]] = mul i16 [[TMP10]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP12:%.*]] = phi i16 [ [[TMP8]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP11]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i16 [[TMP12]]
;
%res = fptosi half %x to i16
ret i16 %res
}
define i24 @fptosi_f16_i24(half %x) {
; CHECK-LABEL: define i24 @fptosi_f16_i24(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP1:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[TMP1]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i16 [[TMP0]], -1
; CHECK-NEXT: [[SIGN:%.*]] = select i1 [[TMP2]], i24 1, i24 -1
; CHECK-NEXT: [[TMP5:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP5]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND1:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP14:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND1]], [[TMP14]]
; CHECK-NEXT: [[TMP8:%.*]] = zext i16 [[TMP7]] to i24
; CHECK-NEXT: [[TMP9:%.*]] = mul i24 [[TMP8]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP15:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = zext i16 [[SIGNIFICAND1]] to i24
; CHECK-NEXT: [[TMP10:%.*]] = zext i16 [[TMP15]] to i24
; CHECK-NEXT: [[TMP11:%.*]] = shl i24 [[SIGNIFICAND]], [[TMP10]]
; CHECK-NEXT: [[TMP12:%.*]] = mul i24 [[TMP11]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP13:%.*]] = phi i24 [ [[TMP9]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP12]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i24 [[TMP13]]
;
%res = fptosi half %x to i24
ret i24 %res
}
define i8 @fptosi_f16_i8(half %x) {
; CHECK-LABEL: define i8 @fptosi_f16_i8(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP16:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[TMP16]] to i16
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i16 [[TMP0]], -1
; CHECK-NEXT: [[SIGN:%.*]] = select i1 [[TMP1]], i8 1, i8 -1
; CHECK-NEXT: [[TMP2:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP2]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP6:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = trunc i16 [[TMP7]] to i8
; CHECK-NEXT: [[TMP9:%.*]] = mul i8 [[TMP8]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP10:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP11:%.*]] = trunc i16 [[SIGNIFICAND]] to i8
; CHECK-NEXT: [[TMP12:%.*]] = trunc i16 [[TMP10]] to i8
; CHECK-NEXT: [[TMP13:%.*]] = shl i8 [[TMP11]], [[TMP12]]
; CHECK-NEXT: [[TMP14:%.*]] = mul i8 [[TMP13]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP15:%.*]] = phi i8 [ [[TMP9]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP14]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i8 [[TMP15]]
;
%res = fptosi half %x to i8
ret i8 %res
}
define i16 @fptoui_f16_i16(half %x) {
; CHECK-LABEL: define i16 @fptoui_f16_i16(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP13:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[TMP13]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP2]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP6:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP6]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP9:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP10:%.*]] = shl i16 [[SIGNIFICAND]], [[TMP9]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP12:%.*]] = phi i16 [ [[TMP7]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP10]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i16 [[TMP12]]
;
%res = fptoui half %x to i16
ret i16 %res
}
define i24 @fptoui_f16_i24(half %x) {
; CHECK-LABEL: define i24 @fptoui_f16_i24(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP1:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[TMP1]] to i16
; CHECK-NEXT: [[TMP5:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP5]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND1:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP14:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND1]], [[TMP14]]
; CHECK-NEXT: [[TMP8:%.*]] = zext i16 [[TMP7]] to i24
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP15:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = zext i16 [[SIGNIFICAND1]] to i24
; CHECK-NEXT: [[TMP10:%.*]] = zext i16 [[TMP15]] to i24
; CHECK-NEXT: [[TMP11:%.*]] = shl i24 [[SIGNIFICAND]], [[TMP10]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP13:%.*]] = phi i24 [ [[TMP8]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP11]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i24 [[TMP13]]
;
%res = fptoui half %x to i24
ret i24 %res
}
define i8 @fptoui_f16_i8(half %x) {
; CHECK-LABEL: define i8 @fptoui_f16_i8(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP16:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP0:%.*]] = bitcast half [[TMP16]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = lshr i16 [[TMP0]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP2]], 31
; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP0]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP3]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: br i1 [[EXP_IS_NEGATIVE]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP6:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP7:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP6]]
; CHECK-NEXT: [[TMP8:%.*]] = trunc i16 [[TMP7]] to i8
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP10:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP11:%.*]] = trunc i16 [[SIGNIFICAND]] to i8
; CHECK-NEXT: [[TMP12:%.*]] = trunc i16 [[TMP10]] to i8
; CHECK-NEXT: [[TMP13:%.*]] = shl i8 [[TMP11]], [[TMP12]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP15:%.*]] = phi i8 [ [[TMP8]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP13]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i8 [[TMP15]]
;
%res = fptoui half %x to i8
ret i8 %res
}
define i8 @fptosi_sat_f16_i8(half %x) {
; CHECK-LABEL: define i8 @fptosi_sat_f16_i8(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast half [[TMP0]] to i16
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i16 [[TMP1]], -1
; CHECK-NEXT: [[SIGN:%.*]] = select i1 [[TMP2]], i8 1, i8 -1
; CHECK-NEXT: [[TMP3:%.*]] = lshr i16 [[TMP1]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP3]], 31
; CHECK-NEXT: [[TMP4:%.*]] = and i16 [[TMP1]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP4]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: [[IS_NAN:%.*]] = fcmp uno half [[TMP0]], [[TMP0]]
; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[EXP_IS_NEGATIVE]], [[IS_NAN]]
; CHECK-NEXT: br i1 [[TMP5]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_SATURATE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_SATURATE]]:
; CHECK-NEXT: [[TMP7:%.*]] = icmp uge i16 [[BIASED_EXP]], 22
; CHECK-NEXT: br i1 [[TMP7]], label %[[FP_TO_I_IF_SATURATE:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_SATURATE]]:
; CHECK-NEXT: [[SATURATED:%.*]] = select i1 [[TMP2]], i8 127, i8 -128
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP8:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP9:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP8]]
; CHECK-NEXT: [[TMP10:%.*]] = trunc i16 [[TMP9]] to i8
; CHECK-NEXT: [[TMP11:%.*]] = mul i8 [[TMP10]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP12:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP13:%.*]] = trunc i16 [[SIGNIFICAND]] to i8
; CHECK-NEXT: [[TMP14:%.*]] = trunc i16 [[TMP12]] to i8
; CHECK-NEXT: [[TMP15:%.*]] = shl i8 [[TMP13]], [[TMP14]]
; CHECK-NEXT: [[TMP16:%.*]] = mul i8 [[TMP15]], [[SIGN]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP17:%.*]] = phi i8 [ [[SATURATED]], %[[FP_TO_I_IF_SATURATE]] ], [ [[TMP11]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP16]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i8 [[TMP17]]
;
%res = call i8 @llvm.fptosi.sat(half %x)
ret i8 %res
}
define i8 @fptoui_sat_f16_i8(half %x) {
; CHECK-LABEL: define i8 @fptoui_sat_f16_i8(
; CHECK-SAME: half [[X:%.*]]) {
; CHECK-NEXT: [[FP_TO_I_ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = freeze half [[X]]
; CHECK-NEXT: [[TMP1:%.*]] = bitcast half [[TMP0]] to i16
; CHECK-NEXT: [[TMP3:%.*]] = lshr i16 [[TMP1]], 10
; CHECK-NEXT: [[BIASED_EXP:%.*]] = and i16 [[TMP3]], 31
; CHECK-NEXT: [[TMP4:%.*]] = and i16 [[TMP1]], 1023
; CHECK-NEXT: [[SIGNIFICAND:%.*]] = or i16 [[TMP4]], 1024
; CHECK-NEXT: [[EXP_IS_NEGATIVE:%.*]] = icmp ult i16 [[BIASED_EXP]], 15
; CHECK-NEXT: [[IS_NAN:%.*]] = fcmp uno half [[TMP0]], [[TMP0]]
; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[EXP_IS_NEGATIVE]], [[IS_NAN]]
; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i16 [[TMP1]], 0
; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP5]], [[TMP15]]
; CHECK-NEXT: br i1 [[TMP16]], label %[[FP_TO_I_CLEANUP:.*]], label %[[FP_TO_I_IF_CHECK_SATURATE:.*]]
; CHECK: [[FP_TO_I_IF_CHECK_SATURATE]]:
; CHECK-NEXT: [[TMP6:%.*]] = icmp uge i16 [[BIASED_EXP]], 23
; CHECK-NEXT: br i1 [[TMP6]], label %[[FP_TO_I_IF_SATURATE:.*]], label %[[FP_TO_I_IF_CHECK_EXP_SIZE:.*]]
; CHECK: [[FP_TO_I_IF_SATURATE]]:
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_CHECK_EXP_SIZE]]:
; CHECK-NEXT: [[EXP_SMALLER_MANTISSA_WIDTH:%.*]] = icmp ult i16 [[BIASED_EXP]], 25
; CHECK-NEXT: br i1 [[EXP_SMALLER_MANTISSA_WIDTH]], label %[[FP_TO_I_IF_EXP_SMALL:.*]], label %[[FP_TO_I_IF_EXP_LARGE:.*]]
; CHECK: [[FP_TO_I_IF_EXP_SMALL]]:
; CHECK-NEXT: [[TMP7:%.*]] = sub i16 25, [[BIASED_EXP]]
; CHECK-NEXT: [[TMP8:%.*]] = lshr i16 [[SIGNIFICAND]], [[TMP7]]
; CHECK-NEXT: [[TMP9:%.*]] = trunc i16 [[TMP8]] to i8
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_IF_EXP_LARGE]]:
; CHECK-NEXT: [[TMP10:%.*]] = add i16 [[BIASED_EXP]], -25
; CHECK-NEXT: [[TMP11:%.*]] = trunc i16 [[SIGNIFICAND]] to i8
; CHECK-NEXT: [[TMP12:%.*]] = trunc i16 [[TMP10]] to i8
; CHECK-NEXT: [[TMP13:%.*]] = shl i8 [[TMP11]], [[TMP12]]
; CHECK-NEXT: br label %[[FP_TO_I_CLEANUP]]
; CHECK: [[FP_TO_I_CLEANUP]]:
; CHECK-NEXT: [[TMP14:%.*]] = phi i8 [ -1, %[[FP_TO_I_IF_SATURATE]] ], [ [[TMP9]], %[[FP_TO_I_IF_EXP_SMALL]] ], [ [[TMP13]], %[[FP_TO_I_IF_EXP_LARGE]] ], [ 0, %[[FP_TO_I_ENTRY]] ]
; CHECK-NEXT: ret i8 [[TMP14]]
;
%res = call i8 @llvm.fptoui.sat(half %x)
ret i8 %res
}