llvm/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt -S -passes=attributor -attributor-manifest-internal < %s | FileCheck %s --check-prefixes=CHECK,TUNIT

declare float @llvm.fabs.f32(float)
declare float @llvm.copysign.f32(float, float)
declare void @llvm.assume(i1 noundef)

;---------------------------------------------------------------------
; compare > < to normal constant
;---------------------------------------------------------------------

; can't be +inf
define float @clamp_is_ogt_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_ogt_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT:    [[IS_OGT_1:%.*]] = fcmp ogt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ogt.1 = fcmp ogt float %arg, 1.0
  %select = select i1 %is.ogt.1, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_ogt_1_to_1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_ogt_1_to_1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULE_1:%.*]] = fcmp ule float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULE_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ule.1 = fcmp ule float %arg, 1.0
  %select = select i1 %is.ule.1, float %arg, float 1.0
  ret float %select
}

; can't be +inf or nan
define float @clamp_is_ugt_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf) float @clamp_is_ugt_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_1:%.*]] = fcmp ugt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.1 = fcmp ugt float %arg, 1.0
  %select = select i1 %is.ugt.1, float 1.0, float %arg
  ret float %select
}

; can't be +inf or nan
define float @clamp_is_ugt_1_to_1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf) float @clamp_is_ugt_1_to_1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLE_1:%.*]] = fcmp ole float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ole.1 = fcmp ole float %arg, 1.0
  %select = select i1 %is.ole.1, float %arg, float 1.0
  ret float %select
}

; can't be +inf
define float @clamp_is_oge_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_oge_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGE_1:%.*]] = fcmp oge float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oge.1 = fcmp oge float %arg, 1.0
  %select = select i1 %is.oge.1, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_oge_1_to_1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_oge_1_to_1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULT_1:%.*]] = fcmp ult float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ult.1 = fcmp ult float %arg, 1.0
  %select = select i1 %is.ult.1, float %arg, float 1.0
  ret float %select
}

; can't be +inf or nan
define float @clamp_is_uge_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf) float @clamp_is_uge_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_1:%.*]] = fcmp uge float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.1 = fcmp uge float %arg, 1.0
  %select = select i1 %is.ugt.1, float 1.0, float %arg
  ret float %select
}

; can't be negative, zero, or denormal
define float @clamp_is_olt_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(ninf zero sub nnorm) float @clamp_is_olt_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLT_1:%.*]] = fcmp olt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.olt.1 = fcmp olt float %arg, 1.0
  %select = select i1 %is.olt.1, float 1.0, float %arg
  ret float %select
}

; can't be negative, zero, or denormal
define float @clamp_is_olt_1_to_1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(ninf zero sub nnorm) float @clamp_is_olt_1_to_1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGE_1:%.*]] = fcmp uge float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGE_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.uge.1 = fcmp uge float %arg, 1.0
  %select = select i1 %is.uge.1, float %arg, float 1.0
  ret float %select
}

; can't be negative or zero, nan or denormal
define float @clamp_is_ult_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf zero sub nnorm) float @clamp_is_ult_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULT_1:%.*]] = fcmp ult float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ult.1 = fcmp ult float %arg, 1.0
  %select = select i1 %is.ult.1, float 1.0, float %arg
  ret float %select
}

; can't be negative or zero, nan or denormal
define float @clamp_is_ult_1_to_1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf zero sub nnorm) float @clamp_is_ult_1_to_1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGE_1:%.*]] = fcmp oge float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oge.1 = fcmp oge float %arg, 1.0
  %select = select i1 %is.oge.1, float %arg, float 1.0
  ret float %select
}

; can't be negative, zero or denormal
define float @clamp_is_ole_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(ninf zero sub nnorm) float @clamp_is_ole_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLE_1:%.*]] = fcmp ole float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ole.1 = fcmp ole float %arg, 1.0
  %select = select i1 %is.ole.1, float 1.0, float %arg
  ret float %select
}

; can't be negative or zero, nan or denormal
define float @clamp_is_ule_1_to_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf zero sub nnorm) float @clamp_is_ule_1_to_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULE_1:%.*]] = fcmp ule float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULE_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ule.1 = fcmp ule float %arg, 1.0
  %select = select i1 %is.ule.1, float 1.0, float %arg
  ret float %select
}

; can't be negative or denormal
define float @clamp_is_olt_1_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @clamp_is_olt_1_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLT_1:%.*]] = fcmp olt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.olt.1 = fcmp olt float %arg, 1.0
  %select = select i1 %is.olt.1, float 0.0, float %arg
  ret float %select
}

; can't be negative, nan or denormal
define float @clamp_is_ult_1_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @clamp_is_ult_1_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULT_1:%.*]] = fcmp olt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ult.1 = fcmp olt float %arg, 1.0
  %select = select i1 %is.ult.1, float 0.0, float %arg
  ret float %select
}

; can't be negative or denormal
define float @clamp_is_ole_1_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @clamp_is_ole_1_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLE_1:%.*]] = fcmp ole float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ole.1 = fcmp ole float %arg, 1.0
  %select = select i1 %is.ole.1, float 0.0, float %arg
  ret float %select
}

; can't be negative or denormal
define float @clamp_is_ole_1_to_0_commute(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @clamp_is_ole_1_to_0_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_1:%.*]] = fcmp ugt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_1]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.1 = fcmp ugt float %arg, 1.0
  %select = select i1 %is.ugt.1, float %arg, float 0.0
  ret float %select
}

; can't be negative or denormal
define float @clamp_is_ule_1_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @clamp_is_ule_1_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULE_1:%.*]] = fcmp ole float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULE_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ule.1 = fcmp ole float %arg, 1.0
  %select = select i1 %is.ule.1, float 0.0, float %arg
  ret float %select
}

; can't be positive, zero or denormal
define float @clamp_is_ogt_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(pinf zero sub pnorm) float @clamp_is_ogt_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGT_NEG1:%.*]] = fcmp ogt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ogt.neg1 = fcmp ogt float %arg, -1.0
  %select = select i1 %is.ogt.neg1, float -1.0, float %arg
  ret float %select
}

; can't be positive, zero, nan or denormal
define float @clamp_is_ugt_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf zero sub pnorm) float @clamp_is_ugt_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_NEG1:%.*]] = fcmp ugt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.neg1 = fcmp ugt float %arg, -1.0
  %select = select i1 %is.ugt.neg1, float -1.0, float %arg
  ret float %select
}

; can't be positive or denormal
define float @clamp_is_ogt_neg1_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(pinf nzero sub pnorm) float @clamp_is_ogt_neg1_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGT_NEG1:%.*]] = fcmp ogt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_NEG1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ogt.neg1 = fcmp ogt float %arg, -1.0
  %select = select i1 %is.ogt.neg1, float 0.0, float %arg
  ret float %select
}

; can't be positive, nan or denormal
define float @clamp_is_ugt_neg1_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf nzero sub pnorm) float @clamp_is_ugt_neg1_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_NEG1:%.*]] = fcmp ugt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_NEG1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.neg1 = fcmp ugt float %arg, -1.0
  %select = select i1 %is.ugt.neg1, float 0.0, float %arg
  ret float %select
}

; can't be -inf
define float @clamp_is_olt_neg1_to_neg1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(ninf) float @clamp_is_olt_neg1_to_neg1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGE_NEG1:%.*]] = fcmp uge float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGE_NEG1]], float [[ARG]], float -1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.uge.neg1 = fcmp uge float %arg, -1.0
  %select = select i1 %is.uge.neg1, float %arg, float -1.0
  ret float %select
}

