From fbc2c8f2fbbb7fbc9a88ad64ac83de888d505d27 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 10 Nov 2022 17:10:46 -0500 Subject: [PATCH] [InstSimplify] fold X +nnan Inf If we exclude NaN (and therefore the opposite Inf), anything plus Inf is Inf: https://alive2.llvm.org/ce/z/og3dj9 --- llvm/lib/Analysis/InstructionSimplify.cpp | 18 +++++++++++------- .../InstSimplify/floating-point-arithmetic.ll | 14 ++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index c8b796a..b134234 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -5245,14 +5245,18 @@ simplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF, if (!isDefaultFPEnvironment(ExBehavior, Rounding)) return nullptr; - // With nnan: -X + X --> 0.0 (and commuted variant) - // We don't have to explicitly exclude infinities (ninf): INF + -INF == NaN. - // Negative zeros are allowed because we always end up with positive zero: - // X = -0.0: (-0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0 - // X = -0.0: ( 0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0 - // X = 0.0: (-0.0 - ( 0.0)) + ( 0.0) == (-0.0) + ( 0.0) == 0.0 - // X = 0.0: ( 0.0 - ( 0.0)) + ( 0.0) == ( 0.0) + ( 0.0) == 0.0 if (FMF.noNaNs()) { + // With nnan: X + {+/-}Inf --> {+/-}Inf + if (match(Op1, m_Inf())) + return Op1; + + // With nnan: -X + X --> 0.0 (and commuted variant) + // We don't have to explicitly exclude infinities (ninf): INF + -INF == NaN. + // Negative zeros are allowed because we always end up with positive zero: + // X = -0.0: (-0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0 + // X = -0.0: ( 0.0 - (-0.0)) + (-0.0) == ( 0.0) + (-0.0) == 0.0 + // X = 0.0: (-0.0 - ( 0.0)) + ( 0.0) == (-0.0) + ( 0.0) == 0.0 + // X = 0.0: ( 0.0 - ( 0.0)) + ( 0.0) == ( 0.0) + ( 0.0) == 0.0 if (match(Op0, m_FSub(m_AnyZeroFP(), m_Specific(Op1))) || match(Op1, m_FSub(m_AnyZeroFP(), m_Specific(Op0)))) return ConstantFP::getNullValue(Op0->getType()); diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll index 10a709e..14d179d 100644 --- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll +++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll @@ -818,8 +818,7 @@ define float @maxnum_with_pos_one_op(float %a) { define double @fadd_nnan_inf_op0(double %x) { ; CHECK-LABEL: @fadd_nnan_inf_op0( -; CHECK-NEXT: [[R:%.*]] = fadd nnan double 0x7FF0000000000000, [[X:%.*]] -; CHECK-NEXT: ret double [[R]] +; CHECK-NEXT: ret double 0x7FF0000000000000 ; %r = fadd nnan double 0x7ff0000000000000, %x ret double %r @@ -827,8 +826,7 @@ define double @fadd_nnan_inf_op0(double %x) { define double @fadd_nnan_inf_op1(double %x) { ; CHECK-LABEL: @fadd_nnan_inf_op1( -; CHECK-NEXT: [[R:%.*]] = fadd nnan double [[X:%.*]], 0x7FF0000000000000 -; CHECK-NEXT: ret double [[R]] +; CHECK-NEXT: ret double 0x7FF0000000000000 ; %r = fadd nnan double %x, 0x7ff0000000000000 ret double %r @@ -836,8 +834,7 @@ define double @fadd_nnan_inf_op1(double %x) { define <2 x double> @fadd_nnan_neginf_op1(<2 x double> %x) { ; CHECK-LABEL: @fadd_nnan_neginf_op1( -; CHECK-NEXT: [[R:%.*]] = fadd nnan <2 x double> [[X:%.*]], -; CHECK-NEXT: ret <2 x double> [[R]] +; CHECK-NEXT: ret <2 x double> ; %r = fadd nnan <2 x double> %x, ret <2 x double> %r @@ -845,13 +842,14 @@ define <2 x double> @fadd_nnan_neginf_op1(<2 x double> %x) { define double @fadd_nnan_neginf_op0(double %x) { ; CHECK-LABEL: @fadd_nnan_neginf_op0( -; CHECK-NEXT: [[R:%.*]] = fadd nnan double 0xFFF0000000000000, [[X:%.*]] -; CHECK-NEXT: ret double [[R]] +; CHECK-NEXT: ret double 0xFFF0000000000000 ; %r = fadd nnan double 0xfff0000000000000, %x ret double %r } +; negative test - requires nnan + define double @fadd_inf_op0(double %x) { ; CHECK-LABEL: @fadd_inf_op0( ; CHECK-NEXT: [[R:%.*]] = fadd double 0x7FF0000000000000, [[X:%.*]] -- 2.7.4