; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s declare nofpclass(ninf norm sub zero nan) half @returns_pinf() declare nofpclass(pinf norm sub zero nan) half @returns_ninf() declare nofpclass(norm sub zero nan) half @returns_inf() declare nofpclass(inf norm sub zero) half @returns_nan() declare nofpclass(norm sub zero) half @returns_inf_or_nan() declare nofpclass(qnan inf norm sub zero) half @returns_snan() declare nofpclass(snan inf norm sub zero) half @returns_qnan() declare nofpclass(nan inf norm sub pzero) half @returns_nzero() declare nofpclass(nan inf norm sub nzero) half @returns_pzero() declare nofpclass(nan inf norm sub) half @returns_zero() declare nofpclass(pinf pnorm psub pzero nan) half @returns_negative() declare nofpclass(ninf nnorm nsub nzero nan) half @returns_positive() declare [2 x half] @returns_array() declare { half } @returns_one_elt_struct() declare { half, i32 } @returns_frexp_struct() define nofpclass(nan) half @extractvalue_array_0() { ; CHECK-LABEL: define nofpclass(nan) half @extractvalue_array_0() { ; CHECK-NEXT: [[ARRAY:%.*]] = call [2 x half] @returns_array() ; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue [2 x half] [[ARRAY]], 0 ; CHECK-NEXT: ret half [[EXTRACT]] ; %array = call [2 x half] @returns_array() %extract = extractvalue [2 x half] %array, 0 ret half %extract } define nofpclass(nan) half @extractvalue_array_1() { ; CHECK-LABEL: define nofpclass(nan) half @extractvalue_array_1() { ; CHECK-NEXT: [[ARRAY:%.*]] = call [2 x half] @returns_array() ; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue [2 x half] [[ARRAY]], 1 ; CHECK-NEXT: ret half [[EXTRACT]] ; %array = call [2 x half] @returns_array() %extract = extractvalue [2 x half] %array, 1 ret half %extract } define nofpclass(nan) half @extractvalue_one_elt_struct() { ; CHECK-LABEL: define nofpclass(nan) half @extractvalue_one_elt_struct() { ; CHECK-NEXT: [[STRUCT:%.*]] = call { half } @returns_one_elt_struct() ; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue { half } [[STRUCT]], 0 ; CHECK-NEXT: ret half [[EXTRACT]] ; %struct = call { half } @returns_one_elt_struct() %extract = extractvalue { half } %struct, 0 ret half %extract } define nofpclass(nan) half @extractvalue_not_frexp() { ; CHECK-LABEL: define nofpclass(nan) half @extractvalue_not_frexp() { ; CHECK-NEXT: [[STRUCT:%.*]] = call { half, i32 } @returns_frexp_struct() ; CHECK-NEXT: [[EXTRACT:%.*]] = extractvalue { half, i32 } [[STRUCT]], 0 ; CHECK-NEXT: ret half [[EXTRACT]] ; %struct = call { half, i32 } @returns_frexp_struct() %extract = extractvalue { half, i32 } %struct, 0 ret half %extract } define nofpclass(snan inf norm sub zero) half @ret_only_qnan__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(snan inf zero sub norm) half @ret_only_qnan__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half +qnan ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(qnan inf norm sub zero) half @ret_only_snan__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) half @ret_only_snan__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half [[UNKNOWN]] ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(inf norm sub zero) half @ret_only_nan__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(inf zero sub norm) half @ret_only_nan__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half +qnan ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan ninf norm sub zero) half @ret_only_pinf__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) half @ret_only_pinf__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half +inf ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan pinf norm sub zero) half @ret_only_ninf__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) half @ret_only_ninf__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half -inf ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan norm sub zero) half @ret_only_inf__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan zero sub norm) half @ret_only_inf__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half [[UNKNOWN]] ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan inf norm sub nzero) half @ret_only_pzero__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) half @ret_only_pzero__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half 0.000000e+00 ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan inf norm sub nzero) half @ret_only_nzero__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) half @ret_only_nzero__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half 0.000000e+00 ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan inf norm sub) half @ret_only_zero__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan inf sub norm) half @ret_only_zero__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan inf norm nsub zero) half @ret_only_psub__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan inf zero nsub norm) half @ret_only_psub__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half poison ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan inf norm psub zero) half @ret_only_nsub__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan inf zero psub norm) half @ret_only_nsub__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half poison ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan inf norm zero) half @ret_only_sub__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(nan inf zero norm) half @ret_only_sub__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half poison ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(all) half @ret_nothing__frexp(half %unknown) { ; CHECK-LABEL: define nofpclass(all) half @ret_nothing__frexp( ; CHECK-SAME: half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: ret half poison ; %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %unknown) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.pinf = call half @returns_pinf() %select = select i1 %cond, half %unknown, half %only.pinf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__use_other_output(i1 %cond, half %unknown, ptr %ptr) { ; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__use_other_output( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PINF]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: [[FREXP_EXP:%.*]] = extractvalue { half, i32 } [[FREXP]], 1 ; CHECK-NEXT: store i32 [[FREXP_EXP]], ptr [[PTR]], align 4 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.pinf = call half @returns_pinf() %select = select i1 %cond, half %unknown, half %only.pinf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 %frexp.exp = extractvalue { half, i32 } %frexp, 1 store i32 %frexp.exp, ptr %ptr ret half %frexp.mant } define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__multiple_uses(i1 %cond, half %unknown, ptr %ptr) { ; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__multiple_uses( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PINF]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: store half [[FREXP_MANT]], ptr [[PTR]], align 2 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.pinf = call half @returns_pinf() %select = select i1 %cond, half %unknown, half %only.pinf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 store half %frexp.mant, ptr %ptr ret half %frexp.mant } define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__use_struct(i1 %cond, half %unknown, ptr %ptr) { ; CHECK-LABEL: define nofpclass(pinf) half @ret_nofpclass_pinf__frexp_select_unknown_or_pinf__use_struct( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], ptr [[PTR:%.*]]) { ; CHECK-NEXT: [[ONLY_PINF:%.*]] = call half @returns_pinf() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PINF]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: store { half, i32 } [[FREXP]], ptr [[PTR]], align 4 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.pinf = call half @returns_pinf() %select = select i1 %cond, half %unknown, half %only.pinf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 %frexp.exp = extractvalue { half, i32 } %frexp, 1 store { half, i32 } %frexp, ptr %ptr ret half %frexp.mant } define nofpclass(ninf) half @ret_nofpclass_ninf__frexp_select_unknown_or_ninf(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(ninf) half @ret_nofpclass_ninf__frexp_select_unknown_or_ninf( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_NINF:%.*]] = call half @returns_ninf() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.ninf = call half @returns_ninf() %select = select i1 %cond, half %unknown, half %only.ninf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(inf) half @ret_nofpclass_inf__frexp_select_unknown_or_inf(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(inf) half @ret_nofpclass_inf__frexp_select_unknown_or_inf( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_INF:%.*]] = call half @returns_inf() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.inf = call half @returns_inf() %select = select i1 %cond, half %unknown, half %only.inf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(snan) half @ret_nofpclass_snan__frexp_select_unknown_or_snan(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(snan) half @ret_nofpclass_snan__frexp_select_unknown_or_snan( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_SNAN:%.*]] = call half @returns_snan() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_SNAN]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.snan = call half @returns_snan() %select = select i1 %cond, half %unknown, half %only.snan %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(qnan) half @ret_nofpclass_qnan__frexp_select_unknown_qnan(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(qnan) half @ret_nofpclass_qnan__frexp_select_unknown_qnan( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_QNAN:%.*]] = call half @returns_qnan() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_QNAN]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.qnan = call half @returns_qnan() %select = select i1 %cond, half %unknown, half %only.qnan %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan) half @ret_nofpclass_nan__frexp_select_unknown_nan(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(nan) half @ret_nofpclass_nan__frexp_select_unknown_nan( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_NAN:%.*]] = call half @returns_nan() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.nan = call half @returns_nan() %select = select i1 %cond, half %unknown, half %only.nan %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(pzero) half @ret_nofpclass_pzero__frexp_select_unknown_only_pzero(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(pzero) half @ret_nofpclass_pzero__frexp_select_unknown_only_pzero( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_PZERO:%.*]] = call half @returns_pzero() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.pzero = call half @returns_pzero() %select = select i1 %cond, half %unknown, half %only.pzero %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nzero) half @ret_nofpclass_nzero__frexp_select_unknown_or_not_nzero(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(nzero) half @ret_nofpclass_nzero__frexp_select_unknown_or_not_nzero( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_NZERO:%.*]] = call half @returns_nzero() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.nzero = call half @returns_nzero() %select = select i1 %cond, half %unknown, half %only.nzero %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(zero) half @ret_nofpclass_zero__frexp_select_unknown_or_not_zero(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(zero) half @ret_nofpclass_zero__frexp_select_unknown_or_not_zero( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[ONLY_ZERO:%.*]] = call half @returns_zero() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_ZERO]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.zero = call half @returns_zero() %select = select i1 %cond, half %unknown, half %only.zero %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nnorm sub) half @pnorm_result_demands_psub_source(i1 %cond, half %unknown, half nofpclass(nan inf norm nsub zero) %only.psub) { ; CHECK-LABEL: define nofpclass(sub nnorm) half @pnorm_result_demands_psub_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero nsub norm) [[ONLY_PSUB:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PSUB]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.psub %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(pnorm sub) half @nnorm_result_demands_psub_source(i1 %cond, half %unknown, half nofpclass(nan inf norm psub zero) %only.nsub) { ; CHECK-LABEL: define nofpclass(sub pnorm) half @nnorm_result_demands_psub_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero psub norm) [[ONLY_NSUB:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_NSUB]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.nsub %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(sub) half @norm_result_demands_sub_source(i1 %cond, half %unknown, half nofpclass(nan inf norm zero) %only.sub) { ; CHECK-LABEL: define nofpclass(sub) half @norm_result_demands_sub_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero norm) [[ONLY_SUB:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_SUB]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.sub %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(norm sub nzero) half @pzero_result_demands_psub_source(i1 %cond, half %unknown, half nofpclass(nan inf norm nsub zero) %only.psub) { ; CHECK-LABEL: define nofpclass(nzero sub norm) half @pzero_result_demands_psub_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero nsub norm) [[ONLY_PSUB:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PSUB]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.psub %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(norm sub nzero) half @pzero_result_demands_pnorm_source(i1 %cond, half %unknown, half nofpclass(nan inf nnorm sub zero) %only.pnorm) { ; CHECK-LABEL: define nofpclass(nzero sub norm) half @pzero_result_demands_pnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero sub nnorm) [[ONLY_PNORM:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_PNORM]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.pnorm %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(norm sub pzero) half @nzero_result_demands_nsub_source(i1 %cond, half %unknown, half nofpclass(nan inf norm psub zero) %only.nsub) { ; CHECK-LABEL: define nofpclass(pzero sub norm) half @nzero_result_demands_nsub_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero psub norm) [[ONLY_NSUB:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_NSUB]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.nsub %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(norm sub pzero) half @nzero_result_demands_nnorm_source(i1 %cond, half %unknown, half nofpclass(nan inf pnorm sub zero) %only.nnorm) { ; CHECK-LABEL: define nofpclass(pzero sub norm) half @nzero_result_demands_nnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(nan inf zero sub pnorm) [[ONLY_NNORM:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_NNORM]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.nnorm %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(ninf nnorm nsub nzero) half @ret_only_positive_or_nan__frexp_select_negative_or_unknown(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) half @ret_only_positive_or_nan__frexp_select_negative_or_unknown( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[NEGATIVE:%.*]] = call half @returns_negative() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %negative = call half @returns_negative() %select = select i1 %cond, half %unknown, half %negative %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(pinf pnorm psub pzero) half @ret_only_negative_or_nan__frexp_select_positive_or_unknown(i1 %cond, half %unknown) { ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) half @ret_only_negative_or_nan__frexp_select_positive_or_unknown( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]]) { ; CHECK-NEXT: [[POSITIVE:%.*]] = call half @returns_positive() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[UNKNOWN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %positive = call half @returns_positive() %select = select i1 %cond, half %unknown, half %positive %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(snan) half @src_only_inf__frexp() { ; CHECK-LABEL: define nofpclass(snan) half @src_only_inf__frexp() { ; CHECK-NEXT: [[ONLY_INF:%.*]] = call half @returns_inf() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[ONLY_INF]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.inf = call half @returns_inf() %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %only.inf) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(snan) half @src_only_nan__frexp() { ; CHECK-LABEL: define nofpclass(snan) half @src_only_nan__frexp() { ; CHECK-NEXT: [[ONLY_NAN:%.*]] = call half @returns_nan() ; CHECK-NEXT: ret half +qnan ; %only.nan = call half @returns_nan() %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %only.nan) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(snan) half @src_only_nan_or_inf__frexp() { ; CHECK-LABEL: define nofpclass(snan) half @src_only_nan_or_inf__frexp() { ; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call half @returns_inf_or_nan() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[INF_OR_NAN]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %inf.or.nan = call half @returns_inf_or_nan() %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %inf.or.nan) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(snan) half @src_only_zero__frexp() { ; CHECK-LABEL: define nofpclass(snan) half @src_only_zero__frexp() { ; CHECK-NEXT: [[ONLY_ZERO:%.*]] = call half @returns_zero() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[ONLY_ZERO]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %only.zero = call half @returns_zero() %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %only.zero) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(nan) half @ret_no_nan_src_only_inf__frexp() { ; CHECK-LABEL: define nofpclass(nan) half @ret_no_nan_src_only_inf__frexp() { ; CHECK-NEXT: [[INF:%.*]] = call half @returns_inf() ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[INF]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %inf = call half @returns_inf() %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %inf) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(inf) half @ret_no_inf_src_only_nan__frexp() { ; CHECK-LABEL: define nofpclass(inf) half @ret_no_inf_src_only_nan__frexp() { ; CHECK-NEXT: [[NAN:%.*]] = call half @returns_nan() ; CHECK-NEXT: ret half +qnan ; %nan = call half @returns_nan() %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %nan) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant } define nofpclass(inf) half @multiple_extract_uses(i1 %cond, half %unknown, ptr noundef %ptr) { ; CHECK-LABEL: define nofpclass(inf) half @multiple_extract_uses( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], ptr noundef [[PTR:%.*]]) { ; CHECK-NEXT: [[INF:%.*]] = call half @returns_inf() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[INF]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: [[FREXP_MANT2:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: store half [[FREXP_MANT2]], ptr [[PTR]], align 2 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %inf = call half @returns_inf() %select = select i1 %cond, half %unknown, half %inf %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 %frexp.mant2 = extractvalue { half, i32 } %frexp, 0 store half %frexp.mant2, ptr %ptr ret half %frexp.mant } define nofpclass(snan) half @qnan_result_demands_snan_src(i1 %cond, half %unknown, half nofpclass(qnan inf norm sub zero) %only.snan) { ; CHECK-LABEL: define nofpclass(snan) half @qnan_result_demands_snan_src( ; CHECK-SAME: i1 [[COND:%.*]], half [[UNKNOWN:%.*]], half nofpclass(qnan inf zero sub norm) [[ONLY_SNAN:%.*]]) { ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], half [[UNKNOWN]], half [[ONLY_SNAN]] ; CHECK-NEXT: [[FREXP:%.*]] = call { half, i32 } @llvm.frexp.f16.i32(half [[SELECT]]) ; CHECK-NEXT: [[FREXP_MANT:%.*]] = extractvalue { half, i32 } [[FREXP]], 0 ; CHECK-NEXT: ret half [[FREXP_MANT]] ; %select = select i1 %cond, half %unknown, half %only.snan %frexp = call { half, i32 } @llvm.frexp.f16.i32(half %select) %frexp.mant = extractvalue { half, i32 } %frexp, 0 ret half %frexp.mant }