; can't be -inf
define float @clamp_is_olt_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(ninf) float @clamp_is_olt_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLT_NEG1:%.*]] = fcmp olt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.olt.neg1 = fcmp olt float %arg, -1.0
  %select = select i1 %is.olt.neg1, float -1.0, float %arg
  ret float %select
}

; can't be -inf or nan
define float @clamp_is_ult_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf) float @clamp_is_ult_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULT_NEG1:%.*]] = fcmp ult float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ult.neg1 = fcmp ult float %arg, -1.0
  %select = select i1 %is.ult.neg1, float -1.0, float %arg
  ret float %select
}

; can't be -inf or nan
define float @clamp_is_ult_neg1_to_neg1_commute(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf) float @clamp_is_ult_neg1_to_neg1_commute(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGE_NEG1:%.*]] = fcmp oge float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_NEG1]], float [[ARG]], float -1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oge.neg1 = fcmp oge float %arg, -1.0
  %select = select i1 %is.oge.neg1,  float %arg, float -1.
  ret float %select
}

;---------------------------------------------------------------------
; compare ==, != to normal
;---------------------------------------------------------------------

; Must be 1, only posnormal
define float @fcmp_oeq_1_else_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @fcmp_oeq_1_else_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OEQ_1:%.*]] = fcmp oeq float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oeq.1 = fcmp oeq float %arg, 1.0
  %select = select i1 %is.oeq.1, float %arg, float 1.0
  ret float %select
}

; Don't know anything
define float @fcmp_one_1_else_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @fcmp_one_1_else_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ONE_1:%.*]] = fcmp one float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.one.1 = fcmp one float %arg, 1.0
  %select = select i1 %is.one.1, float %arg, float 1.0
  ret float %select
}

; must be 1 or nan
define float @fcmp_one_1_1_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(inf zero sub nnorm) float @fcmp_one_1_1_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ONE_1:%.*]] = fcmp one float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.one.1 = fcmp one float %arg, 1.0
  %select = select i1 %is.one.1, float 1.0, float %arg
  ret float %select
}

; must be 1
define float @fcmp_une_1_1_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @fcmp_une_1_1_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UNE_1:%.*]] = fcmp une float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UNE_1]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.une.1 = fcmp une float %arg, 1.0
  %select = select i1 %is.une.1, float 1.0, float %arg
  ret float %select
}

; Must be -1, only negnormal
define float @fcmp_oeq_neg1_else_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf zero sub pnorm) float @fcmp_oeq_neg1_else_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OEQ_NEG1:%.*]] = fcmp oeq float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_NEG1]], float [[ARG]], float -1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oeq.neg1 = fcmp oeq float %arg, -1.0
  %select = select i1 %is.oeq.neg1, float %arg, float -1.0
  ret float %select
}

; Don't know anything
define float @fcmp_one_neg1_else_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @fcmp_one_neg1_else_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ONE_NEG1:%.*]] = fcmp one float [[ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_NEG1]], float [[ARG]], float -1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.one.neg1 = fcmp one float %arg, -1.0
  %select = select i1 %is.one.neg1, float %arg, float -1.0
  ret float %select
}

define float @fcmp_oeq_1_else_0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub nnorm) float @fcmp_oeq_1_else_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OEQ_1:%.*]] = fcmp oeq float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_1]], float 1.000000e+00, float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oeq.1 = fcmp oeq float %arg, 1.0
  %select = select i1 %is.oeq.1, float 1.0, float 0.0
  ret float %select
}

define float @fcmp_ueq_1_else_0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub nnorm) float @fcmp_ueq_1_else_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UEQ_1:%.*]] = fcmp ueq float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UEQ_1]], float 1.000000e+00, float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ueq.1 = fcmp ueq float %arg, 1.0
  %select = select i1 %is.ueq.1, float 1.0, float 0.0
  ret float %select
}

define float @if_fcmp_oeq_1_0_else_arg(float %arg) {
; CHECK-LABEL: define float @if_fcmp_oeq_1_0_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OEQ_1:%.*]] = fcmp oeq float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oeq.1 = fcmp oeq float %arg, 1.0
  %select = select i1 %is.oeq.1, float 0.0, float %arg
  ret float %select
}

define float @if_fcmp_oeq_0_1_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(zero) float @if_fcmp_oeq_0_1_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OEQ_0:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_0]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oeq.0 = fcmp oeq float %arg, 0.0
  %select = select i1 %is.oeq.0, float 1.0, float %arg
  ret float %select
}

define float @if_fcmp_one_0_arg_else_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan zero) float @if_fcmp_one_0_arg_else_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ONE_0:%.*]] = fcmp one float [[ARG]], 0.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_0]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.one.0 = fcmp one float %arg, 0.0
  %select = select i1 %is.one.0, float %arg, float 1.0
  ret float %select
}

define float @if_fcmp_une_0_arg_else_1(float %arg) {
; CHECK-LABEL: define nofpclass(zero) float @if_fcmp_une_0_arg_else_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UNE_0:%.*]] = fcmp une float [[ARG]], 0.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UNE_0]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.une.0 = fcmp une float %arg, 0.0
  %select = select i1 %is.une.0, float %arg, float 1.0
  ret float %select
}

define float @if_fcmp_one_0_1_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(inf sub nnorm) float @if_fcmp_one_0_1_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ONE_0:%.*]] = fcmp one float [[ARG]], 0.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_0]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.one.0 = fcmp one float %arg, 0.0
  %select = select i1 %is.one.0, float 1.0, float %arg
  ret float %select
}

define float @if_fcmp_one_1_arg_else_0(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @if_fcmp_one_1_arg_else_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ONE_1:%.*]] = fcmp one float [[ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_1]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.one.1 = fcmp one float %arg, 1.0
  %select = select i1 %is.one.1, float %arg, float 0.0
  ret float %select
}

define float @fcmp_fabs_oeq_1_else_1(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf zero sub) float @fcmp_fabs_oeq_1_else_1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4:[0-9]+]]
; CHECK-NEXT:    [[FABS_IS_OEQ_1:%.*]] = fcmp oeq float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OEQ_1]], float [[ARG]], float 1.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.oeq.1 = fcmp oeq float %fabs.arg, 1.0
  %select = select i1 %fabs.is.oeq.1, float %arg, float 1.0
  ret float %select
}

define float @fcmp_fabs_oeq_1_0_else_arg(float %arg) {
; CHECK-LABEL: define float @fcmp_fabs_oeq_1_0_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OEQ_1:%.*]] = fcmp oeq float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OEQ_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.oeq.1 = fcmp oeq float %fabs.arg, 1.0
  %select = select i1 %fabs.is.oeq.1, float 0.0, float %arg
  ret float %select
}

define float @fcmp_fabs_ueq_1_0_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @fcmp_fabs_ueq_1_0_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_UEQ_1:%.*]] = fcmp ueq float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_UEQ_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ueq.1 = fcmp ueq float %fabs.arg, 1.0
  %select = select i1 %fabs.is.ueq.1, float 0.0, float %arg
  ret float %select
}

define float @fcmp_fabs_one_1_arg_else_0(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @fcmp_fabs_one_1_arg_else_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ONE_1:%.*]] = fcmp one float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ONE_1]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.one.1 = fcmp one float %fabs.arg, 1.0
  %select = select i1 %fabs.is.one.1, float %arg, float 0.0
  ret float %select
}

