Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1615,21 +1615,6 @@ break; } - - case Intrinsic::minnum: - case Intrinsic::maxnum: { - Value *Arg0 = II->getArgOperand(0); - Value *Arg1 = II->getArgOperand(1); - // Canonicalize constants to the RHS. - if (isa(Arg0) && !isa(Arg1)) { - II->setArgOperand(0, Arg1); - II->setArgOperand(1, Arg0); - return II; - } - if (Value *V = simplifyMinnumMaxnum(*II)) - return replaceInstUsesWith(*II, V); - break; - } case Intrinsic::fma: case Intrinsic::fmuladd: { Value *Src0 = II->getArgOperand(0); @@ -1715,11 +1700,29 @@ break; } + case Intrinsic::minnum: + case Intrinsic::maxnum: { + Value *Arg0 = II->getArgOperand(0); + Value *Arg1 = II->getArgOperand(1); + + // Canonicalize constants to the RHS. + if (match(Arg0, m_Constant()) && !match(Arg1, m_Constant())) { + II->setArgOperand(0, Arg1); + II->setArgOperand(1, Arg0); + return II; + } + if (Value *V = simplifyMinnumMaxnum(*II)) + return replaceInstUsesWith(*II, V); + + LLVM_FALLTHROUGH; + } case Intrinsic::copysign: { Value *ExtSrc0; Value *ExtSrc1; // copysign (fpext x), (fpext y) -> copysign x, y + // minnum (fpext x), (fpext y) -> minnum x, y + // maxnum (fpext x), (fpext y) -> maxnum x, y if (match(II->getArgOperand(0), m_FPExt(m_Value(ExtSrc0))) && match(II->getArgOperand(1), m_FPExt(m_Value(ExtSrc1))) && ExtSrc0->getType() == ExtSrc1->getType()) { Index: test/Transforms/InstCombine/maxnum.ll =================================================================== --- test/Transforms/InstCombine/maxnum.ll +++ test/Transforms/InstCombine/maxnum.ll @@ -1,7 +1,7 @@ ; RUN: opt -S -instcombine < %s | FileCheck %s declare float @llvm.maxnum.f32(float, float) #0 -declare float @llvm.maxnum.v2f32(<2 x float>, <2 x float>) #0 +declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>) #0 declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>) #0 declare double @llvm.maxnum.f64(double, double) #0 @@ -154,6 +154,13 @@ ret float %val } +; CHECK-LABEL: @canonicalize_constant_maxnum_v2f32( +; CHECK: call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> ) +define <2 x float> @canonicalize_constant_maxnum_v2f32(<2 x float> %x) #0 { + %y = call <2 x float> @llvm.maxnum.v2f32(<2 x float> , <2 x float> %x) #0 + ret <2 x float> %y +} + ; CHECK-LABEL: @maxnum_x_maxnum_x_y ; CHECK-NEXT: call float @llvm.maxnum.f32(float %x, float %y) ; CHECK-NEXT: ret float @@ -219,4 +226,26 @@ ret float %val } +; CHECK-LABEL: @reduce_precision( +; CHECK: %maxnum = call float @llvm.maxnum.f32(float %x, float %y) +; CHECK-NEXT: ret float %maxnum +define float @reduce_precision(float %x, float %y) { + %x.ext = fpext float %x to double + %y.ext = fpext float %y to double + %maxnum = call double @llvm.maxnum.f64(double %x.ext, double %y.ext) + %trunc = fptrunc double %maxnum to float + ret float %trunc +} + +; CHECK-LABEL: @reduce_precision_fmf( +; CHECK: %maxnum = call nnan float @llvm.maxnum.f32(float %x, float %y) +; CHECK-NEXT: ret float %maxnum +define float @reduce_precision_fmf(float %x, float %y) { + %x.ext = fpext float %x to double + %y.ext = fpext float %y to double + %maxnum = call nnan double @llvm.maxnum.f64(double %x.ext, double %y.ext) + %trunc = fptrunc double %maxnum to float + ret float %trunc +} + attributes #0 = { nounwind readnone } Index: test/Transforms/InstCombine/minnum.ll =================================================================== --- test/Transforms/InstCombine/minnum.ll +++ test/Transforms/InstCombine/minnum.ll @@ -1,7 +1,7 @@ ; RUN: opt -S -instcombine < %s | FileCheck %s declare float @llvm.minnum.f32(float, float) #0 -declare float @llvm.minnum.v2f32(<2 x float>, <2 x float>) #0 +declare <2 x float> @llvm.minnum.v2f32(<2 x float>, <2 x float>) #0 declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>) #0 declare double @llvm.minnum.f64(double, double) #0 @@ -156,6 +156,13 @@ ret float %val } +; CHECK-LABEL: @canonicalize_constant_minnum_v2f32( +; CHECK: call <2 x float> @llvm.minnum.v2f32(<2 x float> %x, <2 x float> ) +define <2 x float> @canonicalize_constant_minnum_v2f32(<2 x float> %x) #0 { + %y = call <2 x float> @llvm.minnum.v2f32(<2 x float> , <2 x float> %x) #0 + ret <2 x float> %y +} + ; CHECK-LABEL: @minnum_x_minnum_x_y ; CHECK-NEXT: call float @llvm.minnum.f32(float %x, float %y) ; CHECK-NEXT: ret float @@ -241,4 +248,26 @@ ret float %val } +; CHECK-LABEL: @reduce_precision( +; CHECK: %minnum = call float @llvm.minnum.f32(float %x, float %y) +; CHECK-NEXT: ret float %minnum +define float @reduce_precision(float %x, float %y) { + %x.ext = fpext float %x to double + %y.ext = fpext float %y to double + %minnum = call double @llvm.minnum.f64(double %x.ext, double %y.ext) + %trunc = fptrunc double %minnum to float + ret float %trunc +} + +; CHECK-LABEL: @reduce_precision_fmf( +; CHECK: %minnum = call nnan float @llvm.minnum.f32(float %x, float %y) +; CHECK-NEXT: ret float %minnum +define float @reduce_precision_fmf(float %x, float %y) { + %x.ext = fpext float %x to double + %y.ext = fpext float %y to double + %minnum = call nnan double @llvm.minnum.f64(double %x.ext, double %y.ext) + %trunc = fptrunc double %minnum to float + ret float %trunc +} + attributes #0 = { nounwind readnone }