| ; 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 0x7FF8000000000000 |
| ; |
| %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 0x7FF8000000000000 |
| ; |
| %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 0x7FF0000000000000 |
| ; |
| %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 0xFFF0000000000000 |
| ; |
| %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 |
| } |