define float @fcmp_fabs_une_1_arg_else_0(float %arg) {
; CHECK-LABEL: define float @fcmp_fabs_une_1_arg_else_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_UNE_1:%.*]] = fcmp une float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_UNE_1]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.une.1 = fcmp une float %fabs.arg, 1.0
  %select = select i1 %fabs.is.une.1, float %arg, float 0.0
  ret float %select
}

define float @fcmp_fabs_one_1_0_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(inf nzero sub) float @fcmp_fabs_one_1_0_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ONE_1:%.*]] = fcmp one float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ONE_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.one.1 = fcmp one float %fabs.arg, 1.0
  %select = select i1 %fabs.is.one.1, float 0.0, float %arg
  ret float %select
}

define float @fcmp_fabs_une_1_0_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf nzero sub) float @fcmp_fabs_une_1_0_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_UNE_1:%.*]] = fcmp une float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_UNE_1]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.une.1 = fcmp une float %fabs.arg, 1.0
  %select = select i1 %fabs.is.une.1, float 0.0, float %arg
  ret float %select
}

define float @fcmp_fabs_one_1_neg2_else_arg(float %arg) {
; CHECK-LABEL: define nofpclass(inf zero sub) float @fcmp_fabs_one_1_neg2_else_arg(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ONE_1:%.*]] = fcmp one float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ONE_1]], float -2.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.one.1 = fcmp one float %fabs.arg, 1.0
  %select = select i1 %fabs.is.one.1, float -2.0, float %arg
  ret float %select
}

;---------------------------------------------------------------------
; compare to denormal
;---------------------------------------------------------------------

define float @clamp_olt_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @clamp_olt_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLT_LARGEST_DENORMAL:%.*]] = fcmp olt float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_LARGEST_DENORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.olt.largest.denormal = fcmp olt float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.olt.largest.denormal, float 0.0, float %arg
  ret float %select
}

define float @clamp_ole_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @clamp_ole_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OLE_LARGEST_DENORMAL:%.*]] = fcmp ole float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_LARGEST_DENORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ole.largest.denormal = fcmp ole float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.ole.largest.denormal, float 0.0, float %arg
  ret float %select
}

define float @clamp_ult_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @clamp_ult_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULT_LARGEST_DENORMAL:%.*]] = fcmp ult float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_LARGEST_DENORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ult.largest.denormal = fcmp ult float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.ult.largest.denormal, float 0.0, float %arg
  ret float %select
}

define float @clamp_ule_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @clamp_ule_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_ULE_LARGEST_DENORMAL:%.*]] = fcmp ule float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULE_LARGEST_DENORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ule.largest.denormal = fcmp ule float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.ule.largest.denormal, float 0.0, float %arg
  ret float %select
}

define float @clamp_ogt_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @clamp_ogt_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGT_LARGEST_DENORMAL:%.*]] = fcmp ogt float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_LARGEST_DENORMAL]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ogt.largest.denormal = fcmp ogt float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.ogt.largest.denormal, float %arg, float 0.0
  ret float %select
}

define float @clamp_oge_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @clamp_oge_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGE_LARGEST_DENORMAL:%.*]] = fcmp oge float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_LARGEST_DENORMAL]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oge.largest.denormal = fcmp oge float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.oge.largest.denormal, float %arg, float 0.0
  ret float %select
}

define float @clamp_ugt_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @clamp_ugt_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_LARGEST_DENORMAL:%.*]] = fcmp ugt float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_LARGEST_DENORMAL]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.largest.denormal = fcmp ugt float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.ugt.largest.denormal, float %arg, float 0.0
  ret float %select
}

define float @clamp_uge_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @clamp_uge_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGE_LARGEST_DENORMAL:%.*]] = fcmp uge float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGE_LARGEST_DENORMAL]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.uge.largest.denormal = fcmp uge float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.uge.largest.denormal, float %arg, float 0.0
  ret float %select
}

define float @fcmp_oeq_largest_denormal_arg_else_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf nzero nsub norm) float @fcmp_oeq_largest_denormal_arg_else_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OEQ_LARGEST_DENORMAL:%.*]] = fcmp oeq float [[ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_LARGEST_DENORMAL]], float [[ARG]], float 0.000000e+00
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oeq.largest.denormal = fcmp oeq float %arg, 0x380FFFFFC0000000
  %select = select i1 %is.oeq.largest.denormal, float %arg, float 0.0
  ret float %select
}

define float @clamp_fabs_olt_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nzero) float @clamp_fabs_olt_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_FABS_OLT_LARGEST_DENORMAL:%.*]] = fcmp olt float [[FABS_ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_FABS_OLT_LARGEST_DENORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.fabs.olt.largest.denormal = fcmp olt float %fabs.arg, 0x380FFFFFC0000000
  %select = select i1 %is.fabs.olt.largest.denormal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_ole_largest_denormal_0.0(float %arg) {
; CHECK-LABEL: define nofpclass(nzero) float @clamp_fabs_ole_largest_denormal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_FABS_OLE_LARGEST_DENORMAL:%.*]] = fcmp ole float [[FABS_ARG]], 0x380FFFFFC0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_FABS_OLE_LARGEST_DENORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.fabs.ole.largest.denormal = fcmp ole float %fabs.arg, 0x380FFFFFC0000000
  %select = select i1 %is.fabs.ole.largest.denormal, float 0.0, float %arg
  ret float %select
}

;---------------------------------------------------------------------
; clamp fabs to 1 copysign
;---------------------------------------------------------------------

; can't be inf
define float @clamp_fabs_value_ogt_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_value_ogt_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OGT_1:%.*]] = fcmp ogt float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OGT_1]], float [[COPYSIGN]], float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ogt.1 = fcmp ogt float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.ogt.1, float %copysign, float %arg
  ret float %select
}

; can't be inf
define float @clamp_fabs_value_oge_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_value_oge_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OGE_1:%.*]] = fcmp oge float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OGE_1]], float [[COPYSIGN]], float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.oge.1 = fcmp oge float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.oge.1, float %copysign, float %arg
  ret float %select
}

; can't be inf or nan
define float @clamp_fabs_value_olt_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf) float @clamp_fabs_value_olt_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OLT_1:%.*]] = fcmp olt float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call nofpclass(nan inf zero sub) float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OLT_1]], float [[ARG]], float [[COPYSIGN]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.olt.1 = fcmp olt float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.olt.1, float %arg, float %copysign
  ret float %select
}

; can't be inf or nan
define float @clamp_fabs_value_ole_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf) float @clamp_fabs_value_ole_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OLE_1:%.*]] = fcmp ole float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call nofpclass(nan inf zero sub) float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OLE_1]], float [[ARG]], float [[COPYSIGN]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ole.1 = fcmp ole float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.ole.1, float %arg, float %copysign
  ret float %select
}

; can't be inf or nan
define float @clamp_fabs_value_ugt_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf) float @clamp_fabs_value_ugt_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_UGT_1:%.*]] = fcmp ugt float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_UGT_1]], float [[COPYSIGN]], float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ugt.1 = fcmp ugt float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.ugt.1, float %copysign, float %arg
  ret float %select
}

