Convert "denormal-fp-math" and "denormal-fp-math-f32" into a first class denormal_fpenv attribute. Previously the query for the effective denormal mode involved two string attribute queries with parsing. I'm introducing more uses of this, so it makes sense to convert this to a more efficient encoding. The old representation was also awkward since it was split across two separate attributes. The new encoding just stores the default and float modes as bitfields, largely avoiding the need to consider if the other mode is set. The syntax in the common cases looks like this: `denormal_fpenv(preservesign,preservesign)` `denormal_fpenv(float: preservesign,preservesign)` `denormal_fpenv(dynamic,dynamic float: preservesign,preservesign)` I wasn't sure about reusing the float type name instead of adding a new keyword. It's parsed as a type but only accepts float. I'm also debating switching the name to subnormal to match the current preferred IEEE terminology (also used by nofpclass and other contexts). This has a behavior change when using the command flag debug options to set the denormal mode. The behavior of the flag ignored functions with an explicit attribute set, per the default and f32 version. Now that these are one attribute, the flag logic can't distinguish which of the two components were explicitly set on the function. Only one test appeared to rely on this behavior, so I just avoided using the flags in it. This also does not perform all the code cleanups this enables. In particular the attributor handling could be cleaned up. I also guessed at how to support this in MLIR. I followed MemoryEffects as a reference; it appears bitfields are expanded into arguments to attributes, so the representation there is a bit uglier with the 2 2-element fields flattened into 4 arguments.
2191 lines
112 KiB
LLVM
2191 lines
112 KiB
LLVM
; 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 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()
|
|
|
|
declare nofpclass(ninf nnorm nsub nan) float @returns_positive_or_zero()
|
|
declare nofpclass(pinf pnorm psub nan) float @returns_negative_or_zero()
|
|
|
|
declare nofpclass(ninf nnorm nsub) float @returns_positive_or_zero_or_nan()
|
|
declare nofpclass(pinf pnorm psub) float @returns_negative_or_zero_or_nan()
|
|
|
|
declare nofpclass(inf sub norm nan) float @returns_zero()
|
|
declare nofpclass(inf sub norm) float @returns_zero_or_nan()
|
|
declare nofpclass(inf sub norm nan pzero) float @returns_nzero()
|
|
declare nofpclass(inf sub norm pzero) float @returns_nzero_or_nan()
|
|
declare nofpclass(inf sub norm nan nzero) float @returns_pzero()
|
|
declare nofpclass(inf sub norm nzero) float @returns_pzero_or_nan()
|
|
declare nofpclass(inf norm sub zero) float @returns_nan()
|
|
declare nofpclass(qnan inf norm sub zero) float @returns_snan()
|
|
|
|
declare nofpclass(ninf norm sub zero nan) float @returns_pinf()
|
|
declare nofpclass(ninf norm sub zero) float @returns_pinf_or_nan()
|
|
|
|
declare nofpclass(pinf norm sub zero nan) float @returns_ninf()
|
|
declare nofpclass(pinf norm sub zero) float @returns_ninf_or_nan()
|
|
|
|
declare nofpclass(norm sub zero nan) float @returns_inf()
|
|
declare nofpclass(norm sub zero) float @returns_inf_or_nan()
|
|
|
|
declare nofpclass(inf pnorm sub zero nan) float @returns_nnorm()
|
|
declare nofpclass(inf nnorm sub zero nan) float @returns_pnorm()
|
|
|
|
declare nofpclass(inf pnorm sub zero) float @returns_nnorm_or_nan()
|
|
declare nofpclass(inf nnorm sub zero) float @returns_pnorm_or_nan()
|
|
|
|
declare nofpclass(inf norm psub zero nan) float @returns_nsub()
|
|
declare nofpclass(inf norm nsub zero nan) float @returns_psub()
|
|
|
|
declare nofpclass(pinf pnorm psub zero nan) float @returns_negative_nonzero()
|
|
declare nofpclass(ninf nnorm nsub zero nan) float @returns_positive_nonzero()
|
|
declare nofpclass(pinf pnorm psub zero) float @returns_negative_nonzero_or_nan()
|
|
declare nofpclass(ninf nnorm nsub zero) float @returns_positive_nonzero_or_nan()
|
|
|
|
; -> qnan
|
|
define nofpclass(inf norm sub zero) float @ret_only_nan(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_only_nan(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret float 0x7FF8000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero qnan) float @ret_only_snan(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(qnan inf zero sub norm) float @ret_only_snan(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf norm sub zero snan) float @ret_only_qnan(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_only_qnan(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret float 0x7FF8000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan norm sub zero) float @ret_only_inf(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan zero sub norm) float @ret_only_inf(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan pinf norm sub zero) float @ret_only_ninf(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan pinf zero sub norm) float @ret_only_ninf(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan ninf norm sub zero) float @ret_only_pinf(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf zero sub norm) float @ret_only_pinf(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret float 0x7FF0000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf nan norm sub) float @ret_only_zero(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf sub norm) float @ret_only_zero(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf nan norm sub nzero) float @ret_only_pzero(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @ret_only_pzero(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret float 0.000000e+00
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf nan norm sub pzero) float @ret_only_nzero(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf pzero sub norm) float @ret_only_nzero(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: ret float -0.000000e+00
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_no_nans(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf) float @ret_no_infs(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(inf) float @ret_no_infs(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan inf) float @ret_no_nans_no_infs(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan inf) float @ret_no_nans_no_infs(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
; -> qnan
|
|
define nofpclass(ninf nnorm nsub nzero) float @ret_known_positive_or_nan__minimumnum__negative_or_nan___negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_known_positive_or_nan__minimumnum__negative_or_nan___negative_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_NAN0:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_NAN1:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: ret float 0x7FF8000000000000
|
|
;
|
|
%must.be.negative.or.nan0 = call float @returns_negative_or_nan()
|
|
%must.be.negative.or.nan1 = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.negative.or.nan0, float %must.be.negative.or.nan1)
|
|
ret float %result
|
|
}
|
|
|
|
; -> qnan
|
|
define nofpclass(pinf pnorm psub pzero) float @ret_known_negative_or_nan__minimumnum__positive_or_nan___positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_known_negative_or_nan__minimumnum__positive_or_nan___positive_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN0:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN1:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: ret float 0x7FF8000000000000
|
|
;
|
|
%must.be.positive.or.nan0 = call float @returns_positive_or_nan()
|
|
%must.be.positive.or.nan1 = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.positive.or.nan0, float %must.be.positive.or.nan1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive_or_nan__minimumnum__known_negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive_or_nan__minimumnum__known_negative_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[MUST_BE_POSITIVE_OR_NAN]], float [[MUST_BE_NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.positive.or.nan = call float @returns_positive_or_nan()
|
|
%must.be.negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.positive.or.nan, float %must.be.negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative_or_nan__minimumnum__known_positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative_or_nan__minimumnum__known_positive_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[MUST_BE_NEGATIVE_OR_NAN]], float [[MUST_BE_POSITIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.negative.or.nan = call float @returns_negative_or_nan()
|
|
%must.be.positive.or.nan = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.negative.or.nan, float %must.be.positive.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive_or_nan__minimumnum__known_negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive_or_nan__minimumnum__known_negative() {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[MUST_BE_NEGATIVE]]
|
|
;
|
|
%must.be.positive.or.nan = call float @returns_positive_or_nan()
|
|
%must.be.negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.positive.or.nan, float %must.be.negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative__minimumnum__known_positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative__minimumnum__known_positive_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: ret float [[MUST_BE_NEGATIVE]]
|
|
;
|
|
%must.be.negative = call float @returns_negative()
|
|
%must.be.positive.or.nan = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.negative, float %must.be.positive.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero) float @ret_always_positive_or_nan__select_always_negative_or_unknown__minimumnum__unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_always_positive_or_nan__select_always_negative_or_unknown__minimumnum__unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_LHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT_LHS]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.lhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %select.lhs, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero) float @ret_always_positive_or_nan__unknown__minimumnum__select_always_negative_or_unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_always_positive_or_nan__unknown__minimumnum__select_always_negative_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.rhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero nan) float @ret_always_positive__select_always_negative_or_unknown__minimumnum__unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_always_positive__select_always_negative_or_unknown__minimumnum__unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_LHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT_LHS]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.lhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %select.lhs, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero nan) float @ret_always_positive__unknown__minimumnum__select_always_negative_or_unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_always_positive__unknown__minimumnum__select_always_negative_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.rhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero) float @ret_always_negative_or_nan__simplify_unneeded_lhs_rhs(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_always_negative_or_nan__simplify_unneeded_lhs_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE0:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE1:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_LHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE0]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[UNKNOWN1]], float [[ALWAYS_NEGATIVE1]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT_LHS]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative0 = call float @returns_negative()
|
|
%always.negative1 = call float @returns_negative()
|
|
%select.lhs = select i1 %cond, float %always.negative0, float %unknown0
|
|
%select.rhs = select i1 %cond, float %unknown1, float %always.negative1
|
|
%result = call float @llvm.minimumnum.f32(float %select.lhs, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero nan) float @ret_always_negative__simplify_unneeded_lhs_rhs(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_always_negative__simplify_unneeded_lhs_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE0:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE1:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_LHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE0]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[UNKNOWN1]], float [[ALWAYS_NEGATIVE1]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT_LHS]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative0 = call float @returns_negative()
|
|
%always.negative1 = call float @returns_negative()
|
|
%select.lhs = select i1 %cond, float %always.negative0, float %unknown0
|
|
%select.rhs = select i1 %cond, float %unknown1, float %always.negative1
|
|
%result = call float @llvm.minimumnum.f32(float %select.lhs, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @no_fold_select_always_negative_0(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan) float @no_fold_select_always_negative_0(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_LHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT_LHS]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.lhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %select.lhs, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @no_fold_select_always_negative_1(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan) float @no_fold_select_always_negative_1(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.rhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
; Cannot fold out due to possible -0
|
|
define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_0() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_0() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.negative.or.zero = call float @returns_positive_or_zero()
|
|
%must.be.positive.or.zero = call float @returns_negative_or_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.negative.or.zero, float %must.be.positive.or.zero)
|
|
ret float %result
|
|
}
|
|
|
|
; Cannot fold out due to possible -0
|
|
define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.negative.or.zero = call float @returns_positive_or_zero()
|
|
%must.be.positive.or.zero = call float @returns_negative_or_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.positive.or.zero, float %must.be.negative.or.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0() {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO1:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: ret float [[MUST_BE_POSITIVE_OR_ZERO]]
|
|
;
|
|
%must.be.negative.or.zero = call float @returns_negative_or_zero()
|
|
%must.be.positive.or.zero = call float @returns_positive_or_zero()
|
|
%result = call nsz float @llvm.minimumnum.f32(float %must.be.negative.or.zero, float %must.be.positive.or.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: ret float [[MUST_BE_POSITIVE_OR_ZERO]]
|
|
;
|
|
%must.be.positive.or.zero = call float @returns_positive_or_zero()
|
|
%must.be.negative.or.zero = call float @returns_negative_or_zero()
|
|
%result = call nsz float @llvm.minimumnum.f32(float %must.be.positive.or.zero, float %must.be.negative.or.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @lhs_must_be_pinf_or_nan(float %unknown, float nofpclass(ninf norm zero sub) %must.be.pinf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @lhs_must_be_pinf_or_nan(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(ninf zero sub norm) [[MUST_BE_PINF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[MUST_BE_PINF_OR_NAN]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.pinf.or.nan, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @rhs_must_be_pinf_or_nan(float nofpclass(ninf norm zero sub) %must.be.pinf.or.nan, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @rhs_must_be_pinf_or_nan(
|
|
; CHECK-SAME: float nofpclass(ninf zero sub norm) [[MUST_BE_PINF_OR_NAN:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[MUST_BE_PINF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %must.be.pinf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @lhs_must_be_pinf(float %unknown, float nofpclass(nan ninf norm zero sub) %must.be.pinf) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @lhs_must_be_pinf(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(nan ninf zero sub norm) [[MUST_BE_PINF:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float 0x7FF0000000000000)
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.pinf, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @rhs_must_be_pinf(float nofpclass(nan ninf norm zero sub) %must.be.pinf, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @rhs_must_be_pinf(
|
|
; CHECK-SAME: float nofpclass(nan ninf zero sub norm) [[MUST_BE_PINF:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float 0x7FF0000000000000)
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %must.be.pinf)
|
|
ret float %result
|
|
}
|
|
|
|
; -> inf
|
|
define nofpclass(nsub) float @lhs_must_be_pinf_rhs_non_nan(float nofpclass(nan) %not.nan, float nofpclass(nan ninf norm zero sub) %must.be.pinf) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @lhs_must_be_pinf_rhs_non_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]], float nofpclass(nan ninf zero sub norm) [[MUST_BE_PINF:%.*]]) {
|
|
; CHECK-NEXT: ret float [[NOT_NAN]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.pinf, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
; -> inf
|
|
define nofpclass(nsub) float @rhs_must_be_pinf_lhs_non_nan(float nofpclass(nan ninf norm zero sub) %must.be.pinf, float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @rhs_must_be_pinf_lhs_non_nan(
|
|
; CHECK-SAME: float nofpclass(nan ninf zero sub norm) [[MUST_BE_PINF:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret float [[NOT_NAN]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %must.be.pinf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @lhs_must_be_ninf_or_nan(float %unknown, float nofpclass(pinf norm zero sub) %must.be.ninf.or.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @lhs_must_be_ninf_or_nan(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(pinf zero sub norm) [[MUST_BE_NINF_OR_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[MUST_BE_NINF_OR_NAN]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.ninf.or.nan, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @rhs_must_be_ninf_or_nan(float nofpclass(pinf norm zero sub) %must.be.ninf.or.nan, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @rhs_must_be_ninf_or_nan(
|
|
; CHECK-SAME: float nofpclass(pinf zero sub norm) [[MUST_BE_NINF_OR_NAN:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[MUST_BE_NINF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %must.be.ninf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @lhs_must_be_ninf(float %unknown, float nofpclass(nan pinf norm zero sub) %must.be.ninf) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @lhs_must_be_ninf(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(nan pinf zero sub norm) [[MUST_BE_NINF:%.*]]) {
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.ninf, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nsub) float @rhs_must_be_ninf(float nofpclass(nan pinf norm zero sub) %must.be.ninf, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @rhs_must_be_ninf(
|
|
; CHECK-SAME: float nofpclass(nan pinf zero sub norm) [[MUST_BE_NINF:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %must.be.ninf)
|
|
ret float %result
|
|
}
|
|
|
|
|
|
; -> not.nan
|
|
define nofpclass(nsub) float @lhs_must_be_ninf_rhs_non_nan(float nofpclass(nan) %not.nan, float nofpclass(nan pinf norm zero sub) %must.be.ninf) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @lhs_must_be_ninf_rhs_non_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]], float nofpclass(nan pinf zero sub norm) [[MUST_BE_NINF:%.*]]) {
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.ninf, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
; -> not.nan
|
|
define nofpclass(nsub) float @rhs_must_be_ninf_lhs_non_nan(float nofpclass(nan pinf norm zero sub) %must.be.ninf, float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(nsub) float @rhs_must_be_ninf_lhs_non_nan(
|
|
; CHECK-SAME: float nofpclass(nan pinf zero sub norm) [[MUST_BE_NINF:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %must.be.ninf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nzero) float @result_not_nzero(float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nzero) float @result_not_nzero(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(pzero) float @result_not_pzero(float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(pzero) float @result_not_pzero(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(zero) float @result_not_zero(float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(zero) float @result_not_zero(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(zero) float @result_not_zero__daz(float %unknown0, float %unknown1) #0 {
|
|
; CHECK-LABEL: define nofpclass(zero) float @result_not_zero__daz(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(zero) float @result_not_zero__dynamic(float %unknown0, float %unknown1) #1 {
|
|
; CHECK-LABEL: define nofpclass(zero) float @result_not_zero__dynamic(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(zero) float @result_not_zero_or_sub(float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(zero) float @result_not_zero_or_sub(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(zero sub) float @result_not_zero_or_sub__daz(float %unknown0, float %unknown1) #0 {
|
|
; CHECK-LABEL: define nofpclass(zero sub) float @result_not_zero_or_sub__daz(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(zero sub) float @result_not_zero_or_sub__dynamic(float %unknown0, float %unknown1) #1 {
|
|
; CHECK-LABEL: define nofpclass(zero sub) float @result_not_zero_or_sub__dynamic(
|
|
; CHECK-SAME: float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN0]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown0, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @lhs_not_zero(float nofpclass(zero) %not.zero, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @lhs_not_zero(
|
|
; CHECK-SAME: float nofpclass(zero) [[NOT_ZERO:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @rhs_not_zero(float %unknown, float nofpclass(zero) %not.zero) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @rhs_not_zero(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[NOT_ZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %not.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_zero(float nofpclass(zero) %not.zero0, float nofpclass(zero) %not.zero1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_zero(
|
|
; CHECK-SAME: float nofpclass(zero) [[NOT_ZERO0:%.*]], float nofpclass(zero) [[NOT_ZERO1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO0]], float [[NOT_ZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero0, float %not.zero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_zero__daz(float nofpclass(zero) %not.zero0, float nofpclass(zero) %not.zero1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_zero__daz(
|
|
; CHECK-SAME: float nofpclass(zero) [[NOT_ZERO0:%.*]], float nofpclass(zero) [[NOT_ZERO1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_ZERO0]], float [[NOT_ZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero0, float %not.zero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_zero__dynamic(float nofpclass(zero) %not.zero0, float nofpclass(zero) %not.zero1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_zero__dynamic(
|
|
; CHECK-SAME: float nofpclass(zero) [[NOT_ZERO0:%.*]], float nofpclass(zero) [[NOT_ZERO1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_ZERO0]], float [[NOT_ZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero0, float %not.zero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_zero_or_sub(float nofpclass(zero sub) %not.zero.sub.0, float nofpclass(zero sub) %not.zero.sub.1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_zero_or_sub(
|
|
; CHECK-SAME: float nofpclass(zero sub) [[NOT_ZERO_SUB_0:%.*]], float nofpclass(zero sub) [[NOT_ZERO_SUB_1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO_SUB_0]], float [[NOT_ZERO_SUB_1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero.sub.0, float %not.zero.sub.1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_zero_or_sub__daz(float nofpclass(zero sub) %not.zero.sub.0, float nofpclass(zero sub) %not.zero.sub.1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_zero_or_sub__daz(
|
|
; CHECK-SAME: float nofpclass(zero sub) [[NOT_ZERO_SUB_0:%.*]], float nofpclass(zero sub) [[NOT_ZERO_SUB_1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO_SUB_0]], float [[NOT_ZERO_SUB_1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero.sub.0, float %not.zero.sub.1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_zero_or_sub__dynamic(float nofpclass(zero sub) %not.zero.sub.0, float nofpclass(zero sub) %not.zero.sub.1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_zero_or_sub__dynamic(
|
|
; CHECK-SAME: float nofpclass(zero sub) [[NOT_ZERO_SUB_0:%.*]], float nofpclass(zero sub) [[NOT_ZERO_SUB_1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO_SUB_0]], float [[NOT_ZERO_SUB_1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero.sub.0, float %not.zero.sub.1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_nzero(float nofpclass(nzero) %not.nzero0, float nofpclass(nzero) %not.nzero1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_nzero(
|
|
; CHECK-SAME: float nofpclass(nzero) [[NOT_NZERO0:%.*]], float nofpclass(nzero) [[NOT_NZERO1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_NZERO0]], float [[NOT_NZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero0, float %not.nzero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_pzero(float nofpclass(pzero) %not.pzero0, float nofpclass(pzero) %not.pzero1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_pzero(
|
|
; CHECK-SAME: float nofpclass(pzero) [[NOT_PZERO0:%.*]], float nofpclass(pzero) [[NOT_PZERO1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_PZERO0]], float [[NOT_PZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.pzero0, float %not.pzero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @lhs_not_nzero_rhs_not_pzero(float nofpclass(nzero) %not.nzero, float nofpclass(pzero) %not.pzero) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @lhs_not_nzero_rhs_not_pzero(
|
|
; CHECK-SAME: float nofpclass(nzero) [[NOT_NZERO:%.*]], float nofpclass(pzero) [[NOT_PZERO:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO]], float [[NOT_PZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero, float %not.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @rhs_not_nzero_lhs_not_pzero(float nofpclass(pzero) %not.nzero, float nofpclass(nzero) %not.pzero) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @rhs_not_nzero_lhs_not_pzero(
|
|
; CHECK-SAME: float nofpclass(pzero) [[NOT_NZERO:%.*]], float nofpclass(nzero) [[NOT_PZERO:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO]], float [[NOT_PZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero, float %not.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_nzero__dynamic(float nofpclass(nzero) %not.nzero0, float nofpclass(nzero) %not.nzero1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_nzero__dynamic(
|
|
; CHECK-SAME: float nofpclass(nzero) [[NOT_NZERO0:%.*]], float nofpclass(nzero) [[NOT_NZERO1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO0]], float [[NOT_NZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero0, float %not.nzero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_pzero__dynamic(float nofpclass(pzero) %not.pzero0, float nofpclass(pzero) %not.pzero1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_pzero__dynamic(
|
|
; CHECK-SAME: float nofpclass(pzero) [[NOT_PZERO0:%.*]], float nofpclass(pzero) [[NOT_PZERO1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_PZERO0]], float [[NOT_PZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.pzero0, float %not.pzero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @lhs_not_nzero_rhs_not_pzero__dynamic(float nofpclass(nzero) %not.nzero, float nofpclass(pzero) %not.pzero) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @lhs_not_nzero_rhs_not_pzero__dynamic(
|
|
; CHECK-SAME: float nofpclass(nzero) [[NOT_NZERO:%.*]], float nofpclass(pzero) [[NOT_PZERO:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO]], float [[NOT_PZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero, float %not.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @rhs_not_nzero_lhs_not_pzero__dynamic(float nofpclass(pzero) %not.nzero, float nofpclass(nzero) %not.pzero) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @rhs_not_nzero_lhs_not_pzero__dynamic(
|
|
; CHECK-SAME: float nofpclass(pzero) [[NOT_NZERO:%.*]], float nofpclass(nzero) [[NOT_PZERO:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO]], float [[NOT_PZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero, float %not.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_nzero_nsub__dynamic(float nofpclass(nzero nsub) %not.nzero0, float nofpclass(nzero nsub) %not.nzero1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_nzero_nsub__dynamic(
|
|
; CHECK-SAME: float nofpclass(nzero nsub) [[NOT_NZERO0:%.*]], float nofpclass(nzero nsub) [[NOT_NZERO1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_NZERO0]], float [[NOT_NZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero0, float %not.nzero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @sources_not_pzero_psub__dynamic(float nofpclass(pzero psub) %not.pzero0, float nofpclass(pzero psub) %not.pzero1) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @sources_not_pzero_psub__dynamic(
|
|
; CHECK-SAME: float nofpclass(pzero psub) [[NOT_PZERO0:%.*]], float nofpclass(pzero psub) [[NOT_PZERO1:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_PZERO0]], float [[NOT_PZERO1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.pzero0, float %not.pzero1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @lhs_not_nzero_nsub_rhs_not_pzero__dynamic(float nofpclass(nzero nsub) %not.nzero, float nofpclass(pzero psub) %not.pzero) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @lhs_not_nzero_nsub_rhs_not_pzero__dynamic(
|
|
; CHECK-SAME: float nofpclass(nzero nsub) [[NOT_NZERO:%.*]], float nofpclass(pzero psub) [[NOT_PZERO:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO]], float [[NOT_PZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero, float %not.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @rhs_not_nzero_nsub_lhs_not_pzero_psub__dynamic(float nofpclass(pzero psub) %not.nzero, float nofpclass(nzero nsub) %not.pzero) #1 {
|
|
; CHECK-LABEL: define nofpclass(snan) float @rhs_not_nzero_nsub_lhs_not_pzero_psub__dynamic(
|
|
; CHECK-SAME: float nofpclass(pzero psub) [[NOT_NZERO:%.*]], float nofpclass(nzero nsub) [[NOT_PZERO:%.*]]) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[NOT_NZERO]], float [[NOT_PZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nzero, float %not.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__unknown(float nofpclass(nan) %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__unknown(
|
|
; CHECK-SAME: float nofpclass(nan) [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__not_nan(float %x, float nofpclass(nan) %y) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__not_nan(
|
|
; CHECK-SAME: float [[X:%.*]], float nofpclass(nan) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__not_nan(float nofpclass(nan) %x, float nofpclass(nan) %y) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[X:%.*]], float nofpclass(nan) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_snan__minimumnum__not_snan(float nofpclass(snan) %x, float nofpclass(snan) %y) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_snan__minimumnum__not_snan(
|
|
; CHECK-SAME: float nofpclass(snan) [[X:%.*]], float nofpclass(snan) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf) float @ret_noinf__not_qnan__minimumnum__not_qnan(float nofpclass(qnan) %x, float nofpclass(qnan) %y) {
|
|
; CHECK-LABEL: define nofpclass(inf) float @ret_noinf__not_qnan__minimumnum__not_qnan(
|
|
; CHECK-SAME: float nofpclass(qnan) [[X:%.*]], float nofpclass(qnan) [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive__minimumnum__only_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive__minimumnum__only_zero() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[KNOWN_ZERO:%.*]] = call float @returns_zero()
|
|
; CHECK-NEXT: ret float [[KNOWN_ZERO]]
|
|
;
|
|
%known.positive = call float @returns_positive()
|
|
%known.zero = call float @returns_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive, float %known.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_zero__minimumnum__known_positive() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_zero__minimumnum__known_positive() {
|
|
; CHECK-NEXT: [[KNOWN_ZERO:%.*]] = call float @returns_zero()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: ret float [[KNOWN_ZERO]]
|
|
;
|
|
%known.zero = call float @returns_zero()
|
|
%known.positive = call float @returns_positive()
|
|
%result = call float @llvm.minimumnum.f32(float %known.zero, float %known.positive)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive__minimumnum__only_zero_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive__minimumnum__only_zero_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[KNOWN_ZERO_OR_NAN:%.*]] = call float @returns_zero_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_POSITIVE]], float [[KNOWN_ZERO_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.positive = call float @returns_positive()
|
|
%known.zero.or.nan = call float @returns_zero_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive, float %known.zero.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_zero_or_nan__minimumnum__known_positive() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_zero_or_nan__minimumnum__known_positive() {
|
|
; CHECK-NEXT: [[KNOWN_ZERO_OR_NAN:%.*]] = call float @returns_zero_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_ZERO_OR_NAN]], float [[KNOWN_POSITIVE]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.zero.or.nan = call float @returns_zero_or_nan()
|
|
%known.positive = call float @returns_positive()
|
|
%result = call float @llvm.minimumnum.f32(float %known.zero.or.nan, float %known.positive)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive_or_nan__minimumnum__only_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive_or_nan__minimumnum__only_zero() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_ZERO:%.*]] = call float @returns_zero()
|
|
; CHECK-NEXT: ret float [[KNOWN_ZERO]]
|
|
;
|
|
%known.positive.or.nan = call float @returns_positive_or_nan()
|
|
%known.zero = call float @returns_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive.or.nan, float %known.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_zero__minimumnum__known_positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_zero__minimumnum__known_positive_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_ZERO:%.*]] = call float @returns_zero()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: ret float [[KNOWN_ZERO]]
|
|
;
|
|
%known.zero = call float @returns_zero()
|
|
%known.positive.or.nan = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.zero, float %known.positive.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive__minimumnum__only_nzero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive__minimumnum__only_nzero() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[KNOWN_NZERO:%.*]] = call float @returns_nzero()
|
|
; CHECK-NEXT: ret float -0.000000e+00
|
|
;
|
|
%known.positive = call float @returns_positive()
|
|
%known.nzero = call float @returns_nzero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive, float %known.nzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_nzero__minimumnum__known_positive() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_nzero__minimumnum__known_positive() {
|
|
; CHECK-NEXT: [[KNOWN_NZERO:%.*]] = call float @returns_nzero()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: ret float -0.000000e+00
|
|
;
|
|
%known.nzero = call float @returns_nzero()
|
|
%known.positive = call float @returns_positive()
|
|
%result = call float @llvm.minimumnum.f32(float %known.nzero, float %known.positive)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive__minimumnum__only_pzero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive__minimumnum__only_pzero() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[KNOWN_PZERO:%.*]] = call float @returns_pzero()
|
|
; CHECK-NEXT: ret float 0.000000e+00
|
|
;
|
|
%known.positive = call float @returns_positive()
|
|
%known.pzero = call float @returns_pzero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive, float %known.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_pzero__minimumnum__known_positive() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_pzero__minimumnum__known_positive() {
|
|
; CHECK-NEXT: [[KNOWN_PZERO:%.*]] = call float @returns_pzero()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: ret float 0.000000e+00
|
|
;
|
|
%known.pzero = call float @returns_pzero()
|
|
%known.positive = call float @returns_positive()
|
|
%result = call float @llvm.minimumnum.f32(float %known.pzero, float %known.positive)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative__minimumnum__only_zero_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative__minimumnum__only_zero_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[KNOWN_ZERO_OR_NAN:%.*]] = call float @returns_zero_or_nan()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.negative = call float @returns_negative()
|
|
%known.zero.or.nan = call float @returns_zero_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative, float %known.zero.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_zero_or_nan__minimumnum__known_negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_zero_or_nan__minimumnum__known_negative() {
|
|
; CHECK-NEXT: [[KNOWN_ZERO_OR_NAN:%.*]] = call float @returns_zero_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.zero.or.nan = call float @returns_zero_or_nan()
|
|
%known.negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %known.zero.or.nan, float %known.negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative_or_nan__minimumnum__only_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative_or_nan__minimumnum__only_zero() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_ZERO:%.*]] = call float @returns_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_NEGATIVE_OR_NAN]], float [[KNOWN_ZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%known.zero = call float @returns_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative.or.nan, float %known.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_zero__minimumnum__known_negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_zero__minimumnum__known_negative_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_ZERO:%.*]] = call float @returns_zero()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_ZERO]], float [[KNOWN_NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.zero = call float @returns_zero()
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.zero, float %known.negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative__minimumnum__only_nzero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative__minimumnum__only_nzero() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[KNOWN_NZERO:%.*]] = call float @returns_nzero()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.negative = call float @returns_negative()
|
|
%known.nzero = call float @returns_nzero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative, float %known.nzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_nzero__minimumnum__known_negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_nzero__minimumnum__known_negative() {
|
|
; CHECK-NEXT: [[KNOWN_NZERO:%.*]] = call float @returns_nzero()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.nzero = call float @returns_nzero()
|
|
%known.negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %known.nzero, float %known.negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative__minimumnum__only_nzero_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative__minimumnum__only_nzero_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[KNOWN_NZERO_OR_NAN:%.*]] = call float @returns_nzero_or_nan()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.negative = call float @returns_negative()
|
|
%known.nzero.or.nan = call float @returns_nzero_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative, float %known.nzero.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_nzero_or_nan__minimumnum__known_negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_nzero_or_nan__minimumnum__known_negative() {
|
|
; CHECK-NEXT: [[KNOWN_NZERO_OR_NAN:%.*]] = call float @returns_nzero_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.nzero.or.nan = call float @returns_nzero_or_nan()
|
|
%known.negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %known.nzero.or.nan, float %known.negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative__minimumnum__only_pzero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative__minimumnum__only_pzero() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[KNOWN_PZERO:%.*]] = call float @returns_pzero()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.negative = call float @returns_negative()
|
|
%known.pzero = call float @returns_pzero()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative, float %known.pzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_pzero__minimumnum__known_negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_pzero__minimumnum__known_negative() {
|
|
; CHECK-NEXT: [[KNOWN_PZERO:%.*]] = call float @returns_pzero()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.pzero = call float @returns_pzero()
|
|
%known.negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %known.pzero, float %known.negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_negative__minimumnum__only_pzero_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_negative__minimumnum__only_pzero_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[KNOWN_PZERO_OR_NAN:%.*]] = call float @returns_pzero_or_nan()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.negative = call float @returns_negative()
|
|
%known.pzero.or.nan = call float @returns_pzero_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative, float %known.pzero.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @only_pzero_or_nan__minimumnum__known_negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @only_pzero_or_nan__minimumnum__known_negative() {
|
|
; CHECK-NEXT: [[KNOWN_PZERO_OR_NAN:%.*]] = call float @returns_pzero_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[KNOWN_NEGATIVE]]
|
|
;
|
|
%known.pzero.or.nan = call float @returns_pzero_or_nan()
|
|
%known.negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %known.pzero.or.nan, float %known.negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(pinf pnorm psub pzero) float @ret_always_negative_or_nan__unknown__minimumnum__select_always_negative_or_unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_always_negative_or_nan__unknown__minimumnum__select_always_negative_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.rhs = select i1 %cond, float %always.negative, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(pinf pnorm psub pzero) float @ret_always_negative_or_nan__unknown__minimumnum__select_always_positive_or_unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_always_negative_or_nan__unknown__minimumnum__select_always_positive_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_POSITIVE]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.positive = call float @returns_positive()
|
|
%select.rhs = select i1 %cond, float %always.positive, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(pinf pnorm psub) float @ret_always_positive_nonzero__minimumnum__not_zero_select_positive_or_unknown(i1 %cond, float %unknown, float nofpclass(zero) %not.zero) {
|
|
; CHECK-LABEL: define nofpclass(pinf psub pnorm) float @ret_always_positive_nonzero__minimumnum__not_zero_select_positive_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_POSITIVE]], float [[UNKNOWN]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.positive = call float @returns_positive()
|
|
%select.rhs = select i1 %cond, float %always.positive, float %unknown
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(pinf pnorm psub) float @ret_always_positive_nonzero__minimumnum__not_zero_select_negative_or_unknown(i1 %cond, float %unknown, float nofpclass(zero) %not.zero) {
|
|
; CHECK-LABEL: define nofpclass(pinf psub pnorm) float @ret_always_positive_nonzero__minimumnum__not_zero_select_negative_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(zero) [[NOT_ZERO:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NEGATIVE]], float [[UNKNOWN]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_ZERO]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.negative = call float @returns_negative()
|
|
%select.rhs = select i1 %cond, float %always.negative, float %unknown
|
|
%result = call float @llvm.minimumnum.f32(float %not.zero, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_positive__minimumnum__only_pzero_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_positive__minimumnum__only_pzero_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[KNOWN_PZERO_OR_NAN:%.*]] = call float @returns_pzero_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[KNOWN_POSITIVE]], float [[KNOWN_PZERO_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.positive = call float @returns_positive()
|
|
%known.pzero.or.nan = call float @returns_pzero_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive, float %known.pzero.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_nonan__known_negative_or_nan__minimumnum__known_positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_nonan__known_negative_or_nan__minimumnum__known_positive_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[MUST_BE_NEGATIVE_OR_NAN]], float [[MUST_BE_POSITIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.negative.or.nan = call float @returns_negative_or_nan()
|
|
%must.be.positive.or.nan = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.negative.or.nan, float %must.be.positive.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_nonan__known_positive_or_nan__minimumnum__known_negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_nonan__known_positive_or_nan__minimumnum__known_negative_or_nan() {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[MUST_BE_POSITIVE_OR_NAN]], float [[MUST_BE_NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.positive.or.nan = call float @returns_positive_or_nan()
|
|
%must.be.negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.positive.or.nan, float %must.be.negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_nonan__select_nan_or_unknown__minimumnum__unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_nonan__select_nan_or_unknown__minimumnum__unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NAN:%.*]] = call float @returns_nan()
|
|
; CHECK-NEXT: [[SELECT_LHS:%.*]] = select i1 [[COND]], float [[ALWAYS_NAN]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT_LHS]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.nan = call float @returns_nan()
|
|
%select.lhs = select i1 %cond, float %always.nan, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %select.lhs, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_nonan__unknown__minimumnum__select_nan_or_unknown(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_nonan__unknown__minimumnum__select_nan_or_unknown(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[ALWAYS_NAN:%.*]] = call float @returns_nan()
|
|
; CHECK-NEXT: [[SELECT_RHS:%.*]] = select i1 [[COND]], float [[UNKNOWN0]], float [[ALWAYS_NAN]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT_RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%always.nan = call float @returns_nan()
|
|
%select.rhs = select i1 %cond, float %unknown0, float %always.nan
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select.rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero) float @result_known_positive_or_nan__known_positive__minimumnum__not_nan(float nofpclass(ninf nnorm nsub nzero) %lhs, float nofpclass(nan) %rhs) {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @result_known_positive_or_nan__known_positive__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(ninf nzero nsub nnorm) [[LHS:%.*]], float nofpclass(nan) [[RHS:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[LHS]], float [[RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %lhs, float %rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(ninf nnorm nsub nzero) float @result_known_positive_or_nan__not_nan__minimumnum__known_positive(float nofpclass(nan) %lhs, float nofpclass(ninf nnorm nsub nzero) %rhs) {
|
|
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @result_known_positive_or_nan__not_nan__minimumnum__known_positive(
|
|
; CHECK-SAME: float nofpclass(nan) [[LHS:%.*]], float nofpclass(ninf nzero nsub nnorm) [[RHS:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[LHS]], float [[RHS]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %lhs, float %rhs)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_always_positive__minimumnum__known_always_negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_always_positive__minimumnum__known_always_negative_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_POSITIVE]], float [[KNOWN_NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.positive = call float @returns_positive()
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive, float %known.negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_always_negative_or_nan__minimumnum__known_always_positive() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_always_negative_or_nan__minimumnum__known_always_positive() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_NEGATIVE_OR_NAN]], float [[KNOWN_POSITIVE]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%known.positive = call float @returns_positive()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative.or.nan, float %known.positive)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_always_positive_or_nan__minimumnum__known_always_negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_always_positive_or_nan__minimumnum__known_always_negative_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_POSITIVE_OR_NAN]], float [[KNOWN_NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.positive.or.nan = call float @returns_positive_or_nan()
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive.or.nan, float %known.negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_always_negative_or_nan__minimumnum__known_always_positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_always_negative_or_nan__minimumnum__known_always_positive_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_NEGATIVE_OR_NAN]], float [[KNOWN_POSITIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%known.positive.or.nan = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative.or.nan, float %known.positive.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_no_nan__known_always_positive_or_nan__minimumnum__known_always_negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__known_always_positive_or_nan__minimumnum__known_always_negative_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_POSITIVE_OR_NAN]], float [[KNOWN_NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.positive.or.nan = call float @returns_positive_or_nan()
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.positive.or.nan, float %known.negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_no_nan__known_always_negative_or_nan__minimumnum__known_always_positive_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nan__known_always_negative_or_nan__minimumnum__known_always_positive_or_nan() {
|
|
; CHECK-NEXT: [[KNOWN_NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[KNOWN_POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[KNOWN_NEGATIVE_OR_NAN]], float [[KNOWN_POSITIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%known.negative.or.nan = call float @returns_negative_or_nan()
|
|
%known.positive.or.nan = call float @returns_positive_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %known.negative.or.nan, float %known.positive.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @pinf__minimumnum__unknown(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @pinf__minimumnum__unknown(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF:%.*]] = call float @returns_pinf()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float 0x7FF0000000000000)
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%pinf = call float @returns_pinf()
|
|
%result = call float @llvm.minimumnum.f32(float %pinf, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__pinf(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__pinf(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF:%.*]] = call float @returns_pinf()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float 0x7FF0000000000000)
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%pinf = call float @returns_pinf()
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %pinf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @pinf_or_nan__minimumnum__unknown(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @pinf_or_nan__minimumnum__unknown(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF_OR_NAN:%.*]] = call float @returns_pinf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[PINF_OR_NAN]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%pinf.or.nan = call float @returns_pinf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %pinf.or.nan, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__pinf_or_nan(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__pinf_or_nan(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF_OR_NAN:%.*]] = call float @returns_pinf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[PINF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%pinf.or.nan = call float @returns_pinf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %pinf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @ninf__minimumnum__unknown(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @ninf__minimumnum__unknown(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF:%.*]] = call float @returns_ninf()
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%ninf = call float @returns_ninf()
|
|
%result = call float @llvm.minimumnum.f32(float %ninf, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__ninf(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__ninf(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF:%.*]] = call float @returns_ninf()
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%ninf = call float @returns_ninf()
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %ninf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @ninf_or_nan__minimumnum__unknown(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @ninf_or_nan__minimumnum__unknown(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF_OR_NAN:%.*]] = call float @returns_ninf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NINF_OR_NAN]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%ninf.or.nan = call float @returns_ninf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %ninf.or.nan, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__ninf_or_nan(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__ninf_or_nan(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF_OR_NAN:%.*]] = call float @returns_ninf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[NINF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%ninf.or.nan = call float @returns_ninf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %ninf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @inf__minimumnum__unknown(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @inf__minimumnum__unknown(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[INF]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf = call float @returns_inf()
|
|
%result = call float @llvm.minimumnum.f32(float %inf, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__inf(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__inf(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[INF:%.*]] = call float @returns_inf()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[INF]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf = call float @returns_inf()
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %inf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @inf_or_nan__minimumnum__unknown(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @inf_or_nan__minimumnum__unknown(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call float @returns_inf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[INF_OR_NAN]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf.or.nan = call float @returns_inf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %inf.or.nan, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__minimumnum__inf_or_nan(float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__minimumnum__inf_or_nan(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call float @returns_inf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[INF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf.or.nan = call float @returns_inf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %unknown, float %inf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @ninf_or_nan__minimumnum__not_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @ninf_or_nan__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF_OR_NAN:%.*]] = call float @returns_ninf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NINF_OR_NAN]], float [[NOT_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%ninf.or.nan = call float @returns_ninf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %ninf.or.nan, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__ninf_or_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__ninf_or_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF_OR_NAN:%.*]] = call float @returns_ninf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_NAN]], float [[NINF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%ninf.or.nan = call float @returns_ninf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %ninf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @pinf_or_nan__minimumnum__not_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @pinf_or_nan__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF_OR_NAN:%.*]] = call float @returns_pinf_or_nan()
|
|
; CHECK-NEXT: ret float [[NOT_NAN]]
|
|
;
|
|
%pinf.or.nan = call float @returns_pinf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %pinf.or.nan, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__pinf_or_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__pinf_or_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF_OR_NAN:%.*]] = call float @returns_pinf_or_nan()
|
|
; CHECK-NEXT: ret float [[NOT_NAN]]
|
|
;
|
|
%pinf.or.nan = call float @returns_pinf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %pinf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @inf_or_nan__minimumnum__not_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @inf_or_nan__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call float @returns_inf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[INF_OR_NAN]], float [[NOT_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf.or.nan = call float @returns_inf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %inf.or.nan, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__inf_or_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__inf_or_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call float @returns_inf_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NOT_NAN]], float [[INF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf.or.nan = call float @returns_inf_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %inf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @ninf__minimumnum__not_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @ninf__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF_OR_NAN:%.*]] = call float @returns_ninf()
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%ninf.or.nan = call float @returns_ninf()
|
|
%result = call float @llvm.minimumnum.f32(float %ninf.or.nan, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__ninf(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__ninf(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[NINF_OR_NAN:%.*]] = call float @returns_ninf()
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%ninf.or.nan = call float @returns_ninf()
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %ninf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @pinf__minimumnum__not_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @pinf__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF_OR_NAN:%.*]] = call float @returns_pinf()
|
|
; CHECK-NEXT: ret float [[NOT_NAN]]
|
|
;
|
|
%pinf.or.nan = call float @returns_pinf()
|
|
%result = call float @llvm.minimumnum.f32(float %pinf.or.nan, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__pinf(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__pinf(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[PINF_OR_NAN:%.*]] = call float @returns_pinf()
|
|
; CHECK-NEXT: ret float [[NOT_NAN]]
|
|
;
|
|
%pinf.or.nan = call float @returns_pinf()
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %pinf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @inf__minimumnum__not_nan(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @inf__minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call float @returns_inf()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan nsz float @llvm.minimumnum.f32(float [[INF_OR_NAN]], float [[NOT_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf.or.nan = call float @returns_inf()
|
|
%result = call float @llvm.minimumnum.f32(float %inf.or.nan, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum__inf(float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum__inf(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[INF_OR_NAN:%.*]] = call float @returns_inf()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan nsz float @llvm.minimumnum.f32(float [[NOT_NAN]], float [[INF_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%inf.or.nan = call float @returns_inf()
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan, float %inf.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(nan) float @ret_no_nans__noundef_call_attr(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(nan) float @ret_no_nans__noundef_call_attr(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__noundef_minimumnum__unknown(float nofpclass(nan) %not.nan, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__noundef_minimumnum__unknown(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[NOT_NAN]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %not.nan, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__noundef_minimumnum__not_nan(float %unknown, float nofpclass(nan) %not.nan) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__noundef_minimumnum__not_nan(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[NOT_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %unknown, float %not.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__noundef_minimumnum__not_nan(float nofpclass(nan) %not.nan0, float nofpclass(nan) %not.nan1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__noundef_minimumnum__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN0:%.*]], float nofpclass(nan) [[NOT_NAN1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %not.nan0, float %not.nan1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_inf__noundef_minimumnum__unknown(float nofpclass(inf) %not.inf, float %unknown) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_inf__noundef_minimumnum__unknown(
|
|
; CHECK-SAME: float nofpclass(inf) [[NOT_INF:%.*]], float [[UNKNOWN:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[NOT_INF]], float [[UNKNOWN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %not.inf, float %unknown)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @unknown__noundef_minimumnum__not_inf(float %unknown, float nofpclass(inf) %not.inf) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @unknown__noundef_minimumnum__not_inf(
|
|
; CHECK-SAME: float [[UNKNOWN:%.*]], float nofpclass(inf) [[NOT_INF:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[UNKNOWN]], float [[NOT_INF]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %unknown, float %not.inf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_snan__noundef_minimumnum__not_inf(float nofpclass(inf) %not.inf0, float nofpclass(inf) %not.inf1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_snan__noundef_minimumnum__not_inf(
|
|
; CHECK-SAME: float nofpclass(inf) [[NOT_INF0:%.*]], float nofpclass(inf) [[NOT_INF1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[NOT_INF0]], float [[NOT_INF1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %not.inf0, float %not.inf1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf) float @ret_no_infs_noundef_call_attr(float %x, float %y) {
|
|
; CHECK-LABEL: define nofpclass(inf) float @ret_no_infs_noundef_call_attr(
|
|
; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[X]], float [[Y]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %x, float %y)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(inf) float @not_inf__noundef_minimumnum__not_inf(float nofpclass(inf) %not.inf0, float nofpclass(inf) %not.inf1) {
|
|
; CHECK-LABEL: define nofpclass(inf) float @not_inf__noundef_minimumnum__not_inf(
|
|
; CHECK-SAME: float nofpclass(inf) [[NOT_INF0:%.*]], float nofpclass(inf) [[NOT_INF1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call noundef float @llvm.minimumnum.f32(float [[NOT_INF0]], float [[NOT_INF1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call noundef float @llvm.minimumnum.f32(float %not.inf0, float %not.inf1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @not_nan__minimumnum_noundef_md__not_nan(float nofpclass(nan) %not.nan0, float nofpclass(nan) %not.nan1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @not_nan__minimumnum_noundef_md__not_nan(
|
|
; CHECK-SAME: float nofpclass(nan) [[NOT_NAN0:%.*]], float nofpclass(nan) [[NOT_NAN1:%.*]]) {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[NOT_NAN0]], float [[NOT_NAN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%result = call float @llvm.minimumnum.f32(float %not.nan0, float %not.nan1), !noundef !0, !unknown.md !0
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_0(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_0(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[NNORM:%.*]] = call float @returns_nnorm()
|
|
; CHECK-NEXT: ret float [[NNORM]]
|
|
;
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%nnorm = call float @returns_nnorm()
|
|
%result = call float @llvm.minimumnum.f32(float %select, float %nnorm)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_1(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_1(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[NNORM:%.*]] = call float @returns_nnorm()
|
|
; CHECK-NEXT: ret float [[NNORM]]
|
|
;
|
|
%nnorm = call float @returns_nnorm()
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%result = call float @llvm.minimumnum.f32(float %nnorm, float %select)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_or_nan_0(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_or_nan_0(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[IS_POS_OR_ZERO:%.*]] = fcmp oge float [[ARG]], 0.000000e+00
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_POS_OR_ZERO]], float [[ARG]], float 0.000000e+00
|
|
; CHECK-NEXT: [[NNORM_OR_NAN:%.*]] = call float @returns_nnorm_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[SELECT]], float [[NNORM_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%nnorm.or.nan = call float @returns_nnorm_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %select, float %nnorm.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_or_nan_1(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @select_is_positive_or_0__minimumnum__nnorm_or_nan_1(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[NNORM_OR_NAN:%.*]] = call float @returns_nnorm_or_nan()
|
|
; CHECK-NEXT: [[IS_POS_OR_ZERO:%.*]] = fcmp oge float [[ARG]], 0.000000e+00
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_POS_OR_ZERO]], float [[ARG]], float 0.000000e+00
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NNORM_OR_NAN]], float [[SELECT]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%nnorm.or.nan = call float @returns_nnorm_or_nan()
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%result = call float @llvm.minimumnum.f32(float %nnorm.or.nan, float %select)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @select_is_positive_or_0__minimumnum__negative(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @select_is_positive_or_0__minimumnum__negative(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %select, float %negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative__minimumnum__select_is_positive_or_0(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative__minimumnum__select_is_positive_or_0(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%negative = call float @returns_negative()
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%result = call float @llvm.minimumnum.f32(float %negative, float %select)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @select_is_positive_or_0__minimumnum__negative_or_zero(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @select_is_positive_or_0__minimumnum__negative_or_zero(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[IS_POS_OR_ZERO:%.*]] = fcmp oge float [[ARG]], 0.000000e+00
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_POS_OR_ZERO]], float [[ARG]], float 0.000000e+00
|
|
; CHECK-NEXT: [[NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[SELECT]], float [[NEGATIVE_OR_ZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%negative.or.zero = call float @returns_negative_or_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %select, float %negative.or.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative_or_zero__minimumnum__select_is_positive_or_0(float noundef %arg) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative_or_zero__minimumnum__select_is_positive_or_0(
|
|
; CHECK-SAME: float noundef [[ARG:%.*]]) {
|
|
; CHECK-NEXT: [[NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[IS_POS_OR_ZERO:%.*]] = fcmp oge float [[ARG]], 0.000000e+00
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_POS_OR_ZERO]], float [[ARG]], float 0.000000e+00
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nnan float @llvm.minimumnum.f32(float [[NEGATIVE_OR_ZERO]], float [[SELECT]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%negative.or.zero = call float @returns_negative_or_zero()
|
|
%is.pos.or.zero = fcmp oge float %arg, 0.0
|
|
%select = select i1 %is.pos.or.zero, float %arg, float 0.0
|
|
%result = call float @llvm.minimumnum.f32(float %negative.or.zero, float %select)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative_or_zero__minimumnum__positive() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative_or_zero__minimumnum__positive() {
|
|
; CHECK-NEXT: [[NEG_NONZERO:%.*]] = call float @returns_negative_nonzero()
|
|
; CHECK-NEXT: [[POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: ret float [[NEG_NONZERO]]
|
|
;
|
|
%neg.nonzero = call float @returns_negative_nonzero()
|
|
%positive = call float @returns_positive()
|
|
%result = call float @llvm.minimumnum.f32(float %neg.nonzero, float %positive)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @positive__minimumnum__negative_or_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @positive__minimumnum__negative_or_zero() {
|
|
; CHECK-NEXT: [[POSITIVE:%.*]] = call float @returns_positive()
|
|
; CHECK-NEXT: [[NEG_NONZERO:%.*]] = call float @returns_negative_nonzero()
|
|
; CHECK-NEXT: ret float [[NEG_NONZERO]]
|
|
;
|
|
%positive = call float @returns_positive()
|
|
%neg.nonzero = call float @returns_negative_nonzero()
|
|
%result = call float @llvm.minimumnum.f32(float %positive, float %neg.nonzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative_or_zero__minimumnum__positive_or_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative_or_zero__minimumnum__positive_or_zero() {
|
|
; CHECK-NEXT: [[NEG_NONZERO:%.*]] = call float @returns_negative_nonzero()
|
|
; CHECK-NEXT: [[POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: ret float [[NEG_NONZERO]]
|
|
;
|
|
%neg.nonzero = call float @returns_negative_nonzero()
|
|
%positive.or.zero = call float @returns_positive_or_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %neg.nonzero, float %positive.or.zero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @positive_or_zero__minimumnum__negative_or_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @positive_or_zero__minimumnum__negative_or_zero() {
|
|
; CHECK-NEXT: [[POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[NEG_NONZERO:%.*]] = call float @returns_negative_nonzero()
|
|
; CHECK-NEXT: ret float [[NEG_NONZERO]]
|
|
;
|
|
%positive.or.zero = call float @returns_positive_or_zero()
|
|
%neg.nonzero = call float @returns_negative_nonzero()
|
|
%result = call float @llvm.minimumnum.f32(float %positive.or.zero, float %neg.nonzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @positive_or_zero__minimumnum__negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @positive_or_zero__minimumnum__negative() {
|
|
; CHECK-NEXT: [[POS_NONZERO:%.*]] = call float @returns_positive_nonzero()
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%pos.nonzero = call float @returns_positive_nonzero()
|
|
%negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %pos.nonzero, float %negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative__minimumnum__positive_or_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative__minimumnum__positive_or_zero() {
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[POS_NONZERO:%.*]] = call float @returns_positive_nonzero()
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%negative = call float @returns_negative()
|
|
%pos.nonzero = call float @returns_positive_nonzero()
|
|
%result = call float @llvm.minimumnum.f32(float %negative, float %pos.nonzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @positive_or_zero__minimumnum__negative_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @positive_or_zero__minimumnum__negative_or_nan() {
|
|
; CHECK-NEXT: [[POS_NONZERO:%.*]] = call float @returns_positive_nonzero()
|
|
; CHECK-NEXT: [[NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[POS_NONZERO]], float [[NEGATIVE_OR_NAN]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%pos.nonzero = call float @returns_positive_nonzero()
|
|
%negative.or.nan = call float @returns_negative_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %pos.nonzero, float %negative.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative_or_nan__minimumnum__positive_or_zero() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative_or_nan__minimumnum__positive_or_zero() {
|
|
; CHECK-NEXT: [[NEGATIVE_OR_NAN:%.*]] = call float @returns_negative_or_nan()
|
|
; CHECK-NEXT: [[POS_NONZERO:%.*]] = call float @returns_positive_nonzero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[NEGATIVE_OR_NAN]], float [[POS_NONZERO]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%negative.or.nan = call float @returns_negative_or_nan()
|
|
%pos.nonzero = call float @returns_positive_nonzero()
|
|
%result = call float @llvm.minimumnum.f32(float %negative.or.nan, float %pos.nonzero)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @positive_or_zero_or_nan__minimumnum__negative() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @positive_or_zero_or_nan__minimumnum__negative() {
|
|
; CHECK-NEXT: [[POS_NONZERO_OR_NAN:%.*]] = call float @returns_positive_nonzero_or_nan()
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%pos.nonzero.or.nan = call float @returns_positive_nonzero_or_nan()
|
|
%negative = call float @returns_negative()
|
|
%result = call float @llvm.minimumnum.f32(float %pos.nonzero.or.nan, float %negative)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @negative__minimumnum__positive_or_zero_or_nan() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @negative__minimumnum__positive_or_zero_or_nan() {
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[POS_NONZERO_OR_NAN:%.*]] = call float @returns_positive_nonzero_or_nan()
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%negative = call float @returns_negative()
|
|
%pos.nonzero.or.nan = call float @returns_positive_nonzero_or_nan()
|
|
%result = call float @llvm.minimumnum.f32(float %negative, float %pos.nonzero.or.nan)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_pnorm__minimumnum__known_psub() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_pnorm__minimumnum__known_psub() {
|
|
; CHECK-NEXT: [[PNORM:%.*]] = call float @returns_pnorm()
|
|
; CHECK-NEXT: [[PSUB:%.*]] = call float @returns_psub()
|
|
; CHECK-NEXT: ret float [[PSUB]]
|
|
;
|
|
%pnorm = call float @returns_pnorm()
|
|
%psub = call float @returns_psub()
|
|
%result = call float @llvm.minimumnum.f32(float %pnorm, float %psub)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_psub__minimumnum__known_pnorm() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_psub__minimumnum__known_pnorm() {
|
|
; CHECK-NEXT: [[PSUB:%.*]] = call float @returns_psub()
|
|
; CHECK-NEXT: [[PNORM:%.*]] = call float @returns_pnorm()
|
|
; CHECK-NEXT: ret float [[PSUB]]
|
|
;
|
|
%psub = call float @returns_psub()
|
|
%pnorm = call float @returns_pnorm()
|
|
%result = call float @llvm.minimumnum.f32(float %psub, float %pnorm)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_pinf__minimumnum__known_psub() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_pinf__minimumnum__known_psub() {
|
|
; CHECK-NEXT: [[PINF:%.*]] = call float @returns_pinf()
|
|
; CHECK-NEXT: [[PSUB:%.*]] = call float @returns_psub()
|
|
; CHECK-NEXT: ret float [[PSUB]]
|
|
;
|
|
%pinf = call float @returns_pinf()
|
|
%psub = call float @returns_psub()
|
|
%result = call float @llvm.minimumnum.f32(float %pinf, float %psub)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_psub__minimumnum__known_pinf() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_psub__minimumnum__known_pinf() {
|
|
; CHECK-NEXT: [[PSUB:%.*]] = call float @returns_psub()
|
|
; CHECK-NEXT: [[PINF:%.*]] = call float @returns_pinf()
|
|
; CHECK-NEXT: ret float [[PSUB]]
|
|
;
|
|
%psub = call float @returns_psub()
|
|
%pinf = call float @returns_pinf()
|
|
%result = call float @llvm.minimumnum.f32(float %psub, float %pinf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_nnorm__minimumnum__known_nsub() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_nnorm__minimumnum__known_nsub() {
|
|
; CHECK-NEXT: [[NNORM:%.*]] = call float @returns_nnorm()
|
|
; CHECK-NEXT: [[NSUB:%.*]] = call float @returns_nsub()
|
|
; CHECK-NEXT: ret float [[NNORM]]
|
|
;
|
|
%nnorm = call float @returns_nnorm()
|
|
%nsub = call float @returns_nsub()
|
|
%result = call float @llvm.minimumnum.f32(float %nnorm, float %nsub)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_nsub__minimumnum__known_nnorm() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_nsub__minimumnum__known_nnorm() {
|
|
; CHECK-NEXT: [[NSUB:%.*]] = call float @returns_nsub()
|
|
; CHECK-NEXT: [[NNORM:%.*]] = call float @returns_nnorm()
|
|
; CHECK-NEXT: ret float [[NNORM]]
|
|
;
|
|
%nsub = call float @returns_nsub()
|
|
%nnorm = call float @returns_nnorm()
|
|
%result = call float @llvm.minimumnum.f32(float %nsub, float %nnorm)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_ninf__minimumnum__known_nsub() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_ninf__minimumnum__known_nsub() {
|
|
; CHECK-NEXT: [[NINF:%.*]] = call float @returns_ninf()
|
|
; CHECK-NEXT: [[NSUB:%.*]] = call float @returns_nsub()
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%ninf = call float @returns_ninf()
|
|
%nsub = call float @returns_nsub()
|
|
%result = call float @llvm.minimumnum.f32(float %ninf, float %nsub)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @known_nsub__minimumnum__known_ninf() {
|
|
; CHECK-LABEL: define nofpclass(snan) float @known_nsub__minimumnum__known_ninf() {
|
|
; CHECK-NEXT: [[NSUB:%.*]] = call float @returns_nsub()
|
|
; CHECK-NEXT: [[NINF:%.*]] = call float @returns_ninf()
|
|
; CHECK-NEXT: ret float 0xFFF0000000000000
|
|
;
|
|
%nsub = call float @returns_nsub()
|
|
%ninf = call float @returns_ninf()
|
|
%result = call float @llvm.minimumnum.f32(float %nsub, float %ninf)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @simplify_multiple_use_minimumnum(ptr %ptr) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @simplify_multiple_use_minimumnum(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minimumnum.f32(float [[POSITIVE_OR_NAN]], float [[NEGATIVE]])
|
|
; CHECK-NEXT: store float [[MIN]], ptr [[PTR]], align 4
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%positive.or.nan = call float @returns_positive_or_nan()
|
|
%negative = call float @returns_negative()
|
|
%min = call float @llvm.minimumnum.f32(float %positive.or.nan, float %negative)
|
|
store float %min, ptr %ptr
|
|
ret float %min
|
|
}
|
|
|
|
define nofpclass(snan) float @simplify_multiple_use_minimumnum_commute(ptr %ptr) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @simplify_multiple_use_minimumnum_commute(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[POSITIVE_OR_NAN:%.*]] = call float @returns_positive_or_nan()
|
|
; CHECK-NEXT: [[NEGATIVE:%.*]] = call float @returns_negative()
|
|
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minimumnum.f32(float [[NEGATIVE]], float [[POSITIVE_OR_NAN]])
|
|
; CHECK-NEXT: store float [[MIN]], ptr [[PTR]], align 4
|
|
; CHECK-NEXT: ret float [[NEGATIVE]]
|
|
;
|
|
%positive.or.nan = call float @returns_positive_or_nan()
|
|
%negative = call float @returns_negative()
|
|
%min = call float @llvm.minimumnum.f32(float %negative, float %positive.or.nan)
|
|
store float %min, ptr %ptr
|
|
ret float %min
|
|
}
|
|
|
|
define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0__multiple_use(ptr %ptr) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_0__multiple_use(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]])
|
|
; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.negative.or.zero = call float @returns_negative_or_zero()
|
|
%must.be.positive.or.zero = call float @returns_positive_or_zero()
|
|
%result = call nsz float @llvm.minimumnum.f32(float %must.be.negative.or.zero, float %must.be.positive.or.zero)
|
|
store float %result, ptr %ptr
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1__multiple_use(ptr %ptr) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @nsz_fold_negative_or_zero__positive_or_zero_1__multiple_use(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call nsz float @llvm.minimumnum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]])
|
|
; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.positive.or.zero = call float @returns_positive_or_zero()
|
|
%must.be.negative.or.zero = call float @returns_negative_or_zero()
|
|
%result = call nsz float @llvm.minimumnum.f32(float %must.be.positive.or.zero, float %must.be.negative.or.zero)
|
|
store float %result, ptr %ptr
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_0__multiple_use(ptr %ptr) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_0__multiple_use(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[MUST_BE_NEGATIVE_OR_ZERO]], float [[MUST_BE_POSITIVE_OR_ZERO]])
|
|
; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.negative.or.zero = call float @returns_negative_or_zero()
|
|
%must.be.positive.or.zero = call float @returns_positive_or_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.negative.or.zero, float %must.be.positive.or.zero)
|
|
store float %result, ptr %ptr
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__multiple_use(ptr %ptr) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @cannot_fold_negative_or_zero__positive_or_zero_1__multiple_use(
|
|
; CHECK-SAME: ptr [[PTR:%.*]]) {
|
|
; CHECK-NEXT: [[MUST_BE_POSITIVE_OR_ZERO:%.*]] = call float @returns_positive_or_zero()
|
|
; CHECK-NEXT: [[MUST_BE_NEGATIVE_OR_ZERO:%.*]] = call float @returns_negative_or_zero()
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[MUST_BE_POSITIVE_OR_ZERO]], float [[MUST_BE_NEGATIVE_OR_ZERO]])
|
|
; CHECK-NEXT: store float [[RESULT]], ptr [[PTR]], align 4
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%must.be.positive.or.zero = call float @returns_positive_or_zero()
|
|
%must.be.negative.or.zero = call float @returns_negative_or_zero()
|
|
%result = call float @llvm.minimumnum.f32(float %must.be.positive.or.zero, float %must.be.negative.or.zero)
|
|
store float %result, ptr %ptr
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @qnan_result_demands_snan_lhs(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_lhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SNAN:%.*]] = call float @returns_snan()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[SELECT]], float [[UNKNOWN1]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%snan = call float @returns_snan()
|
|
%select = select i1 %cond, float %snan, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %select, float %unknown1)
|
|
ret float %result
|
|
}
|
|
|
|
define nofpclass(snan) float @qnan_result_demands_snan_rhs(i1 %cond, float %unknown0, float %unknown1) {
|
|
; CHECK-LABEL: define nofpclass(snan) float @qnan_result_demands_snan_rhs(
|
|
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN0:%.*]], float [[UNKNOWN1:%.*]]) {
|
|
; CHECK-NEXT: [[SNAN:%.*]] = call float @returns_snan()
|
|
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[SNAN]], float [[UNKNOWN0]]
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call float @llvm.minimumnum.f32(float [[UNKNOWN1]], float [[SELECT]])
|
|
; CHECK-NEXT: ret float [[RESULT]]
|
|
;
|
|
%snan = call float @returns_snan()
|
|
%select = select i1 %cond, float %snan, float %unknown0
|
|
%result = call float @llvm.minimumnum.f32(float %unknown1, float %select)
|
|
ret float %result
|
|
}
|
|
|
|
!0 = !{}
|
|
|
|
attributes #0 = { denormal_fpenv(preservesign) }
|
|
attributes #1 = { denormal_fpenv(dynamic) }
|