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