; can't be inf or nan
define float @clamp_fabs_value_uge_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf) float @clamp_fabs_value_uge_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_UGE_1:%.*]] = fcmp ugt float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_UGE_1]], float [[COPYSIGN]], float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.uge.1 = fcmp ugt float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.uge.1, float %copysign, float %arg
  ret float %select
}

; can't be inf
define float @clamp_fabs_value_ult_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_value_ult_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ULT_1:%.*]] = fcmp ult float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call nofpclass(nan inf zero sub) float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ULT_1]], float [[ARG]], float [[COPYSIGN]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ult.1 = fcmp ult float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.ult.1, float %arg, float %copysign
  ret float %select
}

; can't be inf
define float @clamp_fabs_value_ule_1_to_1_copysign(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_value_ule_1_to_1_copysign(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ULE_1:%.*]] = fcmp ule float [[FABS_ARG]], 1.000000e+00
; CHECK-NEXT:    [[COPYSIGN:%.*]] = call nofpclass(nan inf zero sub) float @llvm.copysign.f32(float noundef 1.000000e+00, float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ULE_1]], float [[ARG]], float [[COPYSIGN]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ule.1 = fcmp ule float %fabs.arg, 1.0
  %copysign = call float @llvm.copysign.f32(float 1.0, float %arg)
  %select = select i1 %fabs.is.ule.1, float %arg, float %copysign
  ret float %select
}

;---------------------------------------------------------------------
; compare to largest normal
;---------------------------------------------------------------------

; Can't be +inf
define float @clamp_is_ogt_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_ogt_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGT_LARGEST_NORMAL:%.*]] = fcmp ogt float [[ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ogt.largest.normal = fcmp ogt float %arg, 0x47EFFFFFE0000000
  %select = select i1 %is.ogt.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf
define float @clamp_is_oge_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(pinf) float @clamp_is_oge_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_OGE_LARGEST_NORMAL:%.*]] = fcmp oge float [[ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.oge.largest.normal = fcmp oge float %arg, 0x47EFFFFFE0000000
  %select = select i1 %is.oge.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf or nan
define float @clamp_is_ugt_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf) float @clamp_is_ugt_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGT_LARGEST_NORMAL:%.*]] = fcmp ugt float [[ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.ugt.largest.normal = fcmp ugt float %arg, 0x47EFFFFFE0000000
  %select = select i1 %is.ugt.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf or nan
define float @clamp_is_uge_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(nan pinf) float @clamp_is_uge_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[IS_UGE_LARGEST_NORMAL:%.*]] = fcmp uge float [[ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGE_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %is.uge.largest.normal = fcmp uge float %arg, 0x47EFFFFFE0000000
  %select = select i1 %is.uge.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf or -inf
define float @clamp_fabs_is_ogt_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_is_ogt_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OGT_LARGEST_NORMAL:%.*]] = fcmp ogt float [[FABS_ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ogt.largest.normal = fcmp ogt float %fabs.arg, 0x47EFFFFFE0000000
  %select = select i1 %is.ogt.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf or -inf
define float @clamp_fabs_is_oge_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_is_oge_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OGE_LARGEST_NORMAL:%.*]] = fcmp oge float [[FABS_ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.oge.largest.normal = fcmp oge float %fabs.arg, 0x47EFFFFFE0000000
  %select = select i1 %is.oge.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf or -inf or nan
define float @clamp_fabs_is_ugt_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf) float @clamp_fabs_is_ugt_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UGT_LARGEST_NORMAL:%.*]] = fcmp ugt float [[FABS_ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ugt.largest.normal = fcmp ugt float %fabs.arg, 0x47EFFFFFE0000000
  %select = select i1 %is.ugt.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

; Can't be +inf or -inf or nan
define float @clamp_fabs_is_uge_largest_normal_to_largest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf) float @clamp_fabs_is_uge_largest_normal_to_largest_normal(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UGT_LARGEST_NORMAL:%.*]] = fcmp uge float [[FABS_ARG]], 0x47EFFFFFE0000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_LARGEST_NORMAL]], float 0x47EFFFFFE0000000, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ugt.largest.normal = fcmp uge float %fabs.arg, 0x47EFFFFFE0000000
  %select = select i1 %is.ugt.largest.normal, float 0x47EFFFFFE0000000, float %arg
  ret float %select
}

;---------------------------------------------------------------------
; compare to smallest normal
;---------------------------------------------------------------------

; can't be negative or positive subnormal
define float @clamp_fabs_ogt_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(inf) float @clamp_fabs_ogt_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OGT_SMALLEST_NORMAL:%.*]] = fcmp ogt float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;

  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ogt.smallest.normal = fcmp ogt float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.ogt.smallest.normal, float 0.0, float %arg
  ret float %select
}

; can't be negative or positive subnormal
define float @clamp_fabs_oge_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(inf norm) float @clamp_fabs_oge_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OGE_SMALLEST_NORMAL:%.*]] = fcmp oge float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.oge.smallest.normal = fcmp oge float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.oge.smallest.normal, float 0.0, float %arg
  ret float %select
}

; can't be negative or subnormal
define float @clamp_fabs_olt_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(nzero sub) float @clamp_fabs_olt_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OLT_SMALLEST_NORMAL:%.*]] = fcmp olt float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.olt.smallest.normal = fcmp olt float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.olt.smallest.normal, float 0.0, float %arg
  ret float %select
}

; can't be negative or subnormal
define float @clamp_fabs_ole_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(nzero sub) float @clamp_fabs_ole_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OLE_SMALLEST_NORMAL:%.*]] = fcmp ole float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ole.smallest.normal = fcmp ole float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.ole.smallest.normal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_is_is_olt_smallest_normal_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(nzero sub) float @clamp_fabs_is_is_olt_smallest_normal_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OLT_SMALLEST_NORMAL:%.*]] = fcmp olt float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.olt.smallest.normal = fcmp olt float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.olt.smallest.normal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_is_is_ole_smallest_normal_to_0(float %arg) {
; CHECK-LABEL: define nofpclass(nzero sub) float @clamp_fabs_is_is_ole_smallest_normal_to_0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OLE_SMALLEST_NORMAL:%.*]] = fcmp ole float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ole.smallest.normal = fcmp ole float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.ole.smallest.normal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_oeq_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_oeq_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OEQ_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.oeq.smallest.normal = fcmp oeq float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.oeq.smallest.normal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_one_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(inf nzero sub) float @clamp_fabs_one_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_ONE_SMALLEST_NORMAL:%.*]] = fcmp one float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ONE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.one.smallest.normal = fcmp one float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.one.smallest.normal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_ueq_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @clamp_fabs_ueq_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UEQ_SMALLEST_NORMAL:%.*]] = fcmp ueq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UEQ_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ueq.smallest.normal = fcmp ueq float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.ueq.smallest.normal, float 0.0, float %arg
  ret float %select
}

define float @clamp_fabs_une_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define nofpclass(nan inf nzero sub) float @clamp_fabs_une_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UNE_SMALLEST_NORMAL:%.*]] = fcmp une float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UNE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.une.smallest.normal = fcmp une float %fabs.arg, 0x3810000000000000
  %select = select i1 %is.une.smallest.normal, float 0.0, float %arg
  ret float %select
}

;---------------------------------------------------------------------
; compare fabs to negative normal
;---------------------------------------------------------------------

