Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions clang/test/Headers/__clang_hip_math.hip
Original file line number Diff line number Diff line change
Expand Up @@ -8734,47 +8734,42 @@ extern "C" __device__ float test___powf(float x, float y) {
}

// DEFAULT-LABEL: define dso_local noundef float @test___saturatef(
// DEFAULT-SAME: float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR3]] {
// DEFAULT-SAME: float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// DEFAULT-NEXT: [[ENTRY:.*:]]
// DEFAULT-NEXT: [[CMP_I:%.*]] = fcmp contract olt float [[X]], 0.000000e+00
// DEFAULT-NEXT: [[CMP1_I:%.*]] = fcmp contract ogt float [[X]], 1.000000e+00
// DEFAULT-NEXT: [[COND_I:%.*]] = select contract i1 [[CMP1_I]], float 1.000000e+00, float [[X]]
// DEFAULT-NEXT: [[COND_I:%.*]] = tail call contract float @llvm.minnum.f32(float [[X]], float 1.000000e+00)
// DEFAULT-NEXT: [[COND5_I:%.*]] = select contract i1 [[CMP_I]], float 0.000000e+00, float [[COND_I]]
// DEFAULT-NEXT: ret float [[COND5_I]]
//
// FINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @test___saturatef(
// FINITEONLY-SAME: float noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR3]] {
// FINITEONLY-SAME: float noundef nofpclass(nan inf) [[X:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// FINITEONLY-NEXT: [[ENTRY:.*:]]
// FINITEONLY-NEXT: [[CMP_I:%.*]] = fcmp nnan ninf contract olt float [[X]], 0.000000e+00
// FINITEONLY-NEXT: [[CMP1_I:%.*]] = fcmp nnan ninf contract ogt float [[X]], 1.000000e+00
// FINITEONLY-NEXT: [[COND_I:%.*]] = select nnan ninf contract i1 [[CMP1_I]], float 1.000000e+00, float [[X]]
// FINITEONLY-NEXT: [[COND_I:%.*]] = tail call nnan ninf contract float @llvm.minnum.f32(float nofpclass(nan inf) [[X]], float 1.000000e+00)
// FINITEONLY-NEXT: [[COND5_I:%.*]] = select nnan ninf contract i1 [[CMP_I]], float 0.000000e+00, float [[COND_I]]
// FINITEONLY-NEXT: ret float [[COND5_I]]
//
// APPROX-LABEL: define dso_local noundef float @test___saturatef(
// APPROX-SAME: float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR3]] {
// APPROX-SAME: float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// APPROX-NEXT: [[ENTRY:.*:]]
// APPROX-NEXT: [[CMP_I:%.*]] = fcmp contract olt float [[X]], 0.000000e+00
// APPROX-NEXT: [[CMP1_I:%.*]] = fcmp contract ogt float [[X]], 1.000000e+00
// APPROX-NEXT: [[COND_I:%.*]] = select contract i1 [[CMP1_I]], float 1.000000e+00, float [[X]]
// APPROX-NEXT: [[COND_I:%.*]] = tail call contract float @llvm.minnum.f32(float [[X]], float 1.000000e+00)
// APPROX-NEXT: [[COND5_I:%.*]] = select contract i1 [[CMP_I]], float 0.000000e+00, float [[COND_I]]
// APPROX-NEXT: ret float [[COND5_I]]
//
// NCRDIV-LABEL: define dso_local noundef float @test___saturatef(
// NCRDIV-SAME: float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR3]] {
// NCRDIV-SAME: float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// NCRDIV-NEXT: [[ENTRY:.*:]]
// NCRDIV-NEXT: [[CMP_I:%.*]] = fcmp contract olt float [[X]], 0.000000e+00
// NCRDIV-NEXT: [[CMP1_I:%.*]] = fcmp contract ogt float [[X]], 1.000000e+00
// NCRDIV-NEXT: [[COND_I:%.*]] = select contract i1 [[CMP1_I]], float 1.000000e+00, float [[X]]
// NCRDIV-NEXT: [[COND_I:%.*]] = tail call contract float @llvm.minnum.f32(float [[X]], float 1.000000e+00)
// NCRDIV-NEXT: [[COND5_I:%.*]] = select contract i1 [[CMP_I]], float 0.000000e+00, float [[COND_I]]
// NCRDIV-NEXT: ret float [[COND5_I]]
//
// AMDGCNSPIRV-LABEL: define spir_func noundef float @test___saturatef(
// AMDGCNSPIRV-SAME: float noundef [[X:%.*]]) local_unnamed_addr addrspace(4) #[[ATTR3]] {
// AMDGCNSPIRV-SAME: float noundef [[X:%.*]]) local_unnamed_addr addrspace(4) #[[ATTR2:[0-9]+]] {
// AMDGCNSPIRV-NEXT: [[ENTRY:.*:]]
// AMDGCNSPIRV-NEXT: [[CMP_I:%.*]] = fcmp contract olt float [[X]], 0.000000e+00
// AMDGCNSPIRV-NEXT: [[CMP1_I:%.*]] = fcmp contract ogt float [[X]], 1.000000e+00
// AMDGCNSPIRV-NEXT: [[COND_I:%.*]] = select contract i1 [[CMP1_I]], float 1.000000e+00, float [[X]]
// AMDGCNSPIRV-NEXT: [[COND_I:%.*]] = tail call contract addrspace(4) float @llvm.minnum.f32(float [[X]], float 1.000000e+00)
// AMDGCNSPIRV-NEXT: [[COND5_I:%.*]] = select contract i1 [[CMP_I]], float 0.000000e+00, float [[COND_I]]
// AMDGCNSPIRV-NEXT: ret float [[COND5_I]]
//
Expand Down
58 changes: 58 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3963,6 +3963,61 @@ static Value *foldSelectIntoAddConstant(SelectInst &SI,
return nullptr;
}

