CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
2386 lines
112 KiB
LLVM
2386 lines
112 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
|
|
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
|
|
|
|
declare nofpclass(nan inf sub norm) half @returns_zero()
|
|
declare nofpclass(nan inf nzero sub norm) half @returns_pzero()
|
|
declare nofpclass(nan inf pzero sub norm) half @returns_nzero()
|
|
declare nofpclass(nan inf zero sub nnorm) half @returns_pnorm()
|
|
declare nofpclass(nan inf zero sub pnorm) half @returns_nnorm()
|
|
declare nofpclass(nan inf norm zero) half @returns_sub()
|
|
declare nofpclass(nan inf norm nsub zero) half @returns_psub()
|
|
declare nofpclass(nan inf norm psub zero) half @returns_nsub()
|
|
declare nofpclass(nan inf sub zero) half @returns_norm()
|
|
declare nofpclass(nan norm sub zero) half @returns_inf()
|
|
declare nofpclass(qnan inf norm sub zero) half @returns_snan()
|
|
declare void @use(half)
|
|
|
|
define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_unknown_or_pinf(i1 %cond, half %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_unknown_or_pinf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[Y_OR_PINF:%.*]] = select i1 [[COND]], half [[Y]], half +inf
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fdiv half [[X_OR_PINF]], [[Y_OR_PINF]]
|
|
; CHECK-NEXT: ret half [[TMP1]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%y.or.pinf = select i1 %cond, half %y, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %y.or.pinf
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_nofpclass_pinf__fdiv_unknown_or_ninf(i1 %cond, half %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_nofpclass_pinf__fdiv_unknown_or_ninf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_NINF:%.*]] = select i1 [[COND]], half [[X]], half -inf
|
|
; CHECK-NEXT: [[Y_OR_NINF:%.*]] = select i1 [[COND]], half [[Y]], half -inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X_OR_NINF]], [[Y_OR_NINF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.ninf = select i1 %cond, half %x, half 0xFFF0000000000000
|
|
%y.or.ninf = select i1 %cond, half %y, half 0xFFF0000000000000
|
|
%div = fdiv half %x.or.ninf, %y.or.ninf
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_nofpclass_inf__fdiv_unknown_or_pinf(i1 %cond, half %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_nofpclass_inf__fdiv_unknown_or_pinf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[Y_OR_PINF:%.*]] = select i1 [[COND]], half [[Y]], half +inf
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fdiv half [[X_OR_PINF]], [[Y_OR_PINF]]
|
|
; CHECK-NEXT: ret half [[TMP1]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%y.or.pinf = select i1 %cond, half %y, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %y.or.pinf
|
|
ret half %div
|
|
}
|
|
|
|
; -> Only propagate nan %x
|
|
define nofpclass(pinf pnorm psub pzero) half @ret_only_negative_results_or_nan_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) half @ret_only_negative_results_or_nan_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
; -> poison
|
|
define nofpclass(pinf pnorm psub pzero nan) half @ret_only_negative_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) half @ret_only_negative_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
; Cannot fold if undef
|
|
define nofpclass(pinf pnorm psub pzero nan) half @ret_only_negative_results_self_maybe_undef(half %x) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) half @ret_only_negative_results_self_maybe_undef(
|
|
; CHECK-SAME: half [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub) half @ret_only_zero_or_nan_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(inf sub norm) half @ret_only_zero_or_nan_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub nan) half @ret_only_zero_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @ret_only_zero_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @ret_only_nan_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero snan) half @ret_only_qnan_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(snan inf zero sub norm) half @ret_only_qnan_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero qnan) half @ret_only_snan_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) half @ret_only_snan_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(norm sub zero) half @ret_only_inf_or_nan_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(zero sub norm) half @ret_only_inf_or_nan_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(norm sub zero nan) half @ret_only_inf_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(nan zero sub norm) half @ret_only_inf_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf norm sub zero) half @ret_only_pinf_or_nan_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(ninf zero sub norm) half @ret_only_pinf_or_nan_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf norm sub zero nan) half @ret_only_pinf_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) half @ret_only_pinf_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
; -> poison
|
|
define nofpclass(pinf norm sub zero nan) half @ret_only_ninf_results_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) half @ret_only_ninf_results_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_zero_self(half noundef nofpclass(nan inf norm sub) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_zero_self(
|
|
; CHECK-SAME: half noundef nofpclass(nan inf sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_pzero(half noundef nofpclass(nan inf norm sub nzero) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_pzero(
|
|
; CHECK-SAME: half noundef nofpclass(nan inf nzero sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_nzero(half noundef nofpclass(nan inf norm sub pzero) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_nzero(
|
|
; CHECK-SAME: half noundef nofpclass(nan inf pzero sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self(half noundef nofpclass(inf norm sub) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self(
|
|
; CHECK-SAME: half noundef nofpclass(inf sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self__preserve_flags(half noundef nofpclass(inf norm sub) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self__preserve_flags(
|
|
; CHECK-SAME: half noundef nofpclass(inf sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv contract half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self_other_use_input0(half noundef nofpclass(inf norm sub) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self_other_use_input0(
|
|
; CHECK-SAME: half noundef nofpclass(inf sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: call void @use(half [[X]])
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
call void @use(half %x)
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self_other_use_input1(half noundef nofpclass(inf norm sub) %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_src_must_be_zero_or_nan_self_other_use_input1(
|
|
; CHECK-SAME: half noundef nofpclass(inf sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: call void @use(half [[X]])
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
call void @use(half %x)
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_nonan_self(half noundef nofpclass(nan) %x) !prof !0 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_nonan_self(
|
|
; CHECK-SAME: half noundef nofpclass(nan) [[X:%.*]]) !prof [[PROF0:![0-9]+]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 612)
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00, !prof [[PROF1:![0-9]+]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half 1.000000e+00
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_noinf_self(half noundef nofpclass(inf) %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_noinf_self(
|
|
; CHECK-SAME: half noundef nofpclass(inf) [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp ueq half [[X]], 0.000000e+00
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_noinf_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 615)
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_nonan_noinf_self(half noundef nofpclass(nan inf) %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_nonan_noinf_self(
|
|
; CHECK-SAME: half noundef nofpclass(nan inf) [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp ueq half [[X]], 0.000000e+00
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_nozero_self(half noundef nofpclass(zero) %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_nozero_self(
|
|
; CHECK-SAME: half noundef nofpclass(zero) [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fcmp ueq half [[TMP1]], +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP2]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_nozero_self__daz(half noundef nofpclass(zero) %x) #2 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_nozero_self__daz(
|
|
; CHECK-SAME: half noundef nofpclass(zero) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp ueq half [[X]], 0.000000e+00
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[X]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = fcmp ueq half [[TMP2]], +inf
|
|
; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[TMP1]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP4]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_nozero_nosub_self(half noundef nofpclass(sub zero) %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_nozero_nosub_self(
|
|
; CHECK-SAME: half noundef nofpclass(zero sub) [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = fcmp ueq half [[TMP1]], +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP2]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_src_nozero_nosub_self__daz(half noundef nofpclass(sub zero) %x) #2 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_src_nozero_nosub_self__daz(
|
|
; CHECK-SAME: half noundef nofpclass(zero sub) [[X:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp ueq half [[X]], 0.000000e+00
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call half @llvm.fabs.f16(half [[X]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = fcmp ueq half [[TMP2]], +inf
|
|
; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[TMP1]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP4]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_fdiv_nnan_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_fdiv_nnan_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half 1.000000e+00
|
|
;
|
|
%div = fdiv nnan half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_fdiv_ninf_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_fdiv_ninf_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 615)
|
|
; CHECK-NEXT: [[DIV:%.*]] = select ninf i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv ninf half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret_fdiv_nnan_ninf_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_fdiv_nnan_ninf_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half 1.000000e+00
|
|
;
|
|
%div = fdiv nnan ninf half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pnorm) half @ret_nopnorm_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(pnorm) half @ret_nopnorm_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 615)
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nopinf_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 615)
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_nozero_self(half noundef %x) {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_nozero_self(
|
|
; CHECK-SAME: half noundef [[X:%.*]]) {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 615)
|
|
; CHECK-NEXT: [[DIV:%.*]] = select i1 [[TMP1]], half +qnan, half 1.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf norm sub zero) half @pinf_result_demands__self__pnorm_source(i1 %cond, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(ninf zero sub norm) half @pinf_result_demands__self__pnorm_source(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[PNORM:%.*]] = call half @returns_pnorm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[PNORM]], half [[NOT_NAN]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[SELECT]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%pnorm = call half @returns_pnorm()
|
|
%select = select i1 %cond, half %pnorm, half %not.nan
|
|
%div = fdiv half %select, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_self_unknown_or_pinf(i1 %cond, half %x) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_self_unknown_or_pinf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X_OR_PINF]], [[X_OR_PINF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %x.or.pinf
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_self_unknown_or_pinf__other_use0(i1 %cond, half %x) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_self_unknown_or_pinf__other_use0(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: call void @use(half [[X_OR_PINF]])
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X_OR_PINF]], [[X_OR_PINF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
call void @use(half %x.or.pinf)
|
|
%div = fdiv half %x.or.pinf, %x.or.pinf
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_self_unknown_or_pinf__other_use1(i1 %cond, half %x) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__fdiv_self_unknown_or_pinf__other_use1(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X_OR_PINF]], [[X_OR_PINF]]
|
|
; CHECK-NEXT: call void @use(half [[X_OR_PINF]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %x.or.pinf
|
|
call void @use(half %x.or.pinf)
|
|
ret half %div
|
|
}
|
|
|
|
; -> qnan
|
|
define nofpclass(nzero) half @ret_src_must_be_nan_self(half noundef nofpclass(inf norm sub zero) %x) {
|
|
; CHECK-LABEL: define nofpclass(nzero) half @ret_src_must_be_nan_self(
|
|
; CHECK-SAME: half noundef nofpclass(inf zero sub norm) [[X:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %x
|
|
ret half %div
|
|
}
|
|
|
|
; -> qnan
|
|
define nofpclass(pinf pnorm psub pzero) half @ret_only_negative_results_or_nan_fabs_xy(half %x, half nofpclass(ninf nnorm nsub nzero) %y.pos.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) half @ret_only_negative_results_or_nan_fabs_xy(
|
|
; CHECK-SAME: half [[X:%.*]], half nofpclass(ninf nzero nsub nnorm) [[Y_POS_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%x.fabs = call half @llvm.fabs.f32(half %x)
|
|
%div = fdiv half %x.fabs, %y.pos.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> poison
|
|
define nofpclass(pinf pnorm psub pzero nan) half @ret_only_negative_results_fabs_xy(half %x,half nofpclass(ninf nnorm nsub nzero) %y.pos.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) half @ret_only_negative_results_fabs_xy(
|
|
; CHECK-SAME: half [[X:%.*]], half nofpclass(ninf nzero nsub nnorm) [[Y_POS_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%x.fabs = call half @llvm.fabs.f32(half %x)
|
|
%div = fdiv half %x.fabs, %y.pos.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_only_zero_results__rhs_non0_const(half %x) {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_only_zero_results__rhs_non0_const(
|
|
; CHECK-SAME: half [[X:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fmul half [[X]], 5.000000e-01
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, 2.0
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_nonsub(half nofpclass(zero sub) %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_nonsub(
|
|
; CHECK-SAME: half nofpclass(zero sub) [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_nonsub_daz(half nofpclass(zero sub) %x, half %y) #0 {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_nonsub_daz(
|
|
; CHECK-SAME: half nofpclass(zero sub) [[X:%.*]], half [[Y:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_nonsub_dynamic(half nofpclass(zero sub) %x, half %y) #1 {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_nonsub_dynamic(
|
|
; CHECK-SAME: half nofpclass(zero sub) [[X:%.*]], half [[Y:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero(half nofpclass(zero) %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero(
|
|
; CHECK-SAME: half nofpclass(zero) [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_daz(half nofpclass(zero) %x, half %y) #1 {
|
|
; CHECK-LABEL: define nofpclass(zero) half @ret_only_zero_results__lhs_known_nonzero_daz(
|
|
; CHECK-SAME: half nofpclass(zero) [[X:%.*]], half [[Y:%.*]]) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_only_inf_results__lhs_known_non_inf(i1 %cond, half %x, half nofpclass(inf) %y) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_only_inf_results__lhs_known_non_inf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X_OR_PINF]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_no_inf_results__rhs_known_non_inf(i1 %cond, half %x, half nofpclass(inf) %y) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_no_inf_results__rhs_known_non_inf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[Y_OR_PINF:%.*]] = select i1 [[COND]], half [[Y]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y_OR_PINF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%y.or.pinf = select i1 %cond, half %y, half 0x7FF0000000000000
|
|
%div = fdiv half %x, %y.or.pinf
|
|
ret half %div
|
|
}
|
|
|
|
; Do nothing, this could still be -inf
|
|
define nofpclass(ninf nan) half @ret_no_ninf_or_nan_results__lhs_known_non_inf(i1 %cond, half %x, half nofpclass(inf) %y) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf) half @ret_no_ninf_or_nan_results__lhs_known_non_inf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[X_OR_PINF]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %y
|
|
ret half %div
|
|
}
|
|
|
|
; Do nothing, this could still be -inf
|
|
define nofpclass(pinf nan) half @ret_no_pinf_or_nan_results__lhs_known_non_inf(i1 %cond, half %x, half nofpclass(inf) %y) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf) half @ret_no_pinf_or_nan_results__lhs_known_non_inf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[X_OR_PINF:%.*]] = select i1 [[COND]], half [[X]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[X_OR_PINF]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %y
|
|
ret half %div
|
|
}
|
|
|
|
; fold to fdiv
|
|
define nofpclass(inf nan) half @ret_no_inf_or_nan_results__lhs_known_non_inf(i1 %cond, half %x, half nofpclass(inf) %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_no_inf_or_nan_results__lhs_known_non_inf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%x.or.pinf = select i1 %cond, half %x, half 0x7FF0000000000000
|
|
%div = fdiv half %x.or.pinf, %y
|
|
ret half %div
|
|
}
|
|
|
|
; fold to fdiv
|
|
define nofpclass(inf nan) half @ret_no_inf_or_nan_results__rhs_known_non_inf(i1 %cond, half %x, half nofpclass(inf) %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_no_inf_or_nan_results__rhs_known_non_inf(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[X:%.*]], half nofpclass(inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[Y_OR_PINF:%.*]] = select i1 [[COND]], half [[Y]], half +inf
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[X]], [[Y_OR_PINF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%y.or.pinf = select i1 %cond, half %y, half 0x7FF0000000000000
|
|
%div = fdiv half %x, %y.or.pinf
|
|
ret half %div
|
|
}
|
|
|
|
; -> nan
|
|
define nofpclass(ninf nnorm nsub nzero) half @ret_only_positive_results_or_nan_known_negative_fdiv(half nofpclass(ninf nnorm nsub nzero) %only.positive.or.nan, half nofpclass(pinf pnorm psub pzero) %only.negative.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) half @ret_only_positive_results_or_nan_known_negative_fdiv(
|
|
; CHECK-SAME: half nofpclass(ninf nzero nsub nnorm) [[ONLY_POSITIVE_OR_NAN:%.*]], half nofpclass(pinf pzero psub pnorm) [[ONLY_NEGATIVE_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %only.negative.or.nan, %only.positive.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> poison
|
|
define nofpclass(ninf nnorm nsub nzero nan) half @ret_only_positive_results_known_negative_fdiv(half nofpclass(ninf nnorm nsub nzero) %only.positive.or.nan, half nofpclass(pinf pnorm psub pzero) %only.negative.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) half @ret_only_positive_results_known_negative_fdiv(
|
|
; CHECK-SAME: half nofpclass(ninf nzero nsub nnorm) [[ONLY_POSITIVE_OR_NAN:%.*]], half nofpclass(pinf pzero psub pnorm) [[ONLY_NEGATIVE_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %only.negative.or.nan, %only.positive.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; missing nnan rhs
|
|
define nofpclass(nsub) half @ret__known_zero_or_nan__fdiv__not_inf(half nofpclass(inf sub norm) %zero.or.nan, half nofpclass(inf) %not.inf) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_zero_or_nan__fdiv__not_inf(
|
|
; CHECK-SAME: half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], half nofpclass(inf) [[NOT_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NAN]], [[NOT_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.nan, %not.inf
|
|
ret half %div
|
|
}
|
|
|
|
; Needs to be pzero to replace with copysign
|
|
define nofpclass(nsub) half @ret__known_zero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm) %zero.or.nan, half nofpclass(inf nan) %not.inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_zero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NAN]], [[NOT_INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.nan, %not.inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; Needs to be pzero to replace with copysign
|
|
define nofpclass(nsub) half @ret__not_inf_or_nan__fdiv__known_zero_or_nan(half nofpclass(inf nan) %not.inf.or.nan, half nofpclass(inf sub norm) %zero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__not_inf_or_nan__fdiv__known_zero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]], half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_INF_OR_NAN]], [[ZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.inf.or.nan, %zero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign
|
|
define nofpclass(nsub) half @ret__known_pzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(inf nan) %not.inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_pzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[PZERO_OR_NAN]], [[NOT_INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %not.inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; missing nnan lhs
|
|
define nofpclass(nsub) half @ret__not_inf__fdiv__known_pzero_or_nan(half nofpclass(inf) %not.inf, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__not_inf__fdiv__known_pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf) [[NOT_INF:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_INF]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.inf, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign
|
|
define nofpclass(nsub) half @ret__not_inf_or_nan__fdiv__known_pzero_or_nan(half nofpclass(inf nan) %not.inf.or.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__not_inf_or_nan__fdiv__known_pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_INF_OR_NAN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.inf.or.nan, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; Missing no-nan on RHS to turn into fneg
|
|
define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_non0_or_nan(half nofpclass(zero sub norm) %inf.or.nan, half nofpclass(zero pinf pnorm psub) %negative.non0.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_non0_or_nan(
|
|
; CHECK-SAME: half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]], half nofpclass(pinf zero psub pnorm) [[NEGATIVE_NON0_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[INF_OR_NAN]], [[NEGATIVE_NON0_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %inf.or.nan, %negative.non0.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; Missing no-nan on LHS to turn into fneg
|
|
define nofpclass(nsub) half @ret__known_negative_non0_or_nan__fdiv__known_inf_or_nan(half nofpclass(zero pinf pnorm psub) %negative.non0.or.nan, half nofpclass(zero sub norm) %inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_negative_non0_or_nan__fdiv__known_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(pinf zero psub pnorm) [[NEGATIVE_NON0_OR_NAN:%.*]], half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NEGATIVE_NON0_OR_NAN]], [[INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %negative.non0.or.nan, %inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> fneg
|
|
define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_non0(half nofpclass(zero sub norm) %inf.or.nan, half nofpclass(nan zero pinf pnorm psub) %negative.non0) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_non0(
|
|
; CHECK-SAME: half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]], half nofpclass(nan pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[INF_OR_NAN]], [[NEGATIVE_NON0]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %inf.or.nan, %negative.non0
|
|
ret half %div
|
|
}
|
|
|
|
; -> fneg
|
|
define nofpclass(nsub) half @ret__known_negative_non0__fdiv__known_inf_or_nan(half nofpclass(nan zero pinf pnorm psub) %negative.non0, half nofpclass(zero sub norm) %inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_negative_non0__fdiv__known_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]], half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NEGATIVE_NON0]], [[INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %negative.non0, %inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; Cannot fold to fneg due to possible nsub input
|
|
define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_non0__daz(half nofpclass(zero sub norm) %inf.or.nan, half nofpclass(nan zero pinf pnorm psub) %negative.non0) #1 {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_non0__daz(
|
|
; CHECK-SAME: half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]], half nofpclass(nan pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]]) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[INF_OR_NAN]], [[NEGATIVE_NON0]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %inf.or.nan, %negative.non0
|
|
ret half %div
|
|
}
|
|
|
|
; Cannot fold to fneg due to possible nsub input
|
|
define nofpclass(nsub) half @ret__known_negative_non0__fdiv__known_inf_or_nan__daz(half nofpclass(nan zero pinf pnorm psub) %negative.non0, half nofpclass(zero sub norm) %inf.or.nan) #1 {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_negative_non0__fdiv__known_inf_or_nan__daz(
|
|
; CHECK-SAME: half nofpclass(nan pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]], half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NEGATIVE_NON0]], [[INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %negative.non0, %inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> fneg
|
|
define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_nonlogical0__daz(half nofpclass(zero sub norm) %inf.or.nan, half nofpclass(nan zero pinf pnorm sub) %negative.nonlogical0) #1 {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_inf_or_nan__fdiv__known_negative_nonlogical0__daz(
|
|
; CHECK-SAME: half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]], half nofpclass(nan pinf zero sub pnorm) [[NEGATIVE_NONLOGICAL0:%.*]]) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[INF_OR_NAN]], [[NEGATIVE_NONLOGICAL0]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %inf.or.nan, %negative.nonlogical0
|
|
ret half %div
|
|
}
|
|
|
|
; -> fneg
|
|
define nofpclass(nsub) half @ret__known_negative_nonlogical0__fdiv__known_inf_or_nan__daz(half nofpclass(nan zero pinf pnorm sub) %negative.nonlogical0, half nofpclass(zero sub norm) %inf.or.nan) #1 {
|
|
; CHECK-LABEL: define nofpclass(nsub) half @ret__known_negative_nonlogical0__fdiv__known_inf_or_nan__daz(
|
|
; CHECK-SAME: half nofpclass(nan pinf zero sub pnorm) [[NEGATIVE_NONLOGICAL0:%.*]], half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NEGATIVE_NONLOGICAL0]], [[INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %negative.nonlogical0, %inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; Should be able to fold to copysign, helped by the lack of nan results.
|
|
define nofpclass(nan) half @ret_no_nan_result__known_pzero__fdiv__not_inf(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(inf nan) %not.inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_result__known_pzero__fdiv__not_inf(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half 0.000000e+00, half [[NOT_INF_OR_NAN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %not.inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan_result__known_pzero__fdiv__not_inf__insert_point(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(inf nan) %not.inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_result__known_pzero__fdiv__not_inf__insert_point(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half 0.000000e+00, half [[NOT_INF_OR_NAN]])
|
|
; CHECK-NEXT: [[BARRIER:%.*]] = call half @llvm.arithmetic.fence.f16(half [[DIV]])
|
|
; CHECK-NEXT: ret half [[BARRIER]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %not.inf.or.nan
|
|
%barrier = call half @llvm.arithmetic.fence.f16(half %div)
|
|
ret half %barrier
|
|
}
|
|
|
|
; Should be able to fold to copysign, helped by the lack of nan results.
|
|
define nofpclass(nan) half @ret_no_nan_result__not_inf_or_nan__fdiv__known_pzero_or_nan(half nofpclass(inf) %not.inf.or.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_result__not_inf_or_nan__fdiv__known_pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf) [[NOT_INF_OR_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half +inf, half [[NOT_INF_OR_NAN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.inf.or.nan, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan_result__not_inf_or_nan__fdiv__known_pzero_or_nan__insert_pt(half nofpclass(inf) %not.inf.or.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_result__not_inf_or_nan__fdiv__known_pzero_or_nan__insert_pt(
|
|
; CHECK-SAME: half nofpclass(inf) [[NOT_INF_OR_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half +inf, half [[NOT_INF_OR_NAN]])
|
|
; CHECK-NEXT: [[BARRIER:%.*]] = call half @llvm.arithmetic.fence.f16(half [[DIV]])
|
|
; CHECK-NEXT: ret half [[BARRIER]]
|
|
;
|
|
%div = fdiv half %not.inf.or.nan, %pzero.or.nan
|
|
%barrier = call half @llvm.arithmetic.fence.f16(half %div)
|
|
ret half %barrier
|
|
}
|
|
|
|
; -> fneg, with help of no nan results
|
|
define nofpclass(nan) half @ret_no_nan_result__known_inf_or_nan__fdiv__known_negative_non0(half nofpclass(zero sub norm) %inf.or.nan, half nofpclass(zero pinf pnorm psub) %negative.non0) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_result__known_inf_or_nan__fdiv__known_negative_non0(
|
|
; CHECK-SAME: half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]], half nofpclass(pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[INF_OR_NAN]], [[NEGATIVE_NON0]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %inf.or.nan, %negative.non0
|
|
ret half %div
|
|
}
|
|
|
|
; -> fneg, with help of no nan results
|
|
define nofpclass(nan) half @ret_no_nan_result__known_negative_non0__fdiv__known_inf_or_nan(half nofpclass(zero pinf pnorm psub) %negative.non0, half nofpclass(zero sub norm) %inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_result__known_negative_non0__fdiv__known_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(pinf zero psub pnorm) [[NEGATIVE_NON0:%.*]], half nofpclass(zero sub norm) [[INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[NEGATIVE_NON0]], [[INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %negative.non0, %inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, take no-infs-no-nans from invalid return
|
|
define nofpclass(inf nan) half @ret_noinf_nonan__known_pzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_noinf_nonan__known_pzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half 0.000000e+00, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %unknown
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, take no-infs-no-nans from invalid return, commuted
|
|
define nofpclass(inf nan) half @ret_noinf_nonan__not_inf_or_nan__fdiv__known_pzero_or_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_noinf_nonan__not_inf_or_nan__fdiv__known_pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half 0.000000e+00, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %unknown
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, take no-infs from invalid return
|
|
define nofpclass(inf) half @ret_noinf__known_zero_or_nan__fdiv__not_nan(half nofpclass(nan sub norm nzero) %pzero.or.inf, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__known_zero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[PZERO_OR_INF]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.inf, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, take no-infs from invalid return, commuted
|
|
define nofpclass(inf) half @ret_noinf__noinf_or_nan__fdiv__known_pzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(nan sub norm nzero) %pzero.or.inf) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__noinf_or_nan__fdiv__known_pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN]], [[PZERO_OR_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %pzero.or.inf
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, take no-nans from invalid return
|
|
define nofpclass(nan) half @ret_nonan__known_zero_or_nan__fdiv__not_nan(half nofpclass(nan sub norm nzero) %pzero.or.inf, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__known_zero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[PZERO_OR_INF]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.inf, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, take no-nans from invalid return, commuted
|
|
define nofpclass(nan) half @ret_nonan__noinf_or_nan__fdiv__known_pzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(nan sub norm nzero) %pzero.or.inf) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__noinf_or_nan__fdiv__known_pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[NOT_NAN]], [[PZERO_OR_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %pzero.or.inf
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nopinf__known_pzero_or_nan__fdiv__not_nan(half nofpclass(nan sub norm nzero) %pzero.or.inf, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf__known_pzero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[PZERO_OR_INF]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.inf, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nopinf__not_nan__fdiv__known_zero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(nan sub norm nzero) %pzero.or.inf) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf__not_nan__fdiv__known_zero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN]], [[PZERO_OR_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %pzero.or.inf
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf__known_pzero_or_nan__fdiv__not_nan(half nofpclass(nan sub norm nzero) %pzero.or.inf, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf__known_pzero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[PZERO_OR_INF]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.inf, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf__not_nan__fdiv__known_zero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(nan sub norm nzero) %pzero.or.inf) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf__not_nan__fdiv__known_zero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(nan nzero sub norm) [[PZERO_OR_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN]], [[PZERO_OR_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %pzero.or.inf
|
|
ret half %div
|
|
}
|
|
|
|
; no pinf result implies no infs if the signs of each operand are the same, must be +0
|
|
define nofpclass(pinf) half @ret_nopinf__known_zero_or_pos_nan__fdiv__not_nan_pos(half nofpclass(nan ninf sub norm) %zero.or.not.neg, half nofpclass(nan ninf nzero nsub nnorm) %not.nan.not.neg) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf__known_zero_or_pos_nan__fdiv__not_nan_pos(
|
|
; CHECK-SAME: half nofpclass(nan ninf sub norm) [[ZERO_OR_NOT_NEG:%.*]], half nofpclass(nan ninf nzero nsub nnorm) [[NOT_NAN_NOT_NEG:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NOT_NEG]], [[NOT_NAN_NOT_NEG]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.not.neg, %not.nan.not.neg
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nopinf__not_nan_pos__fdiv__known_zero_or_pos_nan(half nofpclass(nan ninf nsub nnorm) %not.nan.not.neg, half nofpclass(nan ninf nzero sub norm) %zero.or.not.neg) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf__not_nan_pos__fdiv__known_zero_or_pos_nan(
|
|
; CHECK-SAME: half nofpclass(nan ninf nsub nnorm) [[NOT_NAN_NOT_NEG:%.*]], half nofpclass(nan ninf nzero sub norm) [[ZERO_OR_NOT_NEG:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN_NOT_NEG]], [[ZERO_OR_NOT_NEG]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan.not.neg, %zero.or.not.neg
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nopinf__known_zero_or_neg_nan__fdiv__not_nan_neg(half nofpclass(nan pinf sub norm) %zero.or.not.pos, half nofpclass(nan pinf pzero psub pnorm) %not.nan.not.pos) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf__known_zero_or_neg_nan__fdiv__not_nan_neg(
|
|
; CHECK-SAME: half nofpclass(nan pinf sub norm) [[ZERO_OR_NOT_POS:%.*]], half nofpclass(nan pinf pzero psub pnorm) [[NOT_NAN_NOT_POS:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NOT_POS]], [[NOT_NAN_NOT_POS]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.not.pos, %not.nan.not.pos
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf) half @ret_nopinf__not_nan_neg__fdiv__known_zero_or_neg_nan(half nofpclass(nan pinf pzero psub pnorm) %not.nan.not.pos, half nofpclass(nan pinf sub norm) %zero.or.not.pos) {
|
|
; CHECK-LABEL: define nofpclass(pinf) half @ret_nopinf__not_nan_neg__fdiv__known_zero_or_neg_nan(
|
|
; CHECK-SAME: half nofpclass(nan pinf pzero psub pnorm) [[NOT_NAN_NOT_POS:%.*]], half nofpclass(nan pinf sub norm) [[ZERO_OR_NOT_POS:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN_NOT_POS]], [[ZERO_OR_NOT_POS]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan.not.pos, %zero.or.not.pos
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf__known_zero_or_pos_nan__fdiv__not_nan_pos(half nofpclass(nan ninf sub norm) %zero.or.not.neg, half nofpclass(nan ninf nzero nsub nnorm) %not.nan.not.neg) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf__known_zero_or_pos_nan__fdiv__not_nan_pos(
|
|
; CHECK-SAME: half nofpclass(nan ninf sub norm) [[ZERO_OR_NOT_NEG:%.*]], half nofpclass(nan ninf nzero nsub nnorm) [[NOT_NAN_NOT_NEG:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NOT_NEG]], [[NOT_NAN_NOT_NEG]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.not.neg, %not.nan.not.neg
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf__not_nan_pos__fdiv__known_zero_or_pos_nan(half nofpclass(nan ninf nzero nsub nnorm) %not.nan.not.neg, half nofpclass(nan ninf sub norm) %zero.or.not.neg) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf__not_nan_pos__fdiv__known_zero_or_pos_nan(
|
|
; CHECK-SAME: half nofpclass(nan ninf nzero nsub nnorm) [[NOT_NAN_NOT_NEG:%.*]], half nofpclass(nan ninf sub norm) [[ZERO_OR_NOT_NEG:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN_NOT_NEG]], [[ZERO_OR_NOT_NEG]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan.not.neg, %zero.or.not.neg
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf__known_zero_or_pos_nan__fdiv__not_nan_neg(half nofpclass(nan ninf sub norm) %zero.or.not.neg, half nofpclass(nan pinf pzero psub pnorm) %not.nan.not.pos) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf__known_zero_or_pos_nan__fdiv__not_nan_neg(
|
|
; CHECK-SAME: half nofpclass(nan ninf sub norm) [[ZERO_OR_NOT_NEG:%.*]], half nofpclass(nan pinf pzero psub pnorm) [[NOT_NAN_NOT_POS:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NOT_NEG]], [[NOT_NAN_NOT_POS]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.not.neg, %not.nan.not.pos
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_noninf__not_nan_neg__fdiv__known_zero_or_pos_nan(half nofpclass(nan pinf pzero psub pnorm) %not.nan.not.pos, half nofpclass(nan ninf sub norm) %zero.or.not.neg) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_noninf__not_nan_neg__fdiv__known_zero_or_pos_nan(
|
|
; CHECK-SAME: half nofpclass(nan pinf pzero psub pnorm) [[NOT_NAN_NOT_POS:%.*]], half nofpclass(nan ninf sub norm) [[ZERO_OR_NOT_NEG:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN_NOT_POS]], [[ZERO_OR_NOT_NEG]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan.not.pos, %zero.or.not.neg
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @ret_only_nan_results_fdiv(half %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan_results_fdiv(
|
|
; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero snan) half @ret_only_qnan_results_fdiv(half %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(snan inf zero sub norm) half @ret_only_qnan_results_fdiv(
|
|
; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero qnan) half @ret_only_snan_results_fdiv(half %x, half %y) {
|
|
; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) half @ret_only_snan_results_fdiv(
|
|
; CHECK-SAME: half [[X:%.*]], half [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %x, %y
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf) half @ret_no_nan_no_inf__fdiv_nonan_noinf__nonan_noinf(half nofpclass(inf nan) %x, half nofpclass(inf nan) %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_no_nan_no_inf__fdiv_nonan_noinf__nonan_noinf(
|
|
; CHECK-SAME: half nofpclass(nan inf) [[X:%.*]], half nofpclass(nan inf) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan ninf half [[X]], [[Y]]
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%fdiv = fdiv half %x, %y
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan inf) half @ret_no_nan_no_inf__fdiv_no_nan__normal_constant(half nofpclass(inf nan) %x) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_no_nan_no_inf__fdiv_no_nan__normal_constant(
|
|
; CHECK-SAME: half nofpclass(nan inf) [[X:%.*]]) {
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fmul nnan ninf half [[X]], 2.500000e-01
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%fdiv = fdiv half %x, 4.0
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan__fdiv_zero__unknown(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__fdiv_zero__unknown(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan half [[ZERO]], [[UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%fdiv = fdiv half %zero, %unknown
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan__fdiv_unknown__zero(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__fdiv_unknown__zero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan half [[UNKNOWN]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%fdiv = fdiv half %unknown, %zero
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan__fdiv_pzero__unknown(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__fdiv_pzero__unknown(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[PZERO:%.*]] = call half @returns_pzero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = call half @llvm.copysign.f16(half 0.000000e+00, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%pzero = call half @returns_pzero()
|
|
%fdiv = fdiv half %pzero, %unknown
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan__fdiv_unknown__pzero(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__fdiv_unknown__pzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[PZERO:%.*]] = call half @returns_pzero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = call half @llvm.copysign.f16(half +inf, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%pzero = call half @returns_pzero()
|
|
%fdiv = fdiv half %unknown, %pzero
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan__fdiv_nzero__unknown(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__fdiv_nzero__unknown(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[NZERO:%.*]] = call half @returns_nzero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan half -0.000000e+00, [[UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%nzero = call half @returns_nzero()
|
|
%fdiv = fdiv half %nzero, %unknown
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_no_nan__fdiv_unknown__nzero(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan__fdiv_unknown__nzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[NZERO:%.*]] = call half @returns_nzero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan half [[UNKNOWN]], -0.000000e+00
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%nzero = call half @returns_nzero()
|
|
%fdiv = fdiv half %unknown, %nzero
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_ninf__fdiv_nnan_zero__unknown(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_ninf__fdiv_nnan_zero__unknown(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[FDIV:%.*]] = fdiv nnan half [[ZERO]], [[UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[FDIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%fdiv = fdiv nnan half %zero, %unknown
|
|
ret half %fdiv
|
|
}
|
|
|
|
define nofpclass(ninf) half @ret_ninf__fdiv_nnan_unknown__zero(half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(ninf) half @ret_ninf__fdiv_nnan_unknown__zero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: ret half +inf
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%fdiv = fdiv nnan half %unknown, %zero
|
|
ret half %fdiv
|
|
}
|
|
|
|
; -> copysign + fneg
|
|
define nofpclass(snan) half @known__nzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm pzero) %nzero.or.nan, half nofpclass(inf nan) %not.inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__nzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[NZERO_OR_NAN]], [[NOT_INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %nzero.or.nan, %not.inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg
|
|
define nofpclass(snan) half @known__not_inf_or_nan__fdiv__nzero_or_nan(half nofpclass(inf nan) %not.inf.or.nan, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__not_inf_or_nan__fdiv__nzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[NOT_INF_OR_NAN]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %not.inf.or.nan, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign + fneg
|
|
define nofpclass(snan) half @known__nzero_or_nan__fdiv__not_inf(half nofpclass(inf sub norm pzero) %nzero.or.nan, half nofpclass(inf) %not.inf) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__nzero_or_nan__fdiv__not_inf(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half nofpclass(inf) [[NOT_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NZERO_OR_NAN]], [[NOT_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %nzero.or.nan, %not.inf
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign + fneg
|
|
define nofpclass(snan) half @known__not_inf__fdiv__nzero_or_nan(half nofpclass(inf) %not.inf, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__not_inf__fdiv__nzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf) [[NOT_INF:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_INF]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.inf, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign + fneg
|
|
define nofpclass(snan) half @known__nzero_or_nan__fdiv__not_nan(half nofpclass(inf sub norm pzero) %nzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__nzero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[NZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %nzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign + fneg
|
|
define nofpclass(snan) half @known__not_nan__fdiv__nzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__not_nan__fdiv__nzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[NOT_NAN]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %not.nan, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no infinity from return
|
|
define nofpclass(inf) half @ret_noinf__nzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm pzero) %nzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__nzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %nzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no infinity from return
|
|
define nofpclass(inf) half @ret_noinf__not_inf_or_nan__fdiv__nzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__not_inf_or_nan__fdiv__nzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no nans from return
|
|
define nofpclass(nan) half @ret_nonan__nzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm pzero) %nzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__nzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half -0.000000e+00, [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %nzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no nans from return
|
|
define nofpclass(nan) half @ret_nonan__not_inf_or_nan__fdiv__nzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__not_inf_or_nan__fdiv__nzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[NOT_NAN]], -0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no infinity from flag
|
|
define nofpclass(snan) half @ret__nzero_or_nan__fdiv_ninf__not_inf_or_nan(half nofpclass(inf sub norm pzero) %nzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__nzero_or_nan__fdiv_ninf__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf half [[NZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv ninf half %nzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no infinity from flag
|
|
define nofpclass(snan) half @ret_not_inf_or_nan__fdiv_ninf__nzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_not_inf_or_nan__fdiv_ninf__nzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf half [[NOT_NAN]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv ninf half %not.nan, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no nan from flag
|
|
define nofpclass(snan) half @ret__nzero_or_nan__fdiv_nnan__not_inf_or_nan(half nofpclass(inf sub norm pzero) %nzero.or.nan, half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__nzero_or_nan__fdiv_nnan__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]], half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half -0.000000e+00, [[UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nnan half %nzero.or.nan, %unknown
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign + fneg, no nan from flag
|
|
define nofpclass(snan) half @not_inf_or_nan__fdiv_nnan__nzero_or_nan(half %unknown, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @not_inf_or_nan__fdiv_nnan__nzero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN]], -0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nnan half %unknown, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign
|
|
define nofpclass(snan) half @known__pzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(inf nan) %not.inf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__pzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[PZERO_OR_NAN]], [[NOT_INF_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %pzero.or.nan, %not.inf.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign
|
|
define nofpclass(snan) half @known__not_inf_or_nan__fdiv__pzero_or_nan(half nofpclass(inf nan) %not.inf.or.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__not_inf_or_nan__fdiv__pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan inf) [[NOT_INF_OR_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[NOT_INF_OR_NAN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %not.inf.or.nan, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign
|
|
define nofpclass(snan) half @known__pzero_or_nan__fdiv__not_inf(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(inf) %not.inf) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__pzero_or_nan__fdiv__not_inf(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(inf) [[NOT_INF:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[PZERO_OR_NAN]], [[NOT_INF]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %not.inf
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign
|
|
define nofpclass(snan) half @known__not_inf__fdiv__pzero_or_nan(half nofpclass(inf) %not.inf, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__not_inf__fdiv__pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf) [[NOT_INF:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_INF]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.inf, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign
|
|
define nofpclass(snan) half @known__pzero_or_nan__fdiv__not_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__pzero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[PZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %pzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; cannot replace with copysign
|
|
define nofpclass(snan) half @known__not_nan__fdiv__pzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @known__not_nan__fdiv__pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv contract half [[NOT_NAN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract half %not.nan, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, no infinity from return
|
|
define nofpclass(inf) half @ret_noinf__pzero_or_nan__fdiv__not_inf_or_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__pzero_or_nan__fdiv__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[PZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %pzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, no infinity from return
|
|
define nofpclass(inf) half @ret_noinf__not_inf_or_nan__fdiv__pzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__not_inf_or_nan__fdiv__pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[NOT_NAN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %not.nan, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, no infinity from flag
|
|
define nofpclass(snan) half @ret__pzero_or_nan__fdiv_ninf__not_inf_or_nan(half nofpclass(inf sub norm nzero) %pzero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__pzero_or_nan__fdiv_ninf__not_inf_or_nan(
|
|
; CHECK-SAME: half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf half [[PZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv ninf half %pzero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
; -> copysign, no infinity from flag
|
|
define nofpclass(snan) half @ret_not_inf_or_nan__fdiv_ninf__pzero_or_nan(half nofpclass(nan) %not.nan, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret_not_inf_or_nan__fdiv_ninf__pzero_or_nan(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf half [[NOT_NAN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv ninf half %not.nan, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm sub) half @zero_result_demands_sub_source_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @zero_result_demands_sub_source_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[SUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub = call half @returns_sub()
|
|
%select = select i1 %cond, half %sub, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm sub) half @zero_result_demands_sub_source_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @zero_result_demands_sub_source_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[SUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub = call half @returns_sub()
|
|
%select = select i1 %cond, half %sub, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm sub) half @zero_result_demands_norm_source_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @zero_result_demands_norm_source_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NORM:%.*]] = call half @returns_norm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%norm = call half @returns_norm()
|
|
%select = select i1 %cond, half %norm, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm sub) half @zero_result_demands_norm_source_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @zero_result_demands_norm_source_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NORM:%.*]] = call half @returns_norm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%norm = call half @returns_norm()
|
|
%select = select i1 %cond, half %norm, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm zero) half @sub_result_demands_norm_source_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero norm) half @sub_result_demands_norm_source_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NORM:%.*]] = call half @returns_norm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%norm = call half @returns_norm()
|
|
%select = select i1 %cond, half %norm, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm zero) half @sub_result_demands_norm_source_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero norm) half @sub_result_demands_norm_source_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NORM:%.*]] = call half @returns_norm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%norm = call half @returns_norm()
|
|
%select = select i1 %cond, half %norm, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf zero sub) half @nan_result_demands_zero_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub) half @nan_result_demands_zero_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[ZERO]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%select = select i1 %cond, half %zero, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf zero sub) half @nan_result_demands_zero_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub) half @nan_result_demands_zero_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[ZERO]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%select = select i1 %cond, half %zero, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf zero sub) half @nan_result_demands_inf_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub) half @nan_result_demands_inf_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[INF:%.*]] = call half @returns_inf()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[INF]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%inf = call half @returns_inf()
|
|
%select = select i1 %cond, half %inf, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf zero sub) half @nan_result_demands_inf_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub) half @nan_result_demands_inf_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[INF:%.*]] = call half @returns_inf()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[INF]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%inf = call half @returns_inf()
|
|
%select = select i1 %cond, half %inf, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(ninf nan zero sub) half @pinf_result_demands_zero_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf zero sub) half @pinf_result_demands_zero_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[ZERO]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%select = select i1 %cond, half %zero, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(pinf nan zero sub) half @ninf_result_demands_zero_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf zero sub) half @ninf_result_demands_zero_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[ZERO]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%select = select i1 %cond, half %zero, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan zero sub) half @inf_result_demands_zero_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan zero sub) half @inf_result_demands_zero_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ZERO:%.*]] = call half @returns_zero()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[ZERO]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%zero = call half @returns_zero()
|
|
%select = select i1 %cond, half %zero, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_pnorm_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_pnorm_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[PNORM:%.*]] = call half @returns_pnorm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[PNORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%pnorm = call half @returns_pnorm()
|
|
%select = select i1 %cond, half %pnorm, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_nnorm_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_nnorm_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NNORM:%.*]] = call half @returns_nnorm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NNORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%nnorm = call half @returns_nnorm()
|
|
%select = select i1 %cond, half %nnorm, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_psub_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_psub_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[PSUB:%.*]] = call half @returns_psub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[PSUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%psub = call half @returns_psub()
|
|
%select = select i1 %cond, half %psub, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_nsub_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_nsub_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NSUB:%.*]] = call half @returns_nsub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NSUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%nsub = call half @returns_nsub()
|
|
%select = select i1 %cond, half %nsub, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_pnorm_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_pnorm_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[PNORM:%.*]] = call half @returns_pnorm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[PNORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%pnorm = call half @returns_pnorm()
|
|
%select = select i1 %cond, half %pnorm, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_nnorm_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_nnorm_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NNORM:%.*]] = call half @returns_nnorm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NNORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%nnorm = call half @returns_nnorm()
|
|
%select = select i1 %cond, half %nnorm, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_psub_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_psub_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[PSUB:%.*]] = call half @returns_psub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[PSUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%psub = call half @returns_psub()
|
|
%select = select i1 %cond, half %psub, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero nnorm) half @pnorm_result_demands_nsub_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) half @pnorm_result_demands_nsub_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[NSUB:%.*]] = call half @returns_nsub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[NSUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%nsub = call half @returns_nsub()
|
|
%select = select i1 %cond, half %nsub, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan zero pnorm) half @nnorm_result_demands_pnorm_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero pnorm) half @nnorm_result_demands_pnorm_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[PNORM:%.*]] = call half @returns_pnorm()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[PNORM]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%pnorm = call half @returns_pnorm()
|
|
%select = select i1 %cond, half %pnorm, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
; Remove selects
|
|
define nofpclass(inf zero norm) half @nan_result_no_demand_subnorm_sources_if_ieee(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero norm) half @nan_result_no_demand_subnorm_sources_if_ieee(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB0:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SUB1:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT0:%.*]] = select i1 [[COND]], half [[SUB0]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[COND]], half [[SUB1]], half [[UNKNOWN1]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[SELECT0]], [[SELECT1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub0 = call half @returns_sub()
|
|
%sub1 = call half @returns_sub()
|
|
%select0 = select i1 %cond, half %sub0, half %unknown0
|
|
%select1 = select i1 %cond, half %sub1, half %unknown1
|
|
%div = fdiv half %select0, %select1
|
|
ret half %div
|
|
}
|
|
|
|
; Keep selects
|
|
define nofpclass(inf zero norm) half @nan_result_demands_subnorm_sources_if_daz(i1 %cond, half %unknown0, half %unknown1) #2 {
|
|
; CHECK-LABEL: define nofpclass(inf zero norm) half @nan_result_demands_subnorm_sources_if_daz(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[SUB0:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SUB1:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT0:%.*]] = select i1 [[COND]], half [[SUB0]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[COND]], half [[SUB1]], half [[UNKNOWN1]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[SELECT0]], [[SELECT1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub0 = call half @returns_sub()
|
|
%sub1 = call half @returns_sub()
|
|
%select0 = select i1 %cond, half %sub0, half %unknown0
|
|
%select1 = select i1 %cond, half %sub1, half %unknown1
|
|
%div = fdiv half %select0, %select1
|
|
ret half %div
|
|
}
|
|
|
|
; Keep selects
|
|
define nofpclass(inf zero norm) half @nan_result_demands_subnorm_sources_if_dynamic_input(i1 %cond, half %unknown0, half %unknown1) #3 {
|
|
; CHECK-LABEL: define nofpclass(inf zero norm) half @nan_result_demands_subnorm_sources_if_dynamic_input(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR3:[0-9]+]] {
|
|
; CHECK-NEXT: [[SUB0:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SUB1:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT0:%.*]] = select i1 [[COND]], half [[SUB0]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[COND]], half [[SUB1]], half [[UNKNOWN1]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[SELECT0]], [[SELECT1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub0 = call half @returns_sub()
|
|
%sub1 = call half @returns_sub()
|
|
%select0 = select i1 %cond, half %sub0, half %unknown0
|
|
%select1 = select i1 %cond, half %sub1, half %unknown1
|
|
%div = fdiv half %select0, %select1
|
|
ret half %div
|
|
}
|
|
|
|
; Keep select
|
|
define nofpclass(nan inf norm) half @zero_result_demand_inf_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf norm) half @zero_result_demand_inf_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[INF:%.*]] = call half @returns_inf()
|
|
; CHECK-NEXT: [[INF_OR_UNKNOWN:%.*]] = select i1 [[COND]], half [[INF]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN1]], [[INF_OR_UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%inf = call half @returns_inf()
|
|
%inf.or.unknown = select i1 %cond, half %inf, half %unknown0
|
|
%div = fdiv half %unknown1, %inf.or.unknown
|
|
ret half %div
|
|
}
|
|
|
|
; Eliminate select
|
|
define nofpclass(nan inf norm) half @zero_result_no_demand_inf_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf norm) half @zero_result_no_demand_inf_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[INF:%.*]] = call half @returns_inf()
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN0]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%inf = call half @returns_inf()
|
|
%inf.or.unknown = select i1 %cond, half %inf, half %unknown0
|
|
%div = fdiv half %inf.or.unknown, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf sub zero) half @norm_result_demands_sub_source_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero sub) half @norm_result_demands_sub_source_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[SUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub = call half @returns_sub()
|
|
%select = select i1 %cond, half %sub, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf sub zero) half @norm_result_demands_sub_source_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero sub) half @norm_result_demands_sub_source_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[SUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub = call half @returns_sub()
|
|
%select = select i1 %cond, half %sub, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan norm zero) half @sub_result_demands_sub_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero norm) half @sub_result_demands_sub_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SUB_OR_UNKNOWN:%.*]] = select i1 [[COND]], half [[SUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[SUB_OR_UNKNOWN]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub = call half @returns_sub()
|
|
%sub.or.unknown = select i1 %cond, half %sub, half %unknown0
|
|
%div = fdiv half %sub.or.unknown, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf nan norm zero) half @sub_result_demands_sub_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan inf zero norm) half @sub_result_demands_sub_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SUB:%.*]] = call half @returns_sub()
|
|
; CHECK-NEXT: [[SUB_OR_UNKNOWN:%.*]] = select i1 [[COND]], half [[SUB]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan ninf half [[UNKNOWN1]], [[SUB_OR_UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%sub = call half @returns_sub()
|
|
%sub.or.unknown = select i1 %cond, half %sub, half %unknown0
|
|
%div = fdiv half %unknown1, %sub.or.unknown
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__known_zero_or_nan__fdiv__not_nan(half nofpclass(inf sub norm) %zero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__known_zero_or_nan__fdiv__not_nan(
|
|
; CHECK-SAME: half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[ZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__known_zero_or_nan__fdiv_nsz__not_nan(half nofpclass(inf sub norm) %zero.or.nan, half nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__known_zero_or_nan__fdiv_nsz__not_nan(
|
|
; CHECK-SAME: half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], half nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[ZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %zero.or.nan, %not.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) <2 x half> @ret__known_zero_or_nan__fdiv_nsz__not_nan_vec(<2 x half> nofpclass(inf sub norm) %zero.or.nan, <2 x half> nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) <2 x half> @ret__known_zero_or_nan__fdiv_nsz__not_nan_vec(
|
|
; CHECK-SAME: <2 x half> nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], <2 x half> nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract <2 x half> [[ZERO_OR_NAN]], [[NOT_NAN]]
|
|
; CHECK-NEXT: ret <2 x half> [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract <2 x half> %zero.or.nan, %not.nan
|
|
ret <2 x half> %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__known_zero_or_nan__fdiv__unknown(half nofpclass(inf sub norm) %zero.or.nan, half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__known_zero_or_nan__fdiv__unknown(
|
|
; CHECK-SAME: half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[ZERO_OR_NAN]], [[UNKNOWN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %zero.or.nan, %unknown
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__zero_or_nan__fdiv_nsz__unknown(half nofpclass(inf sub norm) %zero.or.nan, half %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__zero_or_nan__fdiv_nsz__unknown(
|
|
; CHECK-SAME: half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]], half [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: ret half 0.000000e+00
|
|
;
|
|
%div = fdiv nsz contract half %zero.or.nan, %unknown
|
|
ret half %div
|
|
}
|
|
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv__zero_or_nan(half %unknown, half nofpclass(inf sub norm) %zero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv__zero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], [[ZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %zero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv_nsz__zero_or_nan(half %unknown, half nofpclass(inf sub norm) %zero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv_nsz__zero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[UNKNOWN]], [[ZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %zero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv__pzero_or_nan(half %unknown, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv__pzero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv_nsz__pzero_or_nan(half %unknown, half nofpclass(inf sub norm nzero) %pzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv_nsz__pzero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf nzero sub norm) [[PZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[UNKNOWN]], [[PZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %pzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv__nzero_or_nan(half %unknown, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv__nzero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv_nsz__nzero_or_nan(half %unknown, half nofpclass(inf sub norm pzero) %nzero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv_nsz__nzero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf pzero sub norm) [[NZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[UNKNOWN]], [[NZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv contract nsz half %unknown, %nzero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv__zero(half %unknown, half nofpclass(nan inf sub norm) %zero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv__zero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv_nsz__zero(half %unknown, half nofpclass(nan inf sub norm) %zero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv_nsz__zero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[UNKNOWN]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv__pzero(half %unknown, half nofpclass(inf nan sub norm nzero) %pzero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv__pzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf nzero sub norm) [[PZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], 0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %pzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv_nsz__pzero(half %unknown, half nofpclass(nan inf sub norm nzero) %pzero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv_nsz__pzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf nzero sub norm) [[PZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[UNKNOWN]], 0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %pzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv__nzero(half %unknown, half nofpclass(nan inf sub norm pzero) %nzero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv__nzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf pzero sub norm) [[NZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], -0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %nzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__unknown__fdiv_nsz__nzero(half %unknown, half nofpclass(nan inf sub norm pzero) %nzero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__unknown__fdiv_nsz__nzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf pzero sub norm) [[NZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[UNKNOWN]], -0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %nzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv__zero(half %unknown, half nofpclass(nan inf sub norm) %zero) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv__zero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv_nsz__zero(half %unknown, half nofpclass(nan inf sub norm) %zero) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv_nsz__zero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call nsz contract half @llvm.copysign.f16(half +inf, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv__pzero(half %unknown, half nofpclass(inf nan sub norm nzero) %pzero) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv__pzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf nzero sub norm) [[PZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call half @llvm.copysign.f16(half +inf, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %pzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv_nsz__pzero(half %unknown, half nofpclass(nan inf sub norm nzero) %pzero) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv_nsz__pzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf nzero sub norm) [[PZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call nsz contract half @llvm.copysign.f16(half +inf, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %pzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv__nzero(half %unknown, half nofpclass(nan inf sub norm pzero) %nzero) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv__nzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf pzero sub norm) [[NZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN]], -0.000000e+00
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %nzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv_nsz__nzero(half %unknown, half nofpclass(nan inf sub norm pzero) %nzero) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv_nsz__nzero(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(nan inf pzero sub norm) [[NZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call nsz contract half @llvm.copysign.f16(half +inf, half [[UNKNOWN]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %unknown, %nzero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__not_nan__fdiv_nsz__zero(half nofpclass(nan) %not.nan, half nofpclass(nan inf sub norm) %zero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__not_nan__fdiv_nsz__zero(
|
|
; CHECK-SAME: half nofpclass(nan) [[NOT_NAN:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[NOT_NAN]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %not.nan, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__not_nan_not_zero__fdiv_nsz__zero(half nofpclass(nan zero) %not.nan.or.zero, half nofpclass(nan inf sub norm) %zero) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__not_nan_not_zero__fdiv_nsz__zero(
|
|
; CHECK-SAME: half nofpclass(nan zero) [[NOT_NAN_OR_ZERO:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call nsz contract half @llvm.copysign.f16(half +inf, half [[NOT_NAN_OR_ZERO]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %not.nan.or.zero, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__not_nan_not_zero__fdiv_nsz__zero__daz(half nofpclass(nan zero) %not.nan.or.zero, half nofpclass(nan inf sub norm) %zero) #2 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__not_nan_not_zero__fdiv_nsz__zero__daz(
|
|
; CHECK-SAME: half nofpclass(nan zero) [[NOT_NAN_OR_ZERO:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[NOT_NAN_OR_ZERO]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %not.nan.or.zero, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__not_nan_not_zero__fdiv_nsz__zero__dynamic(half nofpclass(nan zero) %not.nan.or.zero.or.sub, half nofpclass(nan inf sub norm) %zero) #3 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__not_nan_not_zero__fdiv_nsz__zero__dynamic(
|
|
; CHECK-SAME: half nofpclass(nan zero) [[NOT_NAN_OR_ZERO_OR_SUB:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz contract half [[NOT_NAN_OR_ZERO_OR_SUB]], [[ZERO]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %not.nan.or.zero.or.sub, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__not_nan_not_zero_not_sub__fdiv_nsz__zero__daz(half nofpclass(nan zero sub) %not.nan.or.zero.or.sub, half nofpclass(nan inf sub norm) %zero) #2 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__not_nan_not_zero_not_sub__fdiv_nsz__zero__daz(
|
|
; CHECK-SAME: half nofpclass(nan zero sub) [[NOT_NAN_OR_ZERO_OR_SUB:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call nsz contract half @llvm.copysign.f16(half +inf, half [[NOT_NAN_OR_ZERO_OR_SUB]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %not.nan.or.zero.or.sub, %zero
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @ret__not_nan_not_zero_not_sub__fdiv_nsz__zero__dynamic(half nofpclass(nan zero sub) %not.nan.or.zero.or.sub, half nofpclass(nan inf sub norm) %zero) #3 {
|
|
; CHECK-LABEL: define nofpclass(snan) half @ret__not_nan_not_zero_not_sub__fdiv_nsz__zero__dynamic(
|
|
; CHECK-SAME: half nofpclass(nan zero sub) [[NOT_NAN_OR_ZERO_OR_SUB:%.*]], half nofpclass(nan inf sub norm) [[ZERO:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: [[DIV:%.*]] = call nsz contract half @llvm.copysign.f16(half +inf, half [[NOT_NAN_OR_ZERO_OR_SUB]])
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv nsz contract half %not.nan.or.zero.or.sub, %zero
|
|
ret half %div
|
|
}
|
|
|
|
; -> poison
|
|
define nofpclass(nan inf) half @ret_nonan_noinf__unknown__fdiv__zero_or_nan(half %unknown, half nofpclass(inf sub norm) %zero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) half @ret_nonan_noinf__unknown__fdiv__zero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret half poison
|
|
;
|
|
%div = fdiv half %unknown, %zero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan) half @ret_nonan__unknown__fdiv__zero_or_nan(half %unknown, half nofpclass(inf sub norm) %zero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan__unknown__fdiv__zero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[UNKNOWN]], [[ZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %zero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf) half @ret_noinf__unknown__fdiv__zero_or_nan(half %unknown, half nofpclass(inf sub norm) %zero.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(inf) half @ret_noinf__unknown__fdiv__zero_or_nan(
|
|
; CHECK-SAME: half [[UNKNOWN:%.*]], half nofpclass(inf sub norm) [[ZERO_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv half [[UNKNOWN]], [[ZERO_OR_NAN]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%div = fdiv half %unknown, %zero.or.nan
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(nan inf norm sub) half @zero_result_demands_subnorm_lhs__daz(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) #0 {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) half @zero_result_demands_subnorm_lhs__daz(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN0]], half [[ONLY_SUB]]
|
|
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[DIV]]
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_lhs__ieee(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @nan_result_demands_subnorm_lhs__ieee(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_rhs__ieee(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @nan_result_demands_subnorm_rhs__ieee(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_lhs__daz(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) #2 {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @nan_result_demands_subnorm_lhs__daz(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_rhs__daz(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) #2 {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @nan_result_demands_subnorm_rhs__daz(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_lhs__dynamic(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) #3 {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @nan_result_demands_subnorm_lhs__dynamic(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero) half @nan_result_demands_subnorm_rhs__dynamic(i1 %cond, half nofpclass(nan inf zero norm) %only.sub, half %unknown0, half %unknown1) #3 {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) half @nan_result_demands_subnorm_rhs__dynamic(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: ret half +qnan
|
|
;
|
|
%select = select i1 %cond, half %unknown0, half %only.sub
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @qnan_result_demands_snan_src_lhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SNAN:%.*]] = call half @returns_snan()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[MUL:%.*]] = fdiv half [[SELECT]], [[UNKNOWN1]]
|
|
; CHECK-NEXT: ret half [[MUL]]
|
|
;
|
|
%snan = call half @returns_snan()
|
|
%select = select i1 %cond, half %snan, half %unknown0
|
|
%div = fdiv half %select, %unknown1
|
|
ret half %div
|
|
}
|
|
|
|
define nofpclass(snan) half @qnan_result_demands_snan_src_rhs(i1 %cond, half %unknown0, half %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN0:%.*]], half [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SNAN:%.*]] = call half @returns_snan()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[SNAN]], half [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[MUL:%.*]] = fdiv half [[UNKNOWN1]], [[SELECT]]
|
|
; CHECK-NEXT: ret half [[MUL]]
|
|
;
|
|
%snan = call half @returns_snan()
|
|
%select = select i1 %cond, half %snan, half %unknown0
|
|
%div = fdiv half %unknown1, %select
|
|
ret half %div
|
|
}
|
|
|
|
; Make sure the replacement for fdiv is inserted at the fdiv, and not
|
|
; the use fmul
|
|
define float @fdiv_replacement_insert_point_regression(i1 %cmp, float %x, float noundef %y, float noundef %z) {
|
|
; CHECK-LABEL: define float @fdiv_replacement_insert_point_regression(
|
|
; CHECK-SAME: i1 [[CMP:%.*]], float [[X:%.*]], float noundef [[Y:%.*]], float noundef [[Z:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i1 @llvm.is.fpclass.f32(float [[Y]], i32 615)
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], float +qnan, float 1.000000e+00
|
|
; CHECK-NEXT: [[SCALE_0:%.*]] = select i1 [[CMP]], float [[TMP1]], float [[Y]]
|
|
; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SCALE_0]], [[X]]
|
|
; CHECK-NEXT: ret float [[MUL]]
|
|
;
|
|
entry:
|
|
%div = fdiv float %y, %y
|
|
%scale.0 = select i1 %cmp, float %div, float %y
|
|
%mul = fmul float %scale.0, %x
|
|
ret float %mul
|
|
}
|
|
|
|
attributes #0 = { denormal_fpenv(preservesign) }
|
|
attributes #1 = { denormal_fpenv(dynamic) }
|
|
attributes #2 = { denormal_fpenv(ieee|preservesign) }
|
|
attributes #3 = { denormal_fpenv(ieee|dynamic) }
|
|
|
|
!0 = !{!"function_entry_count", i64 1000}
|
|
;.
|
|
; CHECK: attributes #[[ATTR0]] = { denormal_fpenv(ieee|preservesign) }
|
|
; CHECK: attributes #[[ATTR1]] = { denormal_fpenv(preservesign) }
|
|
; CHECK: attributes #[[ATTR2]] = { denormal_fpenv(dynamic) }
|
|
; CHECK: attributes #[[ATTR3]] = { denormal_fpenv(ieee|dynamic) }
|
|
; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
|
|
;.
|
|
; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
|
|
; CHECK: [[PROF1]] = !{!"unknown", !"instcombine"}
|
|
;.
|