define float @clamp_fabs_olt_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_olt_neg1_to_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.olt.neg1 = fcmp olt float %fabs.arg, -1.0
  %select = select i1 %fabs.is.olt.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_ole_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_ole_neg1_to_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ole.neg1 = fcmp ole float %fabs.arg, -1.0
  %select = select i1 %fabs.is.ole.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_ult_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @clamp_fabs_ult_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ULT_NEG1:%.*]] = fcmp ult float [[FABS_ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ULT_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ult.neg1 = fcmp ult float %fabs.arg, -1.0
  %select = select i1 %fabs.is.ult.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_ule_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @clamp_fabs_ule_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ULE_NEG1:%.*]] = fcmp ule float [[FABS_ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ULE_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ule.neg1 = fcmp ule float %fabs.arg, -1.0
  %select = select i1 %fabs.is.ule.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_ogt_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(inf zero sub pnorm) float @clamp_fabs_ogt_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OGT_NEG1:%.*]] = fcmp ogt float [[FABS_ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OGT_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ogt.neg1 = fcmp ogt float %fabs.arg, -1.0
  %select = select i1 %fabs.is.ogt.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_oge_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(inf zero sub pnorm) float @clamp_fabs_oge_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_OGE_NEG1:%.*]] = fcmp oge float [[FABS_ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_OGE_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.oge.neg1 = fcmp oge float %fabs.arg, -1.0
  %select = select i1 %fabs.is.oge.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_ugt_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf zero sub pnorm) float @clamp_fabs_ugt_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float -1.000000e+00
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ugt.neg1 = fcmp ugt float %fabs.arg, -1.0
  %select = select i1 %fabs.is.ugt.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_uge_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf zero sub pnorm) float @clamp_fabs_uge_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float -1.000000e+00
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.uge.neg1 = fcmp uge float %fabs.arg, -1.0
  %select = select i1 %fabs.is.uge.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_oeq_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_oeq_neg1_to_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.oeq.neg1 = fcmp oeq float %fabs.arg, -1.0
  %select = select i1 %fabs.is.oeq.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_ueq_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @clamp_fabs_ueq_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_UEQ_NEG1:%.*]] = fcmp ueq float [[FABS_ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_UEQ_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.ueq.neg1 = fcmp ueq float %fabs.arg, -1.0
  %select = select i1 %fabs.is.ueq.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_one_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define nofpclass(inf zero sub pnorm) float @clamp_fabs_one_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FABS_IS_ONE_NEG1:%.*]] = fcmp one float [[FABS_ARG]], -1.000000e+00
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[FABS_IS_ONE_NEG1]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.one.neg1 = fcmp one float %fabs.arg, -1.0
  %select = select i1 %fabs.is.one.neg1, float -1.0, float %arg
  ret float %select
}

define float @clamp_fabs_une_neg1_to_neg1(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf zero sub pnorm) float @clamp_fabs_une_neg1_to_neg1(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float -1.000000e+00
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %fabs.is.une.neg1 = fcmp une float %fabs.arg, -1.0
  %select = select i1 %fabs.is.une.neg1, float -1.0, float %arg
  ret float %select
}

;---------------------------------------------------------------------
; assume > < to normal
;---------------------------------------------------------------------

define float @ret_assumed_ogt_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ogt_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT:    [[OGT_1:%.*]] = fcmp ogt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGT_1]]) #[[ATTR5:[0-9]+]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ogt.1 = fcmp ogt float %arg, 1.0
  call void @llvm.assume(i1 %ogt.1)
  ret float %arg
}

define float @ret_assumed_oge_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_oge_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OGE_1:%.*]] = fcmp ogt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %oge.1 = fcmp ogt float %arg, 1.0
  call void @llvm.assume(i1 %oge.1)
  ret float %arg
}

define float @ret_assumed_olt_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_olt_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OLT_1:%.*]] = fcmp olt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %olt.1 = fcmp olt float %arg, 1.0
  call void @llvm.assume(i1 %olt.1)
  ret float %arg
}

define float @ret_assumed_ole_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ole_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OLE_1:%.*]] = fcmp ole float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ole.1 = fcmp ole float %arg, 1.0
  call void @llvm.assume(i1 %ole.1)
  ret float %arg
}

define float @ret_assumed_ugt_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ugt_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UGT_1:%.*]] = fcmp ugt float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ugt.1 = fcmp ugt float %arg, 1.0
  call void @llvm.assume(i1 %ugt.1)
  ret float %arg
}

define float @ret_assumed_uge_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_uge_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UGE_1:%.*]] = fcmp uge float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %uge.1 = fcmp uge float %arg, 1.0
  call void @llvm.assume(i1 %uge.1)
  ret float %arg
}

define float @ret_assumed_ult_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ult_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ULT_1:%.*]] = fcmp ult float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ult.1 = fcmp ult float %arg, 1.0
  call void @llvm.assume(i1 %ult.1)
  ret float %arg
}

define float @ret_assumed_ule_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ule_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ULE_1:%.*]] = fcmp ule float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ule.1 = fcmp ule float %arg, 1.0
  call void @llvm.assume(i1 %ule.1)
  ret float %arg
}

define float @ret_assumed_fabs_ogt_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ogt_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[OGT_1:%.*]] = fcmp ogt float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ogt.1 = fcmp ogt float %arg.fabs, 1.0
  call void @llvm.assume(i1 %ogt.1)
  ret float %arg
}

define float @ret_assumed_fabs_oge_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_oge_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[OGE_1:%.*]] = fcmp oge float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %oge.1 = fcmp oge float %arg.fabs, 1.0
  call void @llvm.assume(i1 %oge.1)
  ret float %arg
}

define float @ret_assumed_fabs_olt_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_olt_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[OLT_1:%.*]] = fcmp olt float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %olt.1 = fcmp olt float %arg.fabs, 1.0
  call void @llvm.assume(i1 %olt.1)
  ret float %arg
}

define float @ret_assumed_fabs_ole_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ole_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[OLE_1:%.*]] = fcmp olt float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ole.1 = fcmp olt float %arg.fabs, 1.0
  call void @llvm.assume(i1 %ole.1)
  ret float %arg
}

define float @ret_assumed_fabs_ugt_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ugt_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[UGT_1:%.*]] = fcmp ugt float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ugt.1 = fcmp ugt float %arg.fabs, 1.0
  call void @llvm.assume(i1 %ugt.1)
  ret float %arg
}

define float @ret_assumed_fabs_uge_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_uge_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[UGE_1:%.*]] = fcmp ugt float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %uge.1 = fcmp ugt float %arg.fabs, 1.0
  call void @llvm.assume(i1 %uge.1)
  ret float %arg
}

define float @ret_assumed_fabs_ult_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ult_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[ULT_1:%.*]] = fcmp ult float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULT_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ult.1 = fcmp ult float %arg.fabs, 1.0
  call void @llvm.assume(i1 %ult.1)
  ret float %arg
}

define float @ret_assumed_fabs_ule_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ule_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[ULE_1:%.*]] = fcmp ule float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ule.1 = fcmp ule float %arg.fabs, 1.0
  call void @llvm.assume(i1 %ule.1)
  ret float %arg
}

define float @ret_assumed_ogt_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ogt_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OGT_NEG1:%.*]] = fcmp ogt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGT_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ogt.neg1 = fcmp ogt float %arg, -1.0
  call void @llvm.assume(i1 %ogt.neg1)
  ret float %arg
}

define float @ret_assumed_oge_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_oge_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OGE_NEG1:%.*]] = fcmp ogt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %oge.neg1 = fcmp ogt float %arg, -1.0
  call void @llvm.assume(i1 %oge.neg1)
  ret float %arg
}

