From 8a8bb45a76b221b06cc9fe0f9067afca10474d72 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Tue, 16 Jun 2015 14:57:29 +0000 Subject: [PATCH] [InstSimplify] Allow folding of fdiv X, X with just NaNs ignored Any combination of +-inf/+-inf is NaN so it's already ignored with nnan and we can skip checking for ninf. Also rephrase logic in comments a bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239821 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/InstructionSimplify.cpp | 6 +- test/Transforms/InstSimplify/fast-math.ll | 68 ++++++++--------------- 2 files changed, 27 insertions(+), 47 deletions(-) diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 8f7a940aa95..12e406bb1a2 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1126,13 +1126,13 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZero())) return Op0; - if (FMF.noNaNs() && FMF.noInfs()) { - // X / X -> 1.0 iff NaNs and infinities are ignored. + if (FMF.noNaNs()) { + // X / X -> 1.0 is legal when NaNs are ignored. if (Op0 == Op1) return ConstantFP::get(Op0->getType(), 1.0); // -X / X -> -1.0 and - // X / -X -> -1.0 iff NaNs and infinities are ignored. + // X / -X -> -1.0 are legal when NaNs are ignored. // We can ignore signed zeros because +-0.0/+-0.0 is NaN and ignored. if ((BinaryOperator::isFNeg(Op0, /*IgnoreZeroSign=*/true) && BinaryOperator::getFNegArgument(Op0) == Op1) || diff --git a/test/Transforms/InstSimplify/fast-math.ll b/test/Transforms/InstSimplify/fast-math.ll index c9ae7ef0f09..90532fa5db8 100644 --- a/test/Transforms/InstSimplify/fast-math.ll +++ b/test/Transforms/InstSimplify/fast-math.ll @@ -115,79 +115,59 @@ define double @fdiv_zero_by_x(double %X) { ; CHECK: ret double 0 } -define float @fdiv_self(float %f) { - %div = fdiv nnan ninf float %f, %f +define float @fdiv_self(float %f) { + %div = fdiv nnan float %f, %f ret float %div ; CHECK-LABEL: fdiv_self ; CHECK: ret float 1.000000e+00 } -define float @fdiv_self_invalid1(float %f) { - %div = fdiv ninf float %f, %f - ret float %div -; CHECK-LABEL: fdiv_self_invalid1 -; CHECK: %div = fdiv ninf float %f, %f -; CHECK-NEXT: ret float %div -} - -define float @fdiv_self_invalid2(float %f) { - %div = fdiv nnan float %f, %f - ret float %div -; CHECK-LABEL: fdiv_self_invalid2 -; CHECK: %div = fdiv nnan float %f, %f -; CHECK-NEXT: ret float %div -} - -define float @fdiv_self_invalid3(float %f) { +define float @fdiv_self_invalid(float %f) { %div = fdiv float %f, %f ret float %div -; CHECK-LABEL: fdiv_self_invalid3 +; CHECK-LABEL: fdiv_self_invalid ; CHECK: %div = fdiv float %f, %f ; CHECK-NEXT: ret float %div } -define float @fdiv_neg(float %f) { +define float @fdiv_neg1(float %f) { %neg = fsub fast float -0.000000e+00, %f - %div = fdiv nnan ninf float %neg, %f + %div = fdiv nnan float %neg, %f ret float %div -; CHECK-LABEL: fdiv_neg +; CHECK-LABEL: fdiv_neg1 ; CHECK: ret float -1.000000e+00 } -define float @fdiv_neg_invalid1(float %f) { - %neg = fsub fast float -0.000000e+00, %f - %div = fdiv ninf float %neg, %f - ret float %div -; CHECK-LABEL: fdiv_neg_invalid1 -; CHECK: %neg = fsub fast float -0.000000e+00, %f -; CHECK-NEXT: %div = fdiv ninf float %neg, %f -; CHECK-NEXT: ret float %div -} - -define float @fdiv_neg_invalid2(float %f) { - %neg = fsub fast float -0.000000e+00, %f +define float @fdiv_neg2(float %f) { + %neg = fsub fast float 0.000000e+00, %f %div = fdiv nnan float %neg, %f ret float %div -; CHECK-LABEL: fdiv_neg_invalid2 -; CHECK: %neg = fsub fast float -0.000000e+00, %f -; CHECK-NEXT: %div = fdiv nnan float %neg, %f -; CHECK-NEXT: ret float %div +; CHECK-LABEL: fdiv_neg2 +; CHECK: ret float -1.000000e+00 } -define float @fdiv_neg_invalid3(float %f) { +define float @fdiv_neg_invalid(float %f) { %neg = fsub fast float -0.000000e+00, %f %div = fdiv float %neg, %f ret float %div -; CHECK-LABEL: fdiv_neg_invalid3 +; CHECK-LABEL: fdiv_neg_invalid ; CHECK: %neg = fsub fast float -0.000000e+00, %f ; CHECK-NEXT: %div = fdiv float %neg, %f ; CHECK-NEXT: ret float %div } -define float @fdiv_neg_swapped(float %f) { +define float @fdiv_neg_swapped1(float %f) { + %neg = fsub float -0.000000e+00, %f + %div = fdiv nnan float %f, %neg + ret float %div +; CHECK-LABEL: fdiv_neg_swapped1 +; CHECK: ret float -1.000000e+00 +} + +define float @fdiv_neg_swapped2(float %f) { %neg = fsub float 0.000000e+00, %f - %div = fdiv nnan ninf float %f, %neg + %div = fdiv nnan float %f, %neg ret float %div -; CHECK-LABEL: fdiv_neg_swapped +; CHECK-LABEL: fdiv_neg_swapped2 ; CHECK: ret float -1.000000e+00 } -- 2.34.1