Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1804,6 +1804,16 @@ return replaceInstUsesWith(I, V); } + // minumin(X, Y) + maximum(X, Y) => X + Y. + if (match(&I, + m_c_FAdd(m_Intrinsic(m_Value(X), m_Value(Y)), + m_CombineOr(m_Intrinsic(m_Deferred(X), + m_Deferred(Y)), + m_Intrinsic( + m_Deferred(Y), m_Deferred(X)))))) { + return BinaryOperator::CreateFAddFMF(X, Y, &I); + } + return nullptr; } Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -765,6 +765,16 @@ I.hasNoSignedZeros() && match(Start, m_Zero())) return replaceInstUsesWith(I, Start); + // minumin(X, Y) * maximum(X, Y) => X * Y. + if (match(&I, + m_c_FMul(m_Intrinsic(m_Value(X), m_Value(Y)), + m_CombineOr(m_Intrinsic(m_Deferred(X), + m_Deferred(Y)), + m_Intrinsic( + m_Deferred(Y), m_Deferred(X)))))) { + return BinaryOperator::CreateFMulFMF(X, Y, &I); + } + return nullptr; } Index: llvm/test/Transforms/InstCombine/fadd-maximum-minimum.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/fadd-maximum-minimum.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare float @llvm.minimum.f32(float %Val0, float %Val1) +declare float @llvm.maximum.f32(float %Val0, float %Val1) + +define float @test(float %a, float %b) { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RES:%.*]] = fadd float [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret float [[RES]] +; +entry: + %min = call float @llvm.minimum.f32(float %b, float %a) + %max = call float @llvm.maximum.f32(float %a, float %b) + %res = fadd float %min, %max + ret float %res +} Index: llvm/test/Transforms/InstCombine/fmul-maximum-minimum.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/fmul-maximum-minimum.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare float @llvm.minimum.f32(float %Val0, float %Val1) +declare float @llvm.maximum.f32(float %Val0, float %Val1) + +define float @test(float %a, float %b) { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RES:%.*]] = fmul float [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret float [[RES]] +; +entry: + %min = call float @llvm.minimum.f32(float %b, float %a) + %max = call float @llvm.maximum.f32(float %a, float %b) + %res = fmul float %min, %max + ret float %res +}