define float @ret_assumed_olt_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_olt_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OLT_NEG1:%.*]] = fcmp olt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLT_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %olt.neg1 = fcmp olt float %arg, -1.0
  call void @llvm.assume(i1 %olt.neg1)
  ret float %arg
}

define float @ret_assumed_ole_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ole_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OLE_NEG1:%.*]] = fcmp ole float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ole.neg1 = fcmp ole float %arg, -1.0
  call void @llvm.assume(i1 %ole.neg1)
  ret float %arg
}

define float @ret_assumed_ugt_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ugt_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UGT_NEG1:%.*]] = fcmp ugt float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGT_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ugt.neg1 = fcmp ugt float %arg, -1.0
  call void @llvm.assume(i1 %ugt.neg1)
  ret float %arg
}

define float @ret_assumed_uge_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_uge_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UGE_NEG1:%.*]] = fcmp uge float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %uge.neg1 = fcmp uge float %arg, -1.0
  call void @llvm.assume(i1 %uge.neg1)
  ret float %arg
}

define float @ret_assumed_ult_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ult_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ULT_NEG1:%.*]] = fcmp ult float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULT_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ult.neg1 = fcmp ult float %arg, -1.0
  call void @llvm.assume(i1 %ult.neg1)
  ret float %arg
}

define float @ret_assumed_ule_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ule_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ULE_NEG1:%.*]] = fcmp ule float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ule.neg1 = fcmp ule float %arg, -1.0
  call void @llvm.assume(i1 %ule.neg1)
  ret float %arg
}

define float @ret_assumed_oeq_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_oeq_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[OEQ_1:%.*]] = fcmp oeq float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OEQ_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %oeq.1 = fcmp oeq float %arg, 1.0
  call void @llvm.assume(i1 %oeq.1)
  ret float %arg
}

define float @ret_assumed_ueq_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_ueq_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UEQ_1:%.*]] = fcmp ueq float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UEQ_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %ueq.1 = fcmp ueq float %arg, 1.0
  call void @llvm.assume(i1 %ueq.1)
  ret float %arg
}

define float @ret_assumed_one_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_one_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ONE_1:%.*]] = fcmp one float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ONE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %one.1 = fcmp one float %arg, 1.0
  call void @llvm.assume(i1 %one.1)
  ret float %arg
}

define float @ret_assumed_one_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_one_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ONE_NEG1:%.*]] = fcmp one float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ONE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %one.neg1 = fcmp one float %arg, -1.0
  call void @llvm.assume(i1 %one.neg1)
  ret float %arg
}

define float @ret_assumed_une_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_une_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UNE_NEG1:%.*]] = fcmp une float [[ARG]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %une.neg1 = fcmp une float %arg, -1.0
  call void @llvm.assume(i1 %une.neg1)
  ret float %arg
}

define float @ret_assumed_une_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_une_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[UNE_1:%.*]] = fcmp une float [[ARG]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %une.1 = fcmp une float %arg, 1.0
  call void @llvm.assume(i1 %une.1)
  ret float %arg
}

define float @ret_assumed_fabs_oeq_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_oeq_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[OEQ_1:%.*]] = fcmp oeq float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OEQ_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %oeq.1 = fcmp oeq float %arg.fabs, 1.0
  call void @llvm.assume(i1 %oeq.1)
  ret float %arg
}

define float @ret_assumed_fabs_ueq_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ueq_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[UEQ_1:%.*]] = fcmp ueq float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UEQ_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ueq.1 = fcmp ueq float %arg.fabs, 1.0
  call void @llvm.assume(i1 %ueq.1)
  ret float %arg
}

define float @ret_assumed_fabs_one_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_one_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[ONE_1:%.*]] = fcmp one float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ONE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %one.1 = fcmp one float %arg.fabs, 1.0
  call void @llvm.assume(i1 %one.1)
  ret float %arg
}

define float @ret_assumed_fabs_une_1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_une_1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[UNE_1:%.*]] = fcmp one float [[ARG_FABS]], 1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNE_1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %une.1 = fcmp one float %arg.fabs, 1.0
  call void @llvm.assume(i1 %une.1)
  ret float %arg
}

define float @ret_assumed_fabs_oeq_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_oeq_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %oeq.neg1 = fcmp oeq float %arg.fabs, -1.0
  call void @llvm.assume(i1 %oeq.neg1)
  ret float %arg
}

define float @ret_assumed_fabs_ueq_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_ueq_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[UEQ_NEG1:%.*]] = fcmp ueq float [[ARG_FABS]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UEQ_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %ueq.neg1 = fcmp ueq float %arg.fabs, -1.0
  call void @llvm.assume(i1 %ueq.neg1)
  ret float %arg
}

define float @ret_assumed_fabs_one_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_one_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[ONE_NEG1:%.*]] = fcmp one float [[ARG_FABS]], -1.000000e+00
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ONE_NEG1]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %one.neg1 = fcmp one float %arg.fabs, -1.0
  call void @llvm.assume(i1 %one.neg1)
  ret float %arg
}

define float @ret_assumed_fabs_une_neg1(float %arg) {
; CHECK-LABEL: define float @ret_assumed_fabs_une_neg1(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %arg.fabs = call float @llvm.fabs.f32(float %arg)
  %une.neg1 = fcmp une float %arg.fabs, -1.0
  call void @llvm.assume(i1 %une.neg1)
  ret float %arg
}

;---------------------------------------------------------------------
; compare > fabs(variable)
;---------------------------------------------------------------------

; Can't be +inf
define float @clamp_is_ogt_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ogt_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OGT_KNOWN_POSITIVE:%.*]] = fcmp ogt float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.ogt.known.positive = fcmp ogt float %arg, %known.positive
  %select = select i1 %is.ogt.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_oge_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_oge_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OGE_KNOWN_POSITIVE:%.*]] = fcmp oge float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.oge.known.positive = fcmp oge float %arg, %known.positive
  %select = select i1 %is.oge.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_olt_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_olt_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OLT_KNOWN_POSITIVE:%.*]] = fcmp olt float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.olt.known.positive = fcmp olt float %arg, %known.positive
  %select = select i1 %is.olt.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_ole_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ole_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OLE_KNOWN_POSITIVE:%.*]] = fcmp olt float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.ole.known.positive = fcmp olt float %arg, %known.positive
  %select = select i1 %is.ole.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_ugt_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ugt_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UGT_KNOWN_POSITIVE:%.*]] = fcmp ugt float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.ugt.known.positive = fcmp ugt float %arg, %known.positive
  %select = select i1 %is.ugt.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_uge_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_uge_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UGE_KNOWN_POSITIVE:%.*]] = fcmp uge float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGE_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.uge.known.positive = fcmp uge float %arg, %known.positive
  %select = select i1 %is.uge.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_ult_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ult_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_ULT_KNOWN_POSITIVE:%.*]] = fcmp ult float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.ult.known.positive = fcmp ult float %arg, %known.positive
  %select = select i1 %is.ult.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_ule_known_positive_to_1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ule_known_positive_to_1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_ULE_KNOWN_POSITIVE:%.*]] = fcmp ult float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULE_KNOWN_POSITIVE]], float 1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %is.ule.known.positive = fcmp ult float %arg, %known.positive
  %select = select i1 %is.ule.known.positive, float 1.0, float %arg
  ret float %select
}

