[llvm] ae542d9 - ValueTracking: Add baseline test for fcmp implying classes

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 7 10:30:22 PDT 2023


Author: Matt Arsenault
Date: 2023-09-07T20:30:15+03:00
New Revision: ae542d979de98f15a04c5f938ce2fb560d1fce28

URL: https://github.com/llvm/llvm-project/commit/ae542d979de98f15a04c5f938ce2fb560d1fce28
DIFF: https://github.com/llvm/llvm-project/commit/ae542d979de98f15a04c5f938ce2fb560d1fce28.diff

LOG: ValueTracking: Add baseline test for fcmp implying classes

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

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll b/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll
new file mode 100644
index 00000000000000..19a518a44d48e5
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/nofpclass-implied-by-fcmp.ll
@@ -0,0 +1,2171 @@
+; 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
+define float @fcmp_one_1_1_else_arg(float %arg) {
+; CHECK-LABEL: define 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 float @clamp_ogt_largest_denormal_0.0(
+; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[IS_OGT_LARGEST_DENORMAL:%.*]] = fcmp ugt 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 ugt 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 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 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 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 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
+}
+
+;---------------------------------------------------------------------
+; clamp fabs to 1 copysign
+;---------------------------------------------------------------------
+
+; can't be inf
+define float @clamp_fabs_value_ogt_1_to_1_copysign(float %arg) {
+; CHECK-LABEL: define 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
+}
+
+;---------------------------------------------------------------------
+; 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 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 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 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 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 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 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
+}
+
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; TUNIT: {{.*}}


        


More information about the llvm-commits mailing list