; 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"} ;.