define float @clamp_is_olt_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_olt_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_OLT_NEGATIVE:%.*]] = fcmp olt float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLT_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.olt.negative = fcmp olt float %arg, %known.negative
  %select = select i1 %is.olt.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_ole_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ole_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_OLE_NEGATIVE:%.*]] = fcmp ole float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OLE_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.ole.negative = fcmp ole float %arg, %known.negative
  %select = select i1 %is.ole.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_ogt_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ogt_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_OGT_NEGATIVE:%.*]] = fcmp ogt float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGT_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.ogt.negative = fcmp ogt float %arg, %known.negative
  %select = select i1 %is.ogt.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_oge_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_oge_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_OGE_NEGATIVE:%.*]] = fcmp oge float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_OGE_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.oge.negative = fcmp oge float %arg, %known.negative
  %select = select i1 %is.oge.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_ult_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ult_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_ULT_NEGATIVE:%.*]] = fcmp ult float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULT_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.ult.negative = fcmp ult float %arg, %known.negative
  %select = select i1 %is.ult.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_ule_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ule_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_ULE_NEGATIVE:%.*]] = fcmp ule float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ULE_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.ule.negative = fcmp ule float %arg, %known.negative
  %select = select i1 %is.ule.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_ugt_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_ugt_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_UGT_NEGATIVE:%.*]] = fcmp ugt float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGT_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.ugt.negative = fcmp ugt float %arg, %known.negative
  %select = select i1 %is.ugt.negative, float -1.0, float %arg
  ret float %select
}

define float @clamp_is_uge_known_negative_to_neg1(float %arg, float %unknown) {
; CHECK-LABEL: define float @clamp_is_uge_known_negative_to_neg1(
; CHECK-SAME: float [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[IS_UGE_NEGATIVE:%.*]] = fcmp uge float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_UGE_NEGATIVE]], float -1.000000e+00, float [[ARG]]
; CHECK-NEXT:    ret float [[SELECT]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %is.uge.negative = fcmp uge float %arg, %known.negative
  %select = select i1 %is.uge.negative, float -1.0, float %arg
  ret float %select
}

define float @ret_assumed_ogt_known_positive(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ogt_known_positive(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[OGT_KNOWN_POSITIVE:%.*]] = fcmp ogt float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGT_KNOWN_POSITIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %ogt.known.positive = fcmp ogt float %arg, %known.positive
  call void @llvm.assume(i1 %ogt.known.positive)
  ret float %arg
}

define float @ret_assumed_oge_known_positive(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_oge_known_positive(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[OGE_KNOWN_POSITIVE:%.*]] = fcmp oge float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGE_KNOWN_POSITIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %oge.known.positive = fcmp oge float %arg, %known.positive
  call void @llvm.assume(i1 %oge.known.positive)
  ret float %arg
}

define float @ret_assumed_ugt_known_positive(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ugt_known_positive(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[UGT_KNOWN_POSITIVE:%.*]] = fcmp ugt float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGT_KNOWN_POSITIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %ugt.known.positive = fcmp ugt float %arg, %known.positive
  call void @llvm.assume(i1 %ugt.known.positive)
  ret float %arg
}

define float @ret_assumed_uge_known_positive(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_uge_known_positive(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[UGE_KNOWN_POSITIVE:%.*]] = fcmp uge float [[ARG]], [[KNOWN_POSITIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGE_KNOWN_POSITIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %uge.known.positive = fcmp uge float %arg, %known.positive
  call void @llvm.assume(i1 %uge.known.positive)
  ret float %arg
}

define float @ret_assumed_olt_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_olt_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[OLT_KNOWN_NEGATIVE:%.*]] = fcmp olt float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLT_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %olt.known.negative = fcmp olt float %arg, %known.negative
  call void @llvm.assume(i1 %olt.known.negative)
  ret float %arg
}

define float @ret_assumed_ole_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ole_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[OLE_KNOWN_NEGATIVE:%.*]] = fcmp ole float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OLE_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %ole.known.negative = fcmp ole float %arg, %known.negative
  call void @llvm.assume(i1 %ole.known.negative)
  ret float %arg
}

define float @ret_assumed_ult_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ult_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[ULT_KNOWN_NEGATIVE:%.*]] = fcmp ult float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULT_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %ult.known.negative = fcmp ult float %arg, %known.negative
  call void @llvm.assume(i1 %ult.known.negative)
  ret float %arg
}

define float @ret_assumed_ule_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ule_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[ULE_KNOWN_NEGATIVE:%.*]] = fcmp ule float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ULE_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %ule.known.negative = fcmp ule float %arg, %known.negative
  call void @llvm.assume(i1 %ule.known.negative)
  ret float %arg
}

define float @ret_assumed_ogt_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ogt_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[OGT_KNOWN_NEGATIVE:%.*]] = fcmp ogt float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGT_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %ogt.known.negative = fcmp ogt float %arg, %known.negative
  call void @llvm.assume(i1 %ogt.known.negative)
  ret float %arg
}

define float @ret_assumed_oge_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_oge_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[OGE_KNOWN_NEGATIVE:%.*]] = fcmp oge float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[OGE_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %oge.known.negative = fcmp oge float %arg, %known.negative
  call void @llvm.assume(i1 %oge.known.negative)
  ret float %arg
}

define float @ret_assumed_ugt_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_ugt_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[UGT_KNOWN_NEGATIVE:%.*]] = fcmp ugt float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGT_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %ugt.known.negative = fcmp ugt float %arg, %known.negative
  call void @llvm.assume(i1 %ugt.known.negative)
  ret float %arg
}

define float @ret_assumed_uge_known_negative(float %arg, float %unknown) {
; CHECK-LABEL: define float @ret_assumed_uge_known_negative(
; CHECK-SAME: float returned [[ARG:%.*]], float [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[KNOWN_POSITIVE:%.*]] = call float @llvm.fabs.f32(float [[UNKNOWN]]) #[[ATTR4]]
; CHECK-NEXT:    [[KNOWN_NEGATIVE:%.*]] = fneg float [[KNOWN_POSITIVE]]
; CHECK-NEXT:    [[UGE_KNOWN_NEGATIVE:%.*]] = fcmp uge float [[ARG]], [[KNOWN_NEGATIVE]]
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UGE_KNOWN_NEGATIVE]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %known.positive = call float @llvm.fabs.f32(float %unknown)
  %known.negative = fneg float %known.positive
  %uge.known.negative = fcmp uge float %arg, %known.negative
  call void @llvm.assume(i1 %uge.known.negative)
  ret float %arg
}

;---------------------------------------------------------------------
; assume compare to smallest normal
;---------------------------------------------------------------------

define float @assume_oeq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_oeq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_OEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.oeq.smallest.normal = fcmp oeq float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.oeq.smallest.normal)
  ret float %arg
}

define float @assume_one_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_one_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_ONE_SMALLEST_NORMAL:%.*]] = fcmp one float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_ONE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.one.smallest.normal = fcmp one float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.one.smallest.normal)
  ret float %arg
}

define float @assume_ueq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_ueq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_UEQ_SMALLEST_NORMAL:%.*]] = fcmp ueq float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_UEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.ueq.smallest.normal = fcmp ueq float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.ueq.smallest.normal)
  ret float %arg
}

define float @assume_une_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_une_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_UNE_SMALLEST_NORMAL:%.*]] = fcmp une float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_UNE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.une.smallest.normal = fcmp une float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.une.smallest.normal)
  ret float %arg
}

