; 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(nan inf sub norm) float @returns_zero() declare nofpclass(nan inf nzero sub norm) float @returns_pzero() declare nofpclass(nan inf pzero sub norm) float @returns_nzero() declare nofpclass(nan inf norm zero) float @returns_sub() declare nofpclass(nan inf norm psub zero) float @returns_nsub() declare nofpclass(nan inf norm nsub zero) float @returns_psub() declare nofpclass(nan inf sub zero) float @returns_norm() declare nofpclass(nan inf pnorm sub zero) float @returns_nnorm() declare nofpclass(nan inf nnorm sub zero) float @returns_pnorm() declare nofpclass(inf norm sub zero) float @returns_nan() declare nofpclass(inf norm sub zero) <2 x float> @returns_nan_vec() declare nofpclass(qnan inf norm sub zero) float @returns_snan() declare nofpclass(nan norm sub zero) float @returns_inf() declare nofpclass(ninf nnorm nsub nzero nan) float @returns_positive() declare nofpclass(ninf nnorm nsub nzero) float @returns_positive_or_nan() declare nofpclass(pinf pnorm psub pzero nan) float @returns_negative() declare nofpclass(pinf pnorm psub pzero) float @returns_negative_or_nan() define nofpclass(qnan inf norm sub zero) float @ret_only_snan__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) float @ret_only_snan__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(snan inf norm sub zero) float @ret_only_qnan__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_only_qnan__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: ret float +qnan ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(inf norm sub zero) float @ret_only_nan__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_only_nan__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: ret float +qnan ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(nan norm sub zero) float @ret_only_inf__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan zero sub norm) float @ret_only_inf__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(nan ninf norm sub zero) float @ret_only_pinf__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) float @ret_only_pinf__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: ret float +inf ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(nan pinf norm sub zero) float @ret_only_ninf__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) float @ret_only_ninf__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: ret float -inf ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(inf nan norm sub) float @ret_only_zero__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan inf sub norm) float @ret_only_zero__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(inf nan norm sub nzero) float @ret_only_pzero__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @ret_only_pzero__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: ret float 0.000000e+00 ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(inf nan norm sub pzero) float @ret_only_nzero__ldexp(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan inf pzero sub norm) float @ret_only_nzero__ldexp( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: ret float -0.000000e+00 ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(snan) float @ret_nofpclass_snan__ldexp_unknown_unknown(float %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(snan) float @ret_nofpclass_snan__ldexp_unknown_unknown( ; CHECK-SAME: float [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(snan) float @ret_nofpclass_snan__ldexp_no_snan_unknown(float nofpclass(snan) %x, i32 %exp) { ; CHECK-LABEL: define nofpclass(snan) float @ret_nofpclass_snan__ldexp_no_snan_unknown( ; CHECK-SAME: float nofpclass(snan) [[X:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %exp) ret float %ldexp } define nofpclass(nan) float @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown(i1 %cond, float %unknown, i32 %exp) { ; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[NAN:%.*]] = call float @returns_nan() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %nan = call float @returns_nan() %select = select i1 %cond, float %nan, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %exp) ret float %ldexp } define nofpclass(nan) <2 x float> @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown_vec(i1 %cond, <2 x float> %unknown, <2 x i32> %exp) { ; CHECK-LABEL: define nofpclass(nan) <2 x float> @ret_nofpclass_nan__ldexp_select_nan_or_unknown__unknown_vec( ; CHECK-SAME: i1 [[COND:%.*]], <2 x float> [[UNKNOWN:%.*]], <2 x i32> [[EXP:%.*]]) { ; CHECK-NEXT: [[NAN:%.*]] = call <2 x float> @returns_nan_vec() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[UNKNOWN]], <2 x i32> [[EXP]]) ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %nan = call <2 x float> @returns_nan_vec() %select = select i1 %cond, <2 x float> %nan, <2 x float> %unknown %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %select, <2 x i32> %exp) ret <2 x float> %ldexp } define nofpclass(inf) float @ret_nofpclass_inf__ldexp_select_inf_or_unknown__unknown(i1 %cond, float %unknown, i32 %exp) { ; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__ldexp_select_inf_or_unknown__unknown( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[EXP:%.*]]) { ; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf() ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[EXP]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %inf = call float @returns_inf() %select = select i1 %cond, float %inf, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %exp) ret float %ldexp } define nofpclass(nan inf norm sub) float @zero_result_demands_sub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_demands_sub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %sub = call float @returns_sub() %select = select i1 %cond, float %sub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm psub nzero) float @pzero_result_demands_psub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf nzero psub norm) float @pzero_result_demands_psub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[PSUB:%.*]] = call float @returns_psub() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[PSUB]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %psub = call float @returns_psub() %select = select i1 %cond, float %psub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm nsub pzero) float @nzero_result_demands_nsub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf pzero nsub norm) float @nzero_result_demands_nsub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NSUB:%.*]] = call float @returns_nsub() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NSUB]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %nsub = call float @returns_nsub() %select = select i1 %cond, float %nsub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm psub nzero) float @pzero_result_demands_pnorm_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf nzero psub norm) float @pzero_result_demands_pnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[PNORM:%.*]] = call float @returns_pnorm() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[PNORM]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %pnorm = call float @returns_pnorm() %select = select i1 %cond, float %pnorm, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm psub pzero) float @nzero_result_demands_nnorm_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf pzero psub norm) float @nzero_result_demands_nnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NNORM:%.*]] = call float @returns_nnorm() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NNORM]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %nnorm = call float @returns_nnorm() %select = select i1 %cond, float %nnorm, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm nsub nzero) float @pzero_result_no_demand_nnorm_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf nzero nsub norm) float @pzero_result_no_demand_nnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NNORM:%.*]] = call float @returns_nnorm() ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %nnorm = call float @returns_nnorm() %select = select i1 %cond, float %nnorm, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm psub pzero) float @nzero_result_no_demand_pnorm_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf pzero psub norm) float @nzero_result_no_demand_pnorm_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[PNORM:%.*]] = call float @returns_pnorm() ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %pnorm = call float @returns_pnorm() %select = select i1 %cond, float %pnorm, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm sub nzero) float @pzero_result_no_demand_nsub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf nzero sub norm) float @pzero_result_no_demand_nsub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NSUB:%.*]] = call float @returns_nsub() ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %nsub = call float @returns_nsub() %select = select i1 %cond, float %nsub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(inf norm sub pzero) float @nzero_result_no_demand_psub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(inf pzero sub norm) float @nzero_result_no_demand_psub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[PSUB:%.*]] = call float @returns_psub() ; CHECK-NEXT: [[LDEXP:%.*]] = call ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %psub = call float @returns_psub() %select = select i1 %cond, float %psub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf norm sub) float @zero_result_demands_norm_source_lhs(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_demands_norm_source_lhs( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NORM:%.*]] = call float @returns_norm() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %norm = call float @returns_norm() %select = select i1 %cond, float %norm, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf sub zero) float @norm_result_demands_sub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf zero sub) float @norm_result_demands_sub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %sub = call float @returns_sub() %select = select i1 %cond, float %sub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan norm sub) float @inf_result_demands_sub_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan sub norm) float @inf_result_demands_sub_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[SUB:%.*]] = call float @returns_sub() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SUB]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %sub = call float @returns_sub() %select = select i1 %cond, float %sub, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan norm sub) float @inf_result_demands_norm_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan sub norm) float @inf_result_demands_norm_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NORM:%.*]] = call float @returns_norm() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[NORM]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %norm = call float @returns_norm() %select = select i1 %cond, float %norm, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan norm sub) float @inf_result_demands_inf_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan sub norm) float @inf_result_demands_inf_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[INF]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %inf = call float @returns_inf() %select = select i1 %cond, float %inf, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf sub zero) float @zero_result_no_zero_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf zero sub) float @zero_result_no_zero_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[ZERO:%.*]] = call float @returns_zero() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %zero = call float @returns_zero() %select = select i1 %cond, float %zero, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(pinf pnorm psub pzero) float @negative_result_implies_no_positive_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @negative_result_implies_no_positive_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[POS:%.*]] = call float @returns_positive() ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %pos = call float @returns_positive() %select = select i1 %cond, float %pos, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(ninf nnorm nsub nzero) float @positive_result_implies_no_negative_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @positive_result_implies_no_negative_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NEG:%.*]] = call float @returns_negative() ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %neg = call float @returns_negative() %select = select i1 %cond, float %neg, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan pinf pnorm psub pzero) float @negative_nonan_result_implies_no_positive_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @negative_nonan_result_implies_no_positive_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[POS_OR_NAN:%.*]] = call float @returns_positive_or_nan() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %pos.or.nan = call float @returns_positive_or_nan() %select = select i1 %cond, float %pos.or.nan, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan ninf nnorm nsub nzero) float @positive_nonan_result_implies_no_negative_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @positive_nonan_result_implies_no_negative_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[NEG_OR_NAN:%.*]] = call float @returns_negative_or_nan() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %neg.or.nan = call float @returns_negative_or_nan() %select = select i1 %cond, float %neg.or.nan, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf norm sub) float @zero_result_select_inf_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_select_inf_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %inf = call float @returns_inf() %select = select i1 %cond, float %inf, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf norm zero) float @sub_result_select_inf_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf zero norm) float @sub_result_select_inf_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %inf = call float @returns_inf() %select = select i1 %cond, float %inf, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf sub zero) float @norm_result_select_inf_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf zero sub) float @norm_result_select_inf_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf() ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[UNKNOWN]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %inf = call float @returns_inf() %select = select i1 %cond, float %inf, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(nan inf norm sub) float @zero_result_select_zero_source(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(nan inf sub norm) float @zero_result_select_zero_source( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[ZERO:%.*]] = call float @returns_zero() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[ZERO]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %zero = call float @returns_zero() %select = select i1 %cond, float %zero, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp } define nofpclass(snan) float @qnan_result_demands_snan_src(i1 %cond, float %unknown, i32 %unknown.int) { ; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_src( ; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], i32 [[UNKNOWN_INT:%.*]]) { ; CHECK-NEXT: [[SNAN:%.*]] = call float @returns_snan() ; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN]] ; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[SELECT]], i32 [[UNKNOWN_INT]]) ; CHECK-NEXT: ret float [[LDEXP]] ; %snan = call float @returns_snan() %select = select i1 %cond, float %snan, float %unknown %ldexp = call float @llvm.ldexp.f32.i32(float %select, i32 %unknown.int) ret float %ldexp }