blob: ee431d216b41f52bf3a7bc4ae0803dd75370f6fb [file] [edit]
; 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 0xH7E00
;
%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 0xH7E00
;
%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 0xH7C00
;
%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 0xHFC00
;
%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 0xH0000
;
%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 0xH0000
;
%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 0xH7E00
;
%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 0xH7E00
;
%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
}