// fcmp + sel patterns into max/min intrinsic.
static Value *foldSelectICmpIntoMaxMin(SelectInst &SI,
InstCombiner::BuilderTy &Builder) {

auto TryFoldIntoMaxMinIntrinsic =
[&Builder, &SI](CmpInst::Predicate Pred, Value *CmpLHS, Value *CmpRHS,
Value *TVal, Value *FVal) -> Value * {
// Early exit if the operands are not in the expected form.
if ((CmpRHS != TVal || CmpLHS != FVal) &&
(CmpLHS != TVal || CmpRHS != FVal))
return nullptr;

bool isSwapped = (CmpLHS == FVal && CmpRHS == TVal);
// Only these relational predicates can be transformed into maxnum/minnum
// intrinsic.
// X > C ? X : C --> maxnum(X, C)
// X > C ? C : X --> minnum(X, C)
if (Pred == CmpInst::FCMP_OGT) {
Intrinsic::ID MaxMinIID =
isSwapped ? Intrinsic::minnum : Intrinsic::maxnum;
return Builder.CreateIntrinsic(SI.getType(), MaxMinIID, {TVal, FVal},
&SI);
}

// X < C ? X : C --> minnum(X, C)
// X < C ? C : X --> maxnum(X, C)
if (Pred == CmpInst::FCMP_OLT) {
Intrinsic::ID MaxMinIID =
isSwapped ? Intrinsic::maxnum : Intrinsic::minnum;
return Builder.CreateIntrinsic(SI.getType(), MaxMinIID, {TVal, FVal},
&SI);
}

return nullptr;
};

// select((fcmp Pred, X, Y), X, Y)
// => minnum/maxnum(X, Y)
//
// Pred := OGT and OLT
Value *X, *Y;
Value *TVal, *FVal;
CmpPredicate Pred;

// Note: OneUse check for `Cmp` is necessary because it makes sure that other
// InstCombine folds don't undo this transformation and cause an infinite
// loop. Furthermore, it could also increase the operation count.
if (match(&SI,
m_OneUse(m_Select(m_OneUse(m_FCmp(Pred, m_Value(X), m_Value(Y))),
m_Value(TVal), m_Value(FVal)))))
return TryFoldIntoMaxMinIntrinsic(Pred, X, Y, TVal, FVal);

return nullptr;
}

