blob: 343e453b9f88a1733ac7d2de9f6097f6694aa212 [file] [edit]
; 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"}
;.