Files
clang-p2996/llvm/test/Transforms/InstSimplify/fptoi-range.ll
David Green 2c4a9e830c [ValueTracking] Teach computeConstantRange that the maximum value of a half is 65504
The maximal value of a half is 0x7bff, which is 65504 when converted to
an integer. This patch teaches that to computeConstantRange to compute a
constant range with the correct maximum value.
https://alive2.llvm.org/ce/z/BV_Spb
https://alive2.llvm.org/ce/z/Nwuqvb

The maximum value for a float converted in the same way is 3.4e38, which
requires 129bits of data. I have not added that here as integer types so
larger are rare, compared to integers types larger than 17 bits require
for half floats.

The MVE tests change because instsimplify happens to be run as a part of
the backend, where it doesn't tend to for other backends.

Differential Revision: https://reviews.llvm.org/D112694
2021-10-30 14:27:38 +01:00

276 lines
7.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -instsimplify < %s | FileCheck %s
define i1 @f16_si_max1(half %f) {
; CHECK-LABEL: @f16_si_max1(
; CHECK-NEXT: [[I:%.*]] = fptosi half [[F:%.*]] to i32
; CHECK-NEXT: [[C:%.*]] = icmp sge i32 [[I]], 65504
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptosi half %f to i32
%c = icmp sge i32 %i, 65504
ret i1 %c
}
define i1 @f16_si_max2(half %f) {
; CHECK-LABEL: @f16_si_max2(
; CHECK-NEXT: ret i1 false
;
%i = fptosi half %f to i32
%c = icmp sgt i32 %i, 65504
ret i1 %c
}
define i1 @f16_si16_max2(half %f) {
; CHECK-LABEL: @f16_si16_max2(
; CHECK-NEXT: [[I:%.*]] = fptosi half [[F:%.*]] to i16
; CHECK-NEXT: [[C:%.*]] = icmp sgt i16 [[I]], -32
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptosi half %f to i16
%c = icmp sgt i16 %i, 65504
ret i1 %c
}
define i1 @f16_si_min1(half %f) {
; CHECK-LABEL: @f16_si_min1(
; CHECK-NEXT: ret i1 true
;
%i = fptosi half %f to i32
%c = icmp sge i32 %i, -65504
ret i1 %c
}
define i1 @f16_si16_min1(half %f) {
; CHECK-LABEL: @f16_si16_min1(
; CHECK-NEXT: [[I:%.*]] = fptosi half [[F:%.*]] to i16
; CHECK-NEXT: [[C:%.*]] = icmp sge i16 [[I]], 32
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptosi half %f to i16
%c = icmp sge i16 %i, -65504
ret i1 %c
}
define i1 @f16_si_min2(half %f) {
; CHECK-LABEL: @f16_si_min2(
; CHECK-NEXT: [[I:%.*]] = fptosi half [[F:%.*]] to i32
; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[I]], -65504
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptosi half %f to i32
%c = icmp sgt i32 %i, -65504
ret i1 %c
}
define i1 @f16_ui_max1(half %f) {
; CHECK-LABEL: @f16_ui_max1(
; CHECK-NEXT: [[I:%.*]] = fptoui half [[F:%.*]] to i32
; CHECK-NEXT: [[C:%.*]] = icmp sge i32 [[I]], 65504
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptoui half %f to i32
%c = icmp sge i32 %i, 65504
ret i1 %c
}
define i1 @f16_ui_max2(half %f) {
; CHECK-LABEL: @f16_ui_max2(
; CHECK-NEXT: ret i1 false
;
%i = fptoui half %f to i32
%c = icmp sgt i32 %i, 65504
ret i1 %c
}
define i1 @f16_ui16_max2(half %f) {
; CHECK-LABEL: @f16_ui16_max2(
; CHECK-NEXT: [[I:%.*]] = fptoui half [[F:%.*]] to i16
; CHECK-NEXT: [[C:%.*]] = icmp sgt i16 [[I]], -32
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptoui half %f to i16
%c = icmp sgt i16 %i, 65504
ret i1 %c
}
define i1 @f16_ui16_max3(half %f) {
; CHECK-LABEL: @f16_ui16_max3(
; CHECK-NEXT: ret i1 true
;
%i = fptoui half %f to i16
%c = icmp ule i16 %i, 65504
ret i1 %c
}
define i1 @f16_ui_min1(half %f) {
; CHECK-LABEL: @f16_ui_min1(
; CHECK-NEXT: ret i1 true
;
%i = fptoui half %f to i32
%c = icmp sge i32 %i, 0
ret i1 %c
}
define i1 @f16_ui16_min1(half %f) {
; CHECK-LABEL: @f16_ui16_min1(
; CHECK-NEXT: [[I:%.*]] = fptoui half [[F:%.*]] to i16
; CHECK-NEXT: [[C:%.*]] = icmp sge i16 [[I]], 0
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptoui half %f to i16
%c = icmp sge i16 %i, 0
ret i1 %c
}
define i1 @f16_ui_min2(half %f) {
; CHECK-LABEL: @f16_ui_min2(
; CHECK-NEXT: [[I:%.*]] = fptoui half [[F:%.*]] to i32
; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[I]], 0
; CHECK-NEXT: ret i1 [[C]]
;
%i = fptoui half %f to i32
%c = icmp sgt i32 %i, 0
ret i1 %c
}
define <2 x i1> @v2f16_si_max(<2 x half> %f) {
; CHECK-LABEL: @v2f16_si_max(
; CHECK-NEXT: [[I:%.*]] = fptosi <2 x half> [[F:%.*]] to <2 x i32>
; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i32> [[I]], <i32 65504, i32 65504>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptosi <2 x half> %f to <2 x i32>
%c = icmp sge <2 x i32> %i, <i32 65504, i32 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_si_max2(<2 x half> %f) {
; CHECK-LABEL: @v2f16_si_max2(
; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%i = fptosi <2 x half> %f to <2 x i32>
%c = icmp sgt <2 x i32> %i, <i32 65504, i32 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_si16_max2(<2 x half> %f) {
; CHECK-LABEL: @v2f16_si16_max2(
; CHECK-NEXT: [[I:%.*]] = fptosi <2 x half> [[F:%.*]] to <2 x i16>
; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i16> [[I]], <i16 -32, i16 -32>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptosi <2 x half> %f to <2 x i16>
%c = icmp sgt <2 x i16> %i, <i16 65504, i16 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_si_min1(<2 x half> %f) {
; CHECK-LABEL: @v2f16_si_min1(
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%i = fptosi <2 x half> %f to <2 x i32>
%c = icmp sge <2 x i32> %i, <i32 -65504, i32 -65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_si16_min1(<2 x half> %f) {
; CHECK-LABEL: @v2f16_si16_min1(
; CHECK-NEXT: [[I:%.*]] = fptosi <2 x half> [[F:%.*]] to <2 x i16>
; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i16> [[I]], <i16 32, i16 32>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptosi <2 x half> %f to <2 x i16>
%c = icmp sge <2 x i16> %i, <i16 -65504, i16 -65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_si_min2(<2 x half> %f) {
; CHECK-LABEL: @v2f16_si_min2(
; CHECK-NEXT: [[I:%.*]] = fptosi <2 x half> [[F:%.*]] to <2 x i32>
; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[I]], <i32 -65504, i32 -65504>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptosi <2 x half> %f to <2 x i32>
%c = icmp sgt <2 x i32> %i, <i32 -65504, i32 -65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui_max1(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui_max1(
; CHECK-NEXT: [[I:%.*]] = fptoui <2 x half> [[F:%.*]] to <2 x i32>
; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i32> [[I]], <i32 65504, i32 65504>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptoui <2 x half> %f to <2 x i32>
%c = icmp sge <2 x i32> %i, <i32 65504, i32 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui_max2(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui_max2(
; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%i = fptoui <2 x half> %f to <2 x i32>
%c = icmp sgt <2 x i32> %i, <i32 65504, i32 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui16_max2(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui16_max2(
; CHECK-NEXT: [[I:%.*]] = fptoui <2 x half> [[F:%.*]] to <2 x i16>
; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i16> [[I]], <i16 -32, i16 -32>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptoui <2 x half> %f to <2 x i16>
%c = icmp sgt <2 x i16> %i, <i16 65504, i16 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui16_max3(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui16_max3(
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%i = fptoui <2 x half> %f to <2 x i16>
%c = icmp ule <2 x i16> %i, <i16 65504, i16 65504>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui_min1(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui_min1(
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%i = fptoui <2 x half> %f to <2 x i32>
%c = icmp sge <2 x i32> %i, <i32 0, i32 0>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui16_min1(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui16_min1(
; CHECK-NEXT: [[I:%.*]] = fptoui <2 x half> [[F:%.*]] to <2 x i16>
; CHECK-NEXT: [[C:%.*]] = icmp sge <2 x i16> [[I]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptoui <2 x half> %f to <2 x i16>
%c = icmp sge <2 x i16> %i, <i16 0, i16 0>
ret <2 x i1> %c
}
define <2 x i1> @v2f16_ui_min2(<2 x half> %f) {
; CHECK-LABEL: @v2f16_ui_min2(
; CHECK-NEXT: [[I:%.*]] = fptoui <2 x half> [[F:%.*]] to <2 x i32>
; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[I]], zeroinitializer
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%i = fptoui <2 x half> %f to <2 x i32>
%c = icmp sgt <2 x i32> %i, <i32 0, i32 0>
ret <2 x i1> %c
}
declare i32 @llvm.fptosi.sat.i32.f16(half)
declare i32 @llvm.fptoui.sat.i32.f16(half)
declare <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half>)
declare <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half>)