static Value *foldSelectBitTest(SelectInst &Sel, Value *CondVal, Value *TrueVal,
Value *FalseVal,
InstCombiner::BuilderTy &Builder,
Expand Down Expand Up @@ -4455,6 +4510,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (Value *V = foldSelectIntoAddConstant(SI, Builder))
return replaceInstUsesWith(SI, V);

if (Value *V = foldSelectICmpIntoMaxMin(SI, Builder))
return replaceInstUsesWith(SI, V);

// select(mask, mload(,,mask,0), 0) -> mload(,,mask,0)
// Load inst is intentionally not checked for hasOneUse()
if (match(FalseVal, m_Zero()) &&
Expand Down
64 changes: 24 additions & 40 deletions llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
; (X < C1) ? C1 : MIN(X, C2)
define float @clamp_float_fast_ordered_strict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_strict_maxmin(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast olt float [[X]], 1.000000e+00
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast olt float %x, 255.0
Expand All @@ -21,10 +20,9 @@ define float @clamp_float_fast_ordered_strict_maxmin(float %x) {
; (X <= C1) ? C1 : MIN(X, C2)
define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_maxmin(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ole float [[X]], 1.000000e+00
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast olt float %x, 255.0
Expand All @@ -37,10 +35,9 @@ define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) {
; (X > C1) ? C1 : MAX(X, C2)
define float @clamp_float_fast_ordered_strict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_strict_minmax(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ogt float [[X]], 2.550000e+02
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast ogt float %x, 1.0
Expand All @@ -53,10 +50,9 @@ define float @clamp_float_fast_ordered_strict_minmax(float %x) {
; (X >= C1) ? C1 : MAX(X, C2)
define float @clamp_float_fast_ordered_nonstrict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_minmax(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast oge float [[X]], 2.550000e+02
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast ogt float %x, 1.0
Expand Down Expand Up @@ -191,8 +187,7 @@ define float @clamp_negative_same_op(float %x) {
; First, check that we don't do bad things in the presence of signed zeros
define float @clamp_float_with_zero1(float %x) {
; CHECK-LABEL: @clamp_float_with_zero1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ole float [[X]], 0.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 0.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
Expand All @@ -206,8 +201,7 @@ define float @clamp_float_with_zero1(float %x) {

define float @clamp_float_with_zero2(float %x) {
; CHECK-LABEL: @clamp_float_with_zero2(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 0.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 0.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
Expand All @@ -228,8 +222,7 @@ define float @clamp_float_with_zero2(float %x) {
; (X < C1) ? C1 : MIN(X, C2)
define float @clamp_float_ordered_strict_maxmin1(float %x) {
; CHECK-LABEL: @clamp_float_ordered_strict_maxmin1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -259,8 +252,7 @@ define float @clamp_float_ordered_strict_maxmin2(float %x) {
; (X <= C1) ? C1 : MIN(X, C2)
define float @clamp_float_ordered_nonstrict_maxmin1(float %x) {
; CHECK-LABEL: @clamp_float_ordered_nonstrict_maxmin1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ole float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -290,8 +282,7 @@ define float @clamp_float_ordered_nonstrict_maxmin2(float %x) {
; (X > C1) ? C1 : MAX(X, C2)
define float @clamp_float_ordered_strict_minmax1(float %x) {
; CHECK-LABEL: @clamp_float_ordered_strict_minmax1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[X]], 2.550000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -321,8 +312,7 @@ define float @clamp_float_ordered_strict_minmax2(float %x) {
; (X >= C1) ? C1 : MAX(X, C2)
define float @clamp_float_ordered_nonstrict_minmax1(float %x) {
; CHECK-LABEL: @clamp_float_ordered_nonstrict_minmax1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp oge float [[X]], 2.550000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -355,8 +345,7 @@ define float @clamp_float_ordered_nonstrict_minmax2(float %x) {
; (X < C1) ? C1 : MIN(X, C2)
define float @clamp_float_unordered_strict_maxmin1(float %x) {
; CHECK-LABEL: @clamp_float_unordered_strict_maxmin1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ult float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -386,8 +375,7 @@ define float @clamp_float_unordered_strict_maxmin2(float %x) {
; (X <= C1) ? C1 : MIN(X, C2)
define float @clamp_float_unordered_nonstrict_maxmin1(float %x) {
; CHECK-LABEL: @clamp_float_unordered_nonstrict_maxmin1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ule float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -417,8 +405,7 @@ define float @clamp_float_unordered_nonstrict_maxmin2(float %x) {
; (X > C1) ? C1 : MAX(X, C2)
define float @clamp_float_unordered_strict_minmax1(float %x) {
; CHECK-LABEL: @clamp_float_unordered_strict_minmax1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ugt float [[X]], 2.550000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -448,8 +435,7 @@ define float @clamp_float_unordered_strict_minmax2(float %x) {
; (X >= C1) ? C1 : MAX(X, C2)
define float @clamp_float_unordered_nonstrict_minmax1(float %x) {
; CHECK-LABEL: @clamp_float_unordered_nonstrict_minmax1(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
; CHECK-NEXT: [[CMP1:%.*]] = fcmp uge float [[X]], 2.550000e+02
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
Expand Down Expand Up @@ -527,8 +513,7 @@ define float @mixed_clamp_to_float_1(i32 %x) {

define i32 @mixed_clamp_to_i32_1(float %x) {
; CHECK-LABEL: @mixed_clamp_to_i32_1(
; CHECK-NEXT: [[FLOAT_MIN_CMP:%.*]] = fcmp ogt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = select i1 [[FLOAT_MIN_CMP]], float 2.550000e+02, float [[X]]
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[I32_MIN:%.*]] = fptosi float [[FLOAT_MIN]] to i32
; CHECK-NEXT: [[I32_X:%.*]] = fptosi float [[X]] to i32
; CHECK-NEXT: [[LO_CMP:%.*]] = icmp eq i32 [[I32_X]], 0
Expand Down Expand Up @@ -561,8 +546,7 @@ define float @mixed_clamp_to_float_2(i32 %x) {

define i32 @mixed_clamp_to_i32_2(float %x) {
; CHECK-LABEL: @mixed_clamp_to_i32_2(
; CHECK-NEXT: [[FLOAT_MIN_CMP:%.*]] = fcmp ogt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = select i1 [[FLOAT_MIN_CMP]], float 2.550000e+02, float [[X]]
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
; CHECK-NEXT: [[I32_MIN:%.*]] = fptosi float [[FLOAT_MIN]] to i32
; CHECK-NEXT: [[LO_CMP:%.*]] = fcmp olt float [[X]], 1.000000e+00
; CHECK-NEXT: [[R:%.*]] = select i1 [[LO_CMP]], i32 1, i32 [[I32_MIN]]
Expand Down
9 changes: 3 additions & 6 deletions llvm/test/Transforms/InstCombine/fcmp-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,8 @@ define <2 x i1> @test_fcmp_select_const_const_vec(<2 x double> %x) {

define double @test_fcmp_select_clamp(double %x) {
; CHECK-LABEL: @test_fcmp_select_clamp(
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt double [[X:%.*]], 9.000000e-01
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], double 9.000000e-01, double [[X]]
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt double [[SEL1]], 5.000000e-01
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], double 5.000000e-01, double [[SEL1]]
; CHECK-NEXT: [[SEL1:%.*]] = call double @llvm.minnum.f64(double [[X:%.*]], double 9.000000e-01)
; CHECK-NEXT: [[SEL2:%.*]] = call double @llvm.maxnum.f64(double [[SEL1]], double 5.000000e-01)
; CHECK-NEXT: ret double [[SEL2]]
;
%cmp1 = fcmp ogt double %x, 9.000000e-01
Expand Down Expand Up @@ -284,8 +282,7 @@ define i1 @test_fcmp_ord_select_fcmp_oeq_var_const(double %x) {

define float @test_select_nnan_nsz_fcmp_olt(float %x) {
; CHECK-LABEL: @test_select_nnan_nsz_fcmp_olt(
; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
; CHECK-NEXT: [[SEL1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float -0.000000e+00)
; CHECK-NEXT: ret float [[SEL1]]
;
%cmp = fcmp olt float %x, 0.000000e+00
Expand Down
Loading