diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 6c3adf00c189a..f9cee9dfcfada 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1598,9 +1598,11 @@ Instruction *InstCombinerImpl::foldFDivConstantDivisor(BinaryOperator &I) { return BinaryOperator::CreateFDivFMF(X, NegC, &I); // nnan X / +0.0 -> copysign(inf, X) - if (I.hasNoNaNs() && match(I.getOperand(1), m_Zero())) { + // nnan nsz X / -0.0 -> copysign(inf, X) + if (I.hasNoNaNs() && + (match(I.getOperand(1), m_PosZeroFP()) || + (I.hasNoSignedZeros() && match(I.getOperand(1), m_AnyZeroFP())))) { IRBuilder<> B(&I); - // TODO: nnan nsz X / -0.0 -> copysign(inf, X) CallInst *CopySign = B.CreateIntrinsic( Intrinsic::copysign, {C->getType()}, {ConstantFP::getInfinity(I.getType()), I.getOperand(0)}, &I); diff --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll index c81a9ba6d4215..448f9f8d7dd6e 100644 --- a/llvm/test/Transforms/InstCombine/fdiv.ll +++ b/llvm/test/Transforms/InstCombine/fdiv.ll @@ -992,3 +992,75 @@ define float @fdiv_nnan_neg_zero_f32(float %x) { %fdiv = fdiv nnan float %x, -0.0 ret float %fdiv } + +define double @test_positive_zero_nsz(double %X) { +; CHECK-LABEL: @test_positive_zero_nsz( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.copysign.f64(double 0x7FF0000000000000, double [[X:%.*]]) +; CHECK-NEXT: ret double [[TMP1]] +; + %1 = fdiv nnan nsz double %X, 0.0 + ret double %1 +} + +define double @test_negative_zero_nsz(double %X) { +; CHECK-LABEL: @test_negative_zero_nsz( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz double @llvm.copysign.f64(double 0x7FF0000000000000, double [[X:%.*]]) +; CHECK-NEXT: ret double [[TMP1]] +; + %1 = fdiv nnan nsz double %X, -0.0 + ret double %1 +} + +define double @test_positive_zero(double %X) { +; CHECK-LABEL: @test_positive_zero( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan double @llvm.copysign.f64(double 0x7FF0000000000000, double [[X:%.*]]) +; CHECK-NEXT: ret double [[TMP1]] +; + %1 = fdiv nnan double %X, 0.0 + ret double %1 +} + +define double @test_negative_zero(double %X) { +; CHECK-LABEL: @test_negative_zero( +; CHECK-NEXT: [[TMP1:%.*]] = fdiv nnan double [[X:%.*]], -0.000000e+00 +; CHECK-NEXT: ret double [[TMP1]] +; + %1 = fdiv nnan double %X, -0.0 + ret double %1 +} + +define <2 x double> @test_positive_zero_vector_nsz(<2 x double> %X) { +; CHECK-LABEL: @test_positive_zero_vector_nsz( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz <2 x double> @llvm.copysign.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; CHECK-NEXT: ret <2 x double> [[TMP1]] +; + %1 = fdiv nnan nsz <2 x double> %X, + ret <2 x double> %1 +} + +define <2 x double> @test_negative_zero_vector_nsz(<2 x double> %X) { +; CHECK-LABEL: @test_negative_zero_vector_nsz( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan nsz <2 x double> @llvm.copysign.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; CHECK-NEXT: ret <2 x double> [[TMP1]] +; + %1 = fdiv nnan nsz <2 x double> %X, + ret <2 x double> %1 +} + +define <2 x double> @test_positive_zero_vector(<2 x double> %X) { +; CHECK-LABEL: @test_positive_zero_vector( +; CHECK-NEXT: [[TMP1:%.*]] = call nnan <2 x double> @llvm.copysign.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; CHECK-NEXT: ret <2 x double> [[TMP1]] +; + %1 = fdiv nnan <2 x double> %X, + ret <2 x double> %1 +} + +define <2 x double> @test_negative_zero_vector(<2 x double> %X) { +; CHECK-LABEL: @test_negative_zero_vector( +; CHECK-NEXT: [[TMP1:%.*]] = fdiv nnan <2 x double> [[X:%.*]], +; CHECK-NEXT: ret <2 x double> [[TMP1]] +; + %1 = fdiv nnan <2 x double> %X, + ret <2 x double> %1 +}