2223 lines
75 KiB
LLVM
2223 lines
75 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
|
|
|
|
; Test and/or of fcmps that could be folded to llvm.is.fpclass
|
|
|
|
; --------------------------------------------------------------------
|
|
; Base pattern, !isfinite(x) || x == 0.0
|
|
; --------------------------------------------------------------------
|
|
|
|
; Base pattern !isfinite(x) || x == 0.0
|
|
define i1 @not_isfinite_or_zero_f16(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Base pattern x == 0.0 || !isfinite(x)
|
|
define i1 @not_isfinite_or_zero_f16_commute_or(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_commute_or(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpinf, %cmpzero
|
|
ret i1 %class
|
|
}
|
|
|
|
; Base pattern !isfinite(x) || x == -0.0
|
|
define i1 @not_isfinite_or_zero_f16_negzero(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_negzero(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, -0.0
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @not_isfinite_or_fabs_oeq_zero_f16(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_fabs_oeq_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %fabs, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Base pattern !isfinite(x) || x == 0.0
|
|
define <2 x i1> @not_isfinite_or_zero_v2f16(<2 x half> %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_v2f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret <2 x i1> [[CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
|
|
%class = or <2 x i1> %cmpzero, %cmpinf
|
|
ret <2 x i1> %class
|
|
}
|
|
|
|
; Base pattern !isfinite(x) || x == <0.0, -0.0>
|
|
define <2 x i1> @not_isfinite_or_zero_v2f16_pos0_neg0_vec(<2 x half> %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_v2f16_pos0_neg0_vec(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret <2 x i1> [[CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp oeq <2 x half> %x, <half 0.0, half -0.0>
|
|
%class = or <2 x i1> %cmpzero, %cmpinf
|
|
ret <2 x i1> %class
|
|
}
|
|
|
|
; Base pattern x == 0.0 || !isfinite(x)
|
|
define <2 x i1> @not_isfinite_or_zero_v2f16_commute_or(<2 x half> %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_v2f16_commute_or(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret <2 x i1> [[CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
|
|
%class = or <2 x i1> %cmpinf, %cmpzero
|
|
ret <2 x i1> %class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @oeq_isinf_or_oeq_zero(half %x) {
|
|
; CHECK-LABEL: @oeq_isinf_or_oeq_zero(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Missing fabs for infinity check
|
|
define i1 @ueq_inf_or_oeq_zero(half %x) {
|
|
; CHECK-LABEL: @ueq_inf_or_oeq_zero(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Extra fabs.
|
|
define i1 @oeq_isinf_or_fabs_oeq_zero(half %x) {
|
|
; CHECK-LABEL: @oeq_isinf_or_fabs_oeq_zero(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %fabs, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @ueq_0_or_oeq_inf(half %x) {
|
|
; CHECK-LABEL: @ueq_0_or_oeq_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH0000
|
|
%cmpzero = fcmp oeq half %x, 0xH7C00
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @not_isfinite_or_zero_f16_not_inf(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_not_inf(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C01
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @ueq_inf_or_ueq_zero(half %x) {
|
|
; CHECK-LABEL: @ueq_inf_or_ueq_zero(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp ueq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @not_isfinite_and_zero_f16(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_and_zero_f16(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @not_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp0(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
store i1 %cmpinf, ptr %ptr
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @not_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp1(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
store i1 %cmpzero, ptr %ptr
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @not_isfinite_or_zero_f16_neg_inf(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_neg_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xHFC00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @olt_0_or_fabs_ueq_inf(half %x) {
|
|
; CHECK-LABEL: @olt_0_or_fabs_ueq_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp olt half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @oeq_0_or_fabs_ult_inf(half %x) {
|
|
; CHECK-LABEL: @oeq_0_or_fabs_ult_inf(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ult half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @not_isfinite_or_zero_f16_multi_not_0(half %x, ptr %ptr) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_not_0(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH3C00
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 1.0
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @not_isfinite_or_zero_f16_fabs_wrong_val(half %x, half %y) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_fabs_wrong_val(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %y)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @not_isfinite_or_zero_f16_not_fabs(half %x) {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_not_fabs(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.canonicalize.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.canonicalize.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; Negated pattern, isfinite(x) && !(x == 0.0)
|
|
; --------------------------------------------------------------------
|
|
|
|
; Negation of base pattern, isfinite(x) && !(x == 0.0)
|
|
define i1 @negated_isfinite_or_zero_f16(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Commuted !(x == 0.0) && isfinite(x)
|
|
define i1 @negated_isfinite_or_zero_f16_commute_and(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_commute_and(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
%not.class = and i1 %cmpinf, %cmpzero
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; isfinite(x) && !(x == -0.0)
|
|
define i1 @negated_isfinite_or_zero_f16_negzero(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_negzero(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, -0.0
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Negated pattern
|
|
define <2 x i1> @negated_isfinite_or_zero_v2f16(<2 x half> %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_v2f16(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret <2 x i1> [[NOT_CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp une <2 x half> %x, zeroinitializer
|
|
%not.class = and <2 x i1> %cmpzero, %cmpinf
|
|
ret <2 x i1> %not.class
|
|
}
|
|
|
|
; Negated pattern, commuted vector and
|
|
define <2 x i1> @negated_isfinite_or_zero_v2f16_comumte(<2 x half> %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_v2f16_comumte(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret <2 x i1> [[NOT_CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp une <2 x half> %x, zeroinitializer
|
|
%not.class = and <2 x i1> %cmpinf, %cmpzero
|
|
ret <2 x i1> %not.class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @negated_isfinite_or_zero_f16_not_une_zero(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_not_une_zero(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp one half %x, 0xH0000
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Positive test
|
|
define i1 @negated_isfinite_and_zero_f16(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_and_zero_f16(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
%not.class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @negated_isfinite_or_zero_f16_swapped_constants(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_swapped_constants(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 412)
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpzero = fcmp one half %fabs, 0xH0000
|
|
%cmpinf = fcmp une half %x, 0xH7C00
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
store i1 %cmpinf, ptr %ptr
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @negated_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp1(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000
|
|
; CHECK-NEXT: store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
store i1 %cmpzero, ptr %ptr
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(half %x) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411)
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp une half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; Negative test
|
|
define i1 @negated_isfinite_or_zero_f16_fabs_wrong_value(half %x, half %y) {
|
|
; CHECK-LABEL: @negated_isfinite_or_zero_f16_fabs_wrong_value(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[NOT_CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %y)
|
|
%cmpinf = fcmp one half %fabs, 0xH7C00
|
|
%cmpzero = fcmp une half %x, 0xH0000
|
|
%not.class = and i1 %cmpzero, %cmpinf
|
|
ret i1 %not.class
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; Other fcmp to class recognition
|
|
; --------------------------------------------------------------------
|
|
|
|
define i1 @fcmp_une_0_or_fcmp_une_inf(half %x) {
|
|
; CHECK-LABEL: @fcmp_une_0_or_fcmp_une_inf(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%cmpzero = fcmp une half %x, 0.0
|
|
%cmpinf = fcmp une half %x, 0xH7C00
|
|
%or = or i1 %cmpzero, %cmpinf
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @fcmp_one_0_and_fcmp_une_fabs_inf(half %x) {
|
|
; CHECK-LABEL: @fcmp_one_0_and_fcmp_une_fabs_inf(
|
|
; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpzero = fcmp one half %x, 0.0
|
|
%cmpinf = fcmp une half %fabs, 0xH7C00
|
|
%and = and i1 %cmpzero, %cmpinf
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @fcmp_une_0_and_fcmp_une_fabs_inf(half %x) {
|
|
; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_fabs_inf(
|
|
; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411)
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpzero = fcmp une half %x, 0.0
|
|
%cmpinf = fcmp une half %fabs, 0xH7C00
|
|
%and = and i1 %cmpzero, %cmpinf
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @fcmp_une_0_and_fcmp_une_neginf(half %x) {
|
|
; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_neginf(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%cmpzero = fcmp une half %x, 0.0
|
|
%cmpinf = fcmp une half %x, 0xHFC00
|
|
%or = or i1 %cmpzero, %cmpinf
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @issubnormal_or_inf(half %x) {
|
|
; CHECK-LABEL: @issubnormal_or_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_smallest_normal_or_inf(half %x) {
|
|
; CHECK-LABEL: @olt_smallest_normal_or_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 764)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400 ; missing fabs
|
|
%class = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @not_issubnormal_or_inf(half %x) {
|
|
; CHECK-LABEL: @not_issubnormal_or_inf(
|
|
; CHECK-NEXT: [[NOT:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 267)
|
|
; CHECK-NEXT: ret i1 [[NOT]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp une half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
|
|
%not = and i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %not
|
|
}
|
|
|
|
define i1 @issubnormal_uge_or_inf(half %x) {
|
|
; CHECK-LABEL: @issubnormal_uge_or_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
; Negative test, not smallest normal
|
|
define i1 @issubnormal_or_inf_wrong_val(half %x) {
|
|
; CHECK-LABEL: @issubnormal_or_inf_wrong_val(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0401
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0401
|
|
%class = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @issubnormal_or_inf_neg_smallest_normal(half %x) {
|
|
; CHECK-LABEL: @issubnormal_or_inf_neg_smallest_normal(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CMPINF]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH8400
|
|
%class = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fneg_fabs_olt_neg_smallest_normal_or_inf(half %x) {
|
|
; CHECK-LABEL: @fneg_fabs_olt_neg_smallest_normal_or_inf(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp ogt half [[FABS]], 0xH0400
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%fneg.fabs = fneg half %fabs
|
|
%cmp.smallest.normal = fcmp olt half %fneg.fabs, 0xH8400
|
|
%class = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @issubnormal_or_finite_olt(half %x) {
|
|
; CHECK-LABEL: @issubnormal_or_finite_olt(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp olt half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%or = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %or
|
|
}
|
|
|
|
; inf | nan | zero | subnormal
|
|
define i1 @issubnormal_or_finite_uge(half %x) {
|
|
; CHECK-LABEL: @issubnormal_or_finite_uge(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 759)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp uge half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%or = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @issubnormal_and_finite_olt(half %x) {
|
|
; CHECK-LABEL: @issubnormal_and_finite_olt(
|
|
; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp olt half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%and = and i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @not_zero_and_subnormal(half %x) {
|
|
; CHECK-LABEL: @not_zero_and_subnormal(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmp.zero = fcmp one half %fabs, 0.0
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%or = or i1 %cmp.smallest.normal, %cmp.zero
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(half %x) {
|
|
; CHECK-LABEL: @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp uge half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
|
|
%or = or i1 %cmp.smallest.normal, %cmpinf
|
|
ret i1 %or
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; Test ord/uno
|
|
; --------------------------------------------------------------------
|
|
|
|
define i1 @is_finite_and_ord(half %x) {
|
|
; CHECK-LABEL: @is_finite_and_ord(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.finite = fcmp ueq half %fabs, 0xH7C00
|
|
%ord = fcmp ord half %x, %x
|
|
%and = and i1 %ord, %is.finite
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @is_finite_and_uno(half %x) {
|
|
; CHECK-LABEL: @is_finite_and_uno(
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.finite = fcmp ueq half %fabs, 0xH7C00
|
|
%uno = fcmp uno half %x, %x
|
|
%and = and i1 %uno, %is.finite
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @is_finite_or_ord(half %x) {
|
|
; CHECK-LABEL: @is_finite_or_ord(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.finite = fcmp ueq half %fabs, 0xH7C00
|
|
%ord = fcmp ord half %x, %x
|
|
%or = or i1 %ord, %is.finite
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @is_finite_or_uno(half %x) {
|
|
; CHECK-LABEL: @is_finite_or_uno(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.finite = fcmp ueq half %fabs, 0xH7C00
|
|
%uno = fcmp uno half %x, %x
|
|
%or = or i1 %uno, %is.finite
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @oeq_isinf_or_uno(half %x) {
|
|
; CHECK-LABEL: @oeq_isinf_or_uno(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0000
|
|
%class = or i1 %cmpinf, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @oeq_isinf_or_ord(half %x) {
|
|
; CHECK-LABEL: @oeq_isinf_or_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%uno = fcmp ord half %x, 0xH0000
|
|
%class = or i1 %cmpinf, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @oeq_isinf_and_uno(half %x) {
|
|
; CHECK-LABEL: @oeq_isinf_and_uno(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0000
|
|
%and = and i1 %cmpinf, %uno
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @oeq_isinf_and_ord(half %x) {
|
|
; CHECK-LABEL: @oeq_isinf_and_ord(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp oeq half %fabs, 0xH7C00
|
|
%uno = fcmp ord half %x, 0xH0000
|
|
%and = and i1 %cmpinf, %uno
|
|
ret i1 %and
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; isnormal(x) || x == 0.0
|
|
; --------------------------------------------------------------------
|
|
|
|
define i1 @isnormal_or_zero(half %x) #0 {
|
|
; CHECK-LABEL: @isnormal_or_zero(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[AND1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360)
|
|
; CHECK-NEXT: ret i1 [[AND1]]
|
|
;
|
|
entry:
|
|
%iseq = fcmp ord half %x, 0xH0000
|
|
%fabs = tail call half @llvm.fabs.f16(half %x)
|
|
%isinf = fcmp ult half %fabs, 0xH7C00
|
|
%isnormal = fcmp uge half %fabs, 0xH0400
|
|
%and = and i1 %iseq, %isinf
|
|
%and1 = and i1 %isnormal, %and
|
|
%cmp = fcmp oeq half %x, 0xH0000
|
|
%spec.select = or i1 %cmp, %and1
|
|
ret i1 %spec.select
|
|
}
|
|
|
|
define i1 @isnormal_uge_or_zero_oeq(half %x) #0 {
|
|
; CHECK-LABEL: @isnormal_uge_or_zero_oeq(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 879)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
entry:
|
|
%fabs = tail call half @llvm.fabs.f16(half %x)
|
|
%is.normal = fcmp uge half %fabs, 0xH0400
|
|
%is.zero = fcmp oeq half %x, 0xH0000
|
|
%or = or i1 %is.normal, %is.zero
|
|
ret i1 %or
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; smallest_normal check part of isnormal(x)
|
|
; --------------------------------------------------------------------
|
|
|
|
; -> ord
|
|
define i1 @isnormalinf_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @isnormalinf_or_ord(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%is.ord = fcmp ord half %x, 0xH0000
|
|
%or = or i1 %is.normal.inf, %is.ord
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @ord_or_isnormalinf(half %x) #0 {
|
|
; CHECK-LABEL: @ord_or_isnormalinf(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%is.ord = fcmp ord half %x, 0xH0000
|
|
%or = or i1 %is.ord, %is.normal.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; No fabs
|
|
; -> iszero
|
|
define i1 @une_or_oge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @une_or_oge_smallest_normal(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%is.normal.inf = fcmp oge half %x, 0xH0400
|
|
%is.une = fcmp une half %x, 0xH0000
|
|
%or = or i1 %is.une, %is.normal.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> normal | inf
|
|
define i1 @isnormalinf_or_inf(half %x) #0 {
|
|
; CHECK-LABEL: @isnormalinf_or_inf(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%is.inf = fcmp oeq half %fabs, 0xH7C00
|
|
%or = or i1 %is.normal.inf, %is.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> pinf | pnormal
|
|
define i1 @posisnormalinf_or_posinf(half %x) #0 {
|
|
; CHECK-LABEL: @posisnormalinf_or_posinf(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.pos.normal.inf = fcmp oge half %x, 0xH0400
|
|
%is.inf = fcmp oeq half %fabs, 0xH7C00
|
|
%or = or i1 %is.pos.normal.inf, %is.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> normal | inf
|
|
define i1 @isnormalinf_or_posinf(half %x) #0 {
|
|
; CHECK-LABEL: @isnormalinf_or_posinf(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%is.pos.inf = fcmp oeq half %x, 0xH7C00
|
|
%or = or i1 %is.normal.inf, %is.pos.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> pinf|ninf
|
|
define i1 @isnormalinf_and_inf(half %x) #0 {
|
|
; CHECK-LABEL: @isnormalinf_and_inf(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%is.inf = fcmp oeq half %fabs, 0xH7C00
|
|
%and = and i1 %is.normal.inf, %is.inf
|
|
ret i1 %and
|
|
}
|
|
|
|
; -> pinf
|
|
define i1 @posisnormalinf_and_posinf(half %x) #0 {
|
|
; CHECK-LABEL: @posisnormalinf_and_posinf(
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.pos.normal.inf = fcmp oge half %x, 0xH0400
|
|
%is.inf = fcmp oeq half %fabs, 0xH7C00
|
|
%and = and i1 %is.pos.normal.inf, %is.inf
|
|
ret i1 %and
|
|
}
|
|
|
|
; -> pinf
|
|
define i1 @isnormalinf_and_posinf(half %x) #0 {
|
|
; CHECK-LABEL: @isnormalinf_and_posinf(
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%is.pos.inf = fcmp oeq half %x, 0xH7C00
|
|
%and = and i1 %is.normal.inf, %is.pos.inf
|
|
ret i1 %and
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; smallest_normal check part of isnormal(x) with inverted compare
|
|
; --------------------------------------------------------------------
|
|
|
|
; -> true
|
|
define i1 @not_isnormalinf_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @not_isnormalinf_or_ord(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%not.is.normal.inf = fcmp ult half %fabs, 0xH0400
|
|
%is.ord = fcmp ord half %x, 0xH0000
|
|
%or = or i1 %not.is.normal.inf, %is.ord
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> subnormal | zero
|
|
define i1 @not_isnormalinf_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @not_isnormalinf_and_ord(
|
|
; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%not.is.normal.inf = fcmp ult half %fabs, 0xH0400
|
|
%is.ord = fcmp ord half %x, 0xH0000
|
|
%and = and i1 %not.is.normal.inf, %is.ord
|
|
ret i1 %and
|
|
}
|
|
|
|
; -> ~ninf
|
|
define i1 @not_isnormalinf_or_inf(half %x) #0 {
|
|
; CHECK-LABEL: @not_isnormalinf_or_inf(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%not.is.normal.inf = fcmp ult half %fabs, 0xH0400
|
|
%is.inf = fcmp olt half %fabs, 0xH7C00
|
|
%or = or i1 %not.is.normal.inf, %is.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> subnormal | zero | nan
|
|
define i1 @not_isnormalinf_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @not_isnormalinf_or_uno(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 243)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%not.is.normal.inf = fcmp ult half %fabs, 0xH0400
|
|
%is.uno = fcmp uno half %fabs, 0.0
|
|
%or = or i1 %not.is.normal.inf, %is.uno
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> subnormal | zero | nan
|
|
define i1 @not_isnormalinf_or_uno_nofabs(half %x) #0 {
|
|
; CHECK-LABEL: @not_isnormalinf_or_uno_nofabs(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 243)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%not.is.normal.inf = fcmp ult half %fabs, 0xH0400
|
|
%is.uno = fcmp uno half %x, 0.0
|
|
%or = or i1 %not.is.normal.inf, %is.uno
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> ~pnormal
|
|
define i1 @not_negisnormalinf_or_inf(half %x) #0 {
|
|
; CHECK-LABEL: @not_negisnormalinf_or_inf(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%not.is.neg.normal.inf = fcmp ult half %x, 0xH0400
|
|
%is.inf = fcmp oeq half %fabs, 0xH7C00
|
|
%or = or i1 %not.is.neg.normal.inf, %is.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> ~pnormal
|
|
define i1 @not_negisnormalinf_or_posinf(half %x) #0 {
|
|
; CHECK-LABEL: @not_negisnormalinf_or_posinf(
|
|
; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%not.is.pos.normal.inf = fcmp ult half %x, 0xH0400
|
|
%is.inf = fcmp oeq half %x, 0xH7C00
|
|
%or = or i1 %not.is.pos.normal.inf, %is.inf
|
|
ret i1 %or
|
|
}
|
|
|
|
; -> ninf | nnormal
|
|
define i1 @not_isposnormalinf_and_isnormalinf(half %x) #0 {
|
|
; CHECK-LABEL: @not_isposnormalinf_and_isnormalinf(
|
|
; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 12)
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%not.is.pos.normal.inf = fcmp ult half %x, 0xH0400
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.normal.inf = fcmp oge half %fabs, 0xH0400
|
|
%and = and i1 %not.is.pos.normal.inf, %is.normal.inf
|
|
ret i1 %and
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @olt_smallest_normal_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_or_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%ord = fcmp ord half %x, 0.0
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~pinf
|
|
define i1 @olt_smallest_normal_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_or_uno(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%uno = fcmp uno half %x, 0.0
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_smallest_normal_or_finite(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_or_finite(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.finite = fcmp olt half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %is.finite
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @uge_smallest_normal_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @uge_smallest_normal_or_ord(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%ord = fcmp ord half %x, 0.0
|
|
%cmp.smallest.normal = fcmp uge half %x, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> nan | pnormal | pinf
|
|
define i1 @uge_smallest_normal_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @uge_smallest_normal_or_uno(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 771)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%uno = fcmp uno half %x, 0.0
|
|
%cmp.smallest.normal = fcmp uge half %x, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> uno
|
|
define i1 @uge_smallest_normal_and_uno(half %x) #0 {
|
|
; CHECK-LABEL: @uge_smallest_normal_and_uno(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%uno = fcmp uno half %x, 0.0
|
|
%cmp.smallest.normal = fcmp uge half %x, 0xH0400
|
|
%class = and i1 %cmp.smallest.normal, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> true
|
|
define i1 @olt_infinity_or_finite(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_or_finite(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %cmp.smallest.normal, %lt.infinity
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> zero|subnormal|normal
|
|
define i1 @olt_infinity_and_finite(half %x) #0 { ; bustttedddd
|
|
; CHECK-LABEL: @olt_infinity_and_finite(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = and i1 %cmp.smallest.normal, %lt.infinity
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @olt_infinity_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_or_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%ord = fcmp ord half %x, 0xH0400
|
|
%class = or i1 %lt.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~posinf
|
|
define i1 @olt_infinity_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_or_uno(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0400
|
|
%class = or i1 %lt.infinity, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_infinity_or_subnormal(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_or_subnormal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.subnormal = fcmp olt half %fabs, 0xH0400
|
|
%class = or i1 %lt.infinity, %is.subnormal
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_infinity_and_subnormal(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_and_subnormal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.subnormal = fcmp olt half %fabs, 0xH0400
|
|
%class = and i1 %lt.infinity, %is.subnormal
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_infinity_and_not_subnormal(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_and_not_subnormal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 268)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.subnormal = fcmp olt half %fabs, 0xH0400
|
|
%not.subnormal = xor i1 %is.subnormal, true
|
|
%class = and i1 %lt.infinity, %not.subnormal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf
|
|
define i1 @olt_infinity_and_ueq_inf(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_and_ueq_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%eq.inf = fcmp ueq half %fabs, 0xH7C00
|
|
%class = and i1 %lt.infinity, %eq.inf
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> true
|
|
define i1 @olt_infinity_or_ueq_inf(half %x) #0 {
|
|
; CHECK-LABEL: @olt_infinity_or_ueq_inf(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%lt.infinity = fcmp olt half %x, 0xH7C00
|
|
%eq.inf = fcmp ueq half %x, 0xH7C00
|
|
%class = or i1 %lt.infinity, %eq.inf
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> pnormal
|
|
define i1 @olt_smallest_normal_or_ueq_inf(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_or_ueq_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.normal = fcmp olt half %x, 0xH0400
|
|
%eq.inf = fcmp ueq half %x, 0xH7C00
|
|
%class = or i1 %lt.normal, %eq.inf
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~pinf
|
|
define i1 @olt_smallest_normal_or_une_inf(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_or_une_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.normal = fcmp olt half %x, 0xH0400
|
|
%eq.inf = fcmp une half %x, 0xH7C00
|
|
%class = or i1 %lt.normal, %eq.inf
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf | nnormal | subnormal | zero
|
|
define i1 @olt_smallest_normal_and_une_inf(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_and_une_inf(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.normal = fcmp olt half %x, 0xH0400
|
|
%eq.inf = fcmp une half %x, 0xH7C00
|
|
%class = and i1 %lt.normal, %eq.inf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.normal = fcmp olt half %x, 0xH0400
|
|
%eq.inf = fcmp une half %x, 0xH7C00
|
|
%class = and i1 %lt.normal, %eq.inf
|
|
%eq.normal = fcmp oeq half %x, 0xH0400
|
|
%eq.largest.normal = or i1 %eq.normal, %class
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @olt_smallest_normal_and_une_inf_or_one_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_one_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%lt.normal = fcmp olt half %x, 0xH0400
|
|
%eq.inf = fcmp une half %x, 0xH7C00
|
|
%class = and i1 %lt.normal, %eq.inf
|
|
%ne.normal = fcmp one half %x, 0xH0400
|
|
%eq.largest.normal = or i1 %ne.normal, %class
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @oge_fabs_eq_inf_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @oge_fabs_eq_inf_and_ord(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%oge.fabs.inf = fcmp oge half %fabs, 0xH7C00
|
|
%ord = fcmp ord half %x, 0xH0000
|
|
%and = and i1 %oge.fabs.inf, %ord
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @oge_eq_inf_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @oge_eq_inf_and_ord(
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%oge.fabs.inf = fcmp oge half %x, 0xH7C00
|
|
%ord = fcmp ord half %x, 0xH0000
|
|
%and = and i1 %oge.fabs.inf, %ord
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @oge_fabs_eq_inf_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @oge_fabs_eq_inf_or_uno(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%oge.fabs.inf = fcmp oge half %fabs, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0000
|
|
%or = or i1 %oge.fabs.inf, %uno
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @oge_eq_inf_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @oge_eq_inf_or_uno(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%oge.fabs.inf = fcmp oge half %x, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0000
|
|
%or = or i1 %oge.fabs.inf, %uno
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @ult_fabs_eq_inf_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @ult_fabs_eq_inf_and_ord(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp olt half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%ult.fabs.inf = fcmp ult half %fabs, 0xH7C00
|
|
%ord = fcmp ord half %x, 0xH0000
|
|
%and = and i1 %ult.fabs.inf, %ord
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @ult_eq_inf_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @ult_eq_inf_and_ord(
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp olt half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%ult.fabs.inf = fcmp ult half %x, 0xH7C00
|
|
%ord = fcmp ord half %x, 0xH0000
|
|
%and = and i1 %ult.fabs.inf, %ord
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @ult_fabs_eq_inf_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @ult_fabs_eq_inf_or_uno(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%ult.fabs.inf = fcmp ult half %fabs, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0000
|
|
%or = or i1 %ult.fabs.inf, %uno
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @ult_eq_inf_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @ult_eq_inf_or_uno(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%ult.fabs.inf = fcmp ult half %x, 0xH7C00
|
|
%uno = fcmp uno half %x, 0xH0000
|
|
%or = or i1 %ult.fabs.inf, %uno
|
|
ret i1 %or
|
|
}
|
|
|
|
|
|
; Can't do anything with this
|
|
define i1 @oeq_neginfinity_or_oeq_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_or_oeq_smallest_normal(
|
|
; CHECK-NEXT: [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH0400
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[OEQ_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp oeq half %x, 0xH0400
|
|
%class = or i1 %oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf | fcZero | fcSubnormal
|
|
define i1 @oeq_neginfinity_or_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_or_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf
|
|
define i1 @oeq_neginfinity_and_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_and_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = and i1 %oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf | pnormal | pinf
|
|
define i1 @oeq_neginfinity_or_oge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_or_oge_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp oge half %x, 0xH0400
|
|
%class = or i1 %oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> false
|
|
define i1 @oeq_neginfinity_and_oge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_and_oge_smallest_normal(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp oge half %x, 0xH0400
|
|
%class = and i1 %oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @oeq_neginfinity_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_or_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%ord = fcmp ord half %x, 0.0
|
|
%class = or i1 %oeq.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf
|
|
define i1 @oeq_neginfinity_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @oeq_neginfinity_and_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
|
|
%ord = fcmp ord half %x, 0.0
|
|
%class = and i1 %oeq.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; can't do anything with this
|
|
define i1 @une_neginfinity_or_oeq_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @une_neginfinity_or_oeq_smallest_normal(
|
|
; CHECK-NEXT: [[UNE_NEG_INFINITY:%.*]] = fcmp une half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH0400
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[UNE_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%une.neg.infinity = fcmp une half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp oeq half %x, 0xH0400
|
|
%class = or i1 %une.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> true
|
|
define i1 @une_neginfinity_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @une_neginfinity_or_ord(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%une.neg.infinity = fcmp une half %x, 0xHFC00
|
|
%ord = fcmp ord half %x, 0.0
|
|
%class = or i1 %une.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~(nan | ninf)
|
|
define i1 @une_neginfinity_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @une_neginfinity_and_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%une.neg.infinity = fcmp une half %x, 0xHFC00
|
|
%ord = fcmp ord half %x, 0.0
|
|
%class = and i1 %une.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @one_neginfinity_or_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @one_neginfinity_or_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%one.neg.infinity = fcmp one half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %one.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~(nan|ninf)
|
|
define i1 @one_neginfinity_and_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @one_neginfinity_and_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 248)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%one.neg.infinity = fcmp one half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = and i1 %one.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~ninf
|
|
define i1 @one_neginfinity_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @one_neginfinity_or_uno(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%one.neg.infinity = fcmp one half %x, 0xHFC00
|
|
%uno = fcmp uno half %x, 0.0
|
|
%class = or i1 %one.neg.infinity, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~ninf
|
|
define i1 @one_neginfinity_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @one_neginfinity_and_ord(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%one.neg.infinity = fcmp one half %x, 0xHFC00
|
|
%ord = fcmp uno half %x, 0.0
|
|
%class = and i1 %one.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> pnormal|pinf
|
|
define i1 @one_neginfinity_and_uge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @one_neginfinity_and_uge_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%one.neg.infinity = fcmp one half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp uge half %x, 0xH0400
|
|
%class = and i1 %one.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~(pnormal|pinf)
|
|
define i1 @ueq_neginfinity_or_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @ueq_neginfinity_or_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %ueq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ninf
|
|
define i1 @ueq_neginfinity_and_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @ueq_neginfinity_and_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = and i1 %ueq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> nan|ninf
|
|
define i1 @ueq_neginfinity_or_uno(half %x) #0 {
|
|
; CHECK-LABEL: @ueq_neginfinity_or_uno(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
|
|
%uno = fcmp uno half %x, 0.0
|
|
%class = or i1 %ueq.neg.infinity, %uno
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> nan|ninf
|
|
define i1 @ueq_neginfinity_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @ueq_neginfinity_and_ord(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
|
|
%ord = fcmp uno half %x, 0.0
|
|
%class = and i1 %ueq.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> uno
|
|
define i1 @ueq_neginfinity_and_uge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @ueq_neginfinity_and_uge_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
|
|
%cmp.smallest.normal = fcmp uge half %x, 0xH0400
|
|
%class = and i1 %ueq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @fabs_oeq_neginfinity_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_oeq_neginfinity_or_ord(
|
|
; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[ORD]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
|
|
%ord = fcmp ord half %x, 0.0
|
|
%class = or i1 %fabs.oeq.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> true
|
|
define i1 @fabs_une_neginfinity_or_ord(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_une_neginfinity_or_ord(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC00
|
|
%ord = fcmp une half %x, 0.0
|
|
%class = or i1 %fabs.une.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> une
|
|
define i1 @fabs_une_neginfinity_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_une_neginfinity_and_ord(
|
|
; CHECK-NEXT: [[ORD:%.*]] = fcmp une half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[ORD]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC00
|
|
%ord = fcmp une half %x, 0.0
|
|
%class = and i1 %fabs.une.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> false
|
|
define i1 @fabs_oeq_neginfinity_and_uge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_oeq_neginfinity_and_uge_smallest_normal(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
|
|
%cmp.smallest.normal = fcmp oeq half %x, 0xH0400
|
|
%class = and i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> false
|
|
define i1 @fabs_oeq_neginfinity_or_uge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_oeq_neginfinity_or_uge_smallest_normal(
|
|
; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X:%.*]], 0xH0400
|
|
; CHECK-NEXT: ret i1 [[CMP_SMALLEST_NORMAL]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
|
|
%cmp.smallest.normal = fcmp oeq half %x, 0xH0400
|
|
%class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
;- > ord
|
|
define i1 @fabs_oeq_neginfinity_and_ord(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_oeq_neginfinity_and_ord(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC00
|
|
%ord = fcmp ord half %x, 0.0
|
|
%class = and i1 %fabs.oeq.neg.infinity, %ord
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> false
|
|
define i1 @fabs_ueq_neginfinity_and_olt_smallest_normal(half %x) #0 { ; WRONG
|
|
; CHECK-LABEL: @fabs_ueq_neginfinity_and_olt_smallest_normal(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.ueq.neg.infinity = fcmp ueq half %fabs, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = and i1 %fabs.ueq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> pinf|pnormal
|
|
define i1 @fabs_one_neginfinity_and_uge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_one_neginfinity_and_uge_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC00
|
|
%cmp.smallest.normal = fcmp uge half %x, 0xH0400
|
|
%class = and i1 %fabs.one.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ord
|
|
define i1 @fabs_one_neginfinity_or_olt_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_one_neginfinity_or_olt_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC00
|
|
%cmp.smallest.normal = fcmp olt half %x, 0xH0400
|
|
%class = or i1 %fabs.one.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; -> ~(zero|subnormal)
|
|
define i1 @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(half %x) #0 {
|
|
; CHECK-LABEL: @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%fabs.oeq.neg.infinity = fcmp ueq half %fabs, 0xHFC00
|
|
%cmp.smallest.normal = fcmp uge half %fabs, 0xH0400
|
|
%class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
; --------------------------------------------------------------------
|
|
; Test denormal mode handling with x == 0
|
|
; --------------------------------------------------------------------
|
|
|
|
; Base pattern !isfinite(x) || x == 0.0, with input denormals flushed to 0
|
|
define i1 @not_isfinite_or_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_daz(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define <2 x i1> @not_isfinite_or_zero_v2f16_daz(<2 x half> %x) #1 {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_v2f16_daz(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], <half 0xH7C00, half 0xH7C00>
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret <2 x i1> [[CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
|
|
%class = or <2 x i1> %cmpzero, %cmpinf
|
|
ret <2 x i1> %class
|
|
}
|
|
|
|
; Base pattern !isfinite(x) || x == 0.0, with unknown input denormal treatment
|
|
define i1 @not_isfinite_or_zero_f16_dynamic(half %x) #2 {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_f16_dynamic(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp ueq half %fabs, 0xH7C00
|
|
%cmpzero = fcmp oeq half %x, 0xH0000
|
|
%class = or i1 %cmpzero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define <2 x i1> @not_isfinite_or_zero_v2f16_dynamic(<2 x half> %x) #2 {
|
|
; CHECK-LABEL: @not_isfinite_or_zero_v2f16_dynamic(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], <half 0xH7C00, half 0xH7C00>
|
|
; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret <2 x i1> [[CLASS]]
|
|
;
|
|
%fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
|
|
%cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>
|
|
%cmpzero = fcmp oeq <2 x half> %x, zeroinitializer
|
|
%class = or <2 x i1> %cmpzero, %cmpinf
|
|
ret <2 x i1> %class
|
|
}
|
|
|
|
define i1 @not_zero_and_subnormal_daz(half %x) #1 {
|
|
; CHECK-LABEL: @not_zero_and_subnormal_daz(
|
|
; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmp.zero = fcmp one half %fabs, 0.0
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%or = or i1 %cmp.smallest.normal, %cmp.zero
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @not_zero_and_subnormal_dynamic(half %x) #2 {
|
|
; CHECK-LABEL: @not_zero_and_subnormal_dynamic(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[CMP_ZERO:%.*]] = fcmp one half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMP_ZERO]]
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%cmp.zero = fcmp one half %fabs, 0.0
|
|
%cmp.smallest.normal = fcmp olt half %fabs, 0xH0400
|
|
%or = or i1 %cmp.smallest.normal, %cmp.zero
|
|
ret i1 %or
|
|
}
|
|
|
|
; TODO: This could fold to just fcmp olt half %fabs, 0xH0400
|
|
define i1 @subnormal_or_zero_ieee(half %x) #0 {
|
|
; CHECK-LABEL: @subnormal_or_zero_ieee(
|
|
; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.subnormal = fcmp olt half %fabs, 0xH0400
|
|
%is.zero = fcmp oeq half %x, 0xH0000
|
|
%and = or i1 %is.subnormal, %is.zero
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @subnormal_or_zero_daz(half %x) #1 {
|
|
; CHECK-LABEL: @subnormal_or_zero_daz(
|
|
; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.subnormal = fcmp olt half %fabs, 0xH0400
|
|
%is.zero = fcmp oeq half %x, 0xH0000
|
|
%and = or i1 %is.subnormal, %is.zero
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @subnormal_or_zero_dynamic(half %x) #2 {
|
|
; CHECK-LABEL: @subnormal_or_zero_dynamic(
|
|
; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
|
|
; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
|
|
; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[AND:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_ZERO]]
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%fabs = call half @llvm.fabs.f16(half %x)
|
|
%is.subnormal = fcmp olt half %fabs, 0xH0400
|
|
%is.zero = fcmp oeq half %x, 0xH0000
|
|
%and = or i1 %is.subnormal, %is.zero
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @issubnormal_or_inf_nnan_logical_select(half %x) {
|
|
; CHECK-LABEL: @issubnormal_or_inf_nnan_logical_select(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call nnan half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp nnan oeq half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH0400
|
|
%class = select i1 %cmpinf, i1 true, i1 %cmp.smallest.normal
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @issubnormal_and_ninf_nnan_logical_select(half %x) {
|
|
; CHECK-LABEL: @issubnormal_and_ninf_nnan_logical_select(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%fabs = call nnan half @llvm.fabs.f16(half %x)
|
|
%cmpinf = fcmp nnan one half %fabs, 0xH7C00
|
|
%cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH0400
|
|
%class = select i1 %cmpinf, i1 %cmp.smallest.normal, i1 false
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_neginf_or_oge_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 999)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xHFC00
|
|
%cmp.oge.zero = fcmp oge half %x, 0xH0000
|
|
%class = or i1 %cmp.oge.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_neginf_or_oge_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 996)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xHFC00
|
|
%cmp.oge.zero = fcmp oge half %x, 0xH0000
|
|
%class = or i1 %cmp.oge.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_neginf_or_oge_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xHFC00
|
|
%cmp.oge.zero = fcmp oge half %x, 0xH0000
|
|
%class = or i1 %cmp.oge.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_neginf_or_oge_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xHFC00
|
|
%cmp.oge.zero = fcmp oge half %x, 0xH0000
|
|
%class = or i1 %cmp.oge.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_neginf_or_ogt_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 900)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xHFC00
|
|
%cmp.ogt.zero = fcmp ogt half %x, 0xH0000
|
|
%class = or i1 %cmp.ogt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_neginf_or_ogt_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xHFC00
|
|
%cmp.ogt.zero = fcmp ogt half %x, 0xH0000
|
|
%class = or i1 %cmp.ogt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_neginf_or_ogt_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xHFC00
|
|
%cmp.ogt.zero = fcmp ogt half %x, 0xH0000
|
|
%class = or i1 %cmp.ogt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_neginf_or_ogt_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xHFC00
|
|
%cmp.ogt.zero = fcmp ogt half %x, 0xH0000
|
|
%class = or i1 %cmp.ogt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_neginf_or_ugt_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xHFC00
|
|
%cmp.ugt.zero = fcmp ugt half %x, 0xH0000
|
|
%class = or i1 %cmp.ugt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_neginf_or_ugt_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_ueq_neginf_or_ugt_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xHFC00
|
|
%cmp.ugt.zero = fcmp ugt half %x, 0xH0000
|
|
%class = or i1 %cmp.ugt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_neginf_or_ugt_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
|
|
; CHECK-NEXT: [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xHFC00
|
|
%cmp.ugt.zero = fcmp ugt half %x, 0xH0000
|
|
%class = or i1 %cmp.ugt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_ole_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.ole.zero = fcmp ole half %x, 0xH0000
|
|
%class = or i1 %cmp.ole.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_ole_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 636)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.ole.zero = fcmp ole half %x, 0xH0000
|
|
%class = or i1 %cmp.ole.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_ole_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.ole.zero = fcmp ole half %x, 0xH0000
|
|
%class = or i1 %cmp.ole.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_ole_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.ole.zero = fcmp ole half %x, 0xH0000
|
|
%class = or i1 %cmp.ole.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_olt_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 540)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.olt.zero = fcmp olt half %x, 0xH0000
|
|
%class = or i1 %cmp.olt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_olt_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_OLT_ZERO:%.*]] = fcmp olt half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.olt.zero = fcmp olt half %x, 0xH0000
|
|
%class = or i1 %cmp.olt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_ult_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.ult.zero = fcmp ult half %x, 0xH0000
|
|
%class = or i1 %cmp.ult.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_ult_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.ult.zero = fcmp ult half %x, 0xH0000
|
|
%class = or i1 %cmp.ult.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_ult_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.ult.zero = fcmp ult half %x, 0xH0000
|
|
%class = or i1 %cmp.ult.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_ult_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.ult.zero = fcmp ult half %x, 0xH0000
|
|
%class = or i1 %cmp.ult.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_ule_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.ule.zero = fcmp ule half %x, 0xH0000
|
|
%class = or i1 %cmp.ule.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_ule_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.ule.zero = fcmp ule half %x, 0xH0000
|
|
%class = or i1 %cmp.ule.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_oeq_posinf_or_ule_zero_f16_daz(half %x) #1 {
|
|
; CHECK-LABEL: @fcmp_oeq_posinf_or_ule_zero_f16_daz(
|
|
; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
|
|
; CHECK-NEXT: [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH0000
|
|
; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]]
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp oeq half %x, 0xH7C00
|
|
%cmp.ule.zero = fcmp ule half %x, 0xH0000
|
|
%class = or i1 %cmp.ule.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
define i1 @fcmp_ueq_posinf_or_olt_zero_f16(half %x) {
|
|
; CHECK-LABEL: @fcmp_ueq_posinf_or_olt_zero_f16(
|
|
; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)
|
|
; CHECK-NEXT: ret i1 [[CLASS]]
|
|
;
|
|
%cmpinf = fcmp ueq half %x, 0xH7C00
|
|
%cmp.olt.zero = fcmp olt half %x, 0xH0000
|
|
%class = or i1 %cmp.olt.zero, %cmpinf
|
|
ret i1 %class
|
|
}
|
|
|
|
declare half @llvm.fabs.f16(half) #0
|
|
declare half @llvm.canonicalize.f16(half) #0
|
|
declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0
|
|
|
|
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
|
attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }
|
|
attributes #2 = { "denormal-fp-math"="ieee,dynamic" }
|