define float @assume_ord_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_ord_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_ORD_SMALLEST_NORMAL:%.*]] = fcmp ord float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_ORD_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.ord.smallest.normal = fcmp ord float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.ord.smallest.normal)
  ret float %arg
}

define float @assume_uno_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_uno_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_UNO_SMALLEST_NORMAL:%.*]] = fcmp uno float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_UNO_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.uno.smallest.normal = fcmp uno float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.uno.smallest.normal)
  ret float %arg
}

define float @assume_fabs_oeq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_oeq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_OEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.oeq.smallest.normal = fcmp oeq float %fabs.arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.oeq.smallest.normal)
  ret float %arg
}

define float @assume_fabs_one_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_one_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_ONE_SMALLEST_NORMAL:%.*]] = fcmp one float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_ONE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.one.smallest.normal = fcmp one float %fabs.arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.one.smallest.normal)
  ret float %arg
}

define float @assume_fabs_ueq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ueq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UEQ_SMALLEST_NORMAL:%.*]] = fcmp ueq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_UEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ueq.smallest.normal = fcmp ueq float %fabs.arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.ueq.smallest.normal)
  ret float %arg
}

define float @assume_fabs_une_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_une_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UNE_SMALLEST_NORMAL:%.*]] = fcmp une float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_UNE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.une.smallest.normal = fcmp une float %fabs.arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.une.smallest.normal)
  ret float %arg
}

define float @assume_fabs_ord_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ord_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_ORD_SMALLEST_NORMAL:%.*]] = fcmp ord float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_ORD_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.ord.smallest.normal = fcmp ord float %fabs.arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.ord.smallest.normal)
  ret float %arg
}

define float @assume_fabs_uno_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_uno_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[IS_UNO_SMALLEST_NORMAL:%.*]] = fcmp uno float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_UNO_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs.arg = call float @llvm.fabs.f32(float %arg)
  %is.uno.smallest.normal = fcmp uno float %fabs.arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.uno.smallest.normal)
  ret float %arg
}

define float @assume_oeq_smallest_normal_known_pos(float nofpclass(ninf nsub nnorm nzero) %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @assume_oeq_smallest_normal_known_pos(
; CHECK-SAME: float returned nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[ARG]], 0x3810000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_OEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %is.oeq.smallest.normal = fcmp oeq float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %is.oeq.smallest.normal)
  ret float %arg
}

;---------------------------------------------------------------------
; compare to inf
;---------------------------------------------------------------------

define float @assume_ole_pinf(float %arg) {
; CHECK-LABEL: define float @assume_ole_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FCMP:%.*]] = fcmp ole float [[ARG]], 0x7FF0000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp ole float %arg, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_ole_ninf(float %arg) {
; CHECK-LABEL: define float @assume_ole_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FCMP:%.*]] = fcmp ole float [[ARG]], 0xFFF0000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp ole float %arg, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_ugt_pinf(float %arg) {
; CHECK-LABEL: define float @assume_ugt_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FCMP:%.*]] = fcmp ugt float [[ARG]], 0x7FF0000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp ugt float %arg, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_ugt_ninf(float %arg) {
; CHECK-LABEL: define float @assume_ugt_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FCMP:%.*]] = fcmp ugt float [[ARG]], 0xFFF0000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp ugt float %arg, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_fabs_ole_pinf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ole_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FCMP:%.*]] = fcmp ole float [[FABS]], 0x7FF0000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp ole float %fabs, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_fabs_ole_ninf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ole_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp ole float %fabs, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_fabs_ugt_pinf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ugt_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT:    [[FCMP:%.*]] = fcmp ugt float [[FABS]], 0x7FF0000000000000
; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[FCMP]]) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp ugt float %fabs, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_fabs_ugt_ninf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ugt_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp ugt float %fabs, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

;---------------------------------------------------------------------
; fcmp false
;---------------------------------------------------------------------

define float @assume_fabs_false_pinf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_false_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp false float %fabs, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_fabs_false_ninf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_false_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp false float %fabs, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_false_pinf(float %arg) {
; CHECK-LABEL: define float @assume_false_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_false_ninf(float %arg) {
; CHECK-LABEL: define float @assume_false_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @clamp_false_pinf_0.0(float %arg) {
; CHECK-LABEL: define float @clamp_false_pinf_0.0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0x7FF0000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_false_ninf_0.0(float %arg) {
; CHECK-LABEL: define float @clamp_false_ninf_0.0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0xFFF0000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_false_smallest_normal_0.0(float %arg) {
; CHECK-LABEL: define float @clamp_false_smallest_normal_0.0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0x3810000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @assume_false_p0(float %arg) {
; CHECK-LABEL: define float @assume_false_p0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0.0
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_false_n0(float %arg) {
; CHECK-LABEL: define float @assume_false_n0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, -0.0
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_false_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_false_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @clamp_false_nan(float %arg) {
; CHECK-LABEL: define float @clamp_false_nan(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0x7FF8000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_false_p0(float %arg) {
; CHECK-LABEL: define float @clamp_false_p0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, 0.0
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_false_n0(float %arg) {
; CHECK-LABEL: define float @clamp_false_n0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp false float %arg, -0.0
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

;---------------------------------------------------------------------
; fcmp true
;---------------------------------------------------------------------

define float @assume_fabs_true_pinf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_true_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp true float %fabs, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_fabs_true_ninf(float %arg) {
; CHECK-LABEL: define float @assume_fabs_true_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fabs = call float @llvm.fabs.f32(float %arg)
  %fcmp = fcmp true float %fabs, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_true_pinf(float %arg) {
; CHECK-LABEL: define float @assume_true_pinf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp true float %arg, 0x7FF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_true_ninf(float %arg) {
; CHECK-LABEL: define float @assume_true_ninf(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp true float %arg, 0xFFF0000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_true_p0(float %arg) {
; CHECK-LABEL: define float @assume_true_p0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp true float %arg, 0.0
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_true_n0(float %arg) {
; CHECK-LABEL: define float @assume_true_n0(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp true float %arg, -0.0
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @assume_true_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_true_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp true float %arg, 0x3810000000000000
  call void @llvm.assume(i1 %fcmp)
  ret float %arg
}

define float @clamp_true_pinf_0.0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @clamp_true_pinf_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float 0.000000e+00
;
  %fcmp = fcmp true float %arg, 0x7FF0000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_true_ninf_0.0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @clamp_true_ninf_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float 0.000000e+00
;
  %fcmp = fcmp true float %arg, 0xFFF0000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_true_smallest_normal_0.0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @clamp_true_smallest_normal_0.0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float 0.000000e+00
;
  %fcmp = fcmp true float %arg, 0x3810000000000000
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_true_nan(float %arg) {
; CHECK-LABEL: define float @clamp_true_nan(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float [[ARG]]
;
  %fcmp = fcmp true float %arg, 0x7FF8000000000000
  %select = select i1 %fcmp, float %arg, float 0.0
  ret float %select
}

define float @clamp_true_p0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @clamp_true_p0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float 0.000000e+00
;
  %fcmp = fcmp true float %arg, 0.0
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

define float @clamp_true_n0(float %arg) {
; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @clamp_true_n0(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT:    ret float 0.000000e+00
;
  %fcmp = fcmp true float %arg, -0.0
  %select = select i1 %fcmp, float 0.0, float %arg
  ret float %select
}

;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; TUNIT: {{.*}}