diff options
-rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 22 | ||||
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 16 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/fast-math.ll | 18 |
3 files changed, 22 insertions, 34 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 20bdcddad4b..fec89dc8e01 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -144,19 +144,6 @@ struct match_zero { /// zero_initializer for vectors and ConstantPointerNull for pointers. inline match_zero m_Zero() { return match_zero(); } -struct match_any_zero { - template <typename ITy> bool match(ITy *V) { - if (const auto *C = dyn_cast<Constant>(V)) - return C->isZeroValue(); - return false; - } -}; - -/// Match an arbitrary zero/null constant. This includes -/// zero_initializer for vectors and ConstantPointerNull for pointers. For -/// floating point constants, this will match negative zero and positive zero -inline match_any_zero m_AnyZero() { return match_any_zero(); } - struct apint_match { const APInt *&Res; @@ -419,6 +406,15 @@ inline cstfp_pred_ty<is_nan> m_NaN() { return cstfp_pred_ty<is_nan>(); } +struct is_any_zero_fp { + bool isValue(const APFloat &C) { return C.isZero(); } +}; + +/// Match a floating-point negative zero or positive zero +inline cstfp_pred_ty<is_any_zero_fp> m_AnyZeroFP() { + return cstfp_pred_ty<is_any_zero_fp>(); +} + /////////////////////////////////////////////////////////////////////////////// template <typename Class> struct bind_ty { diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 773c3ec0f6e..5e43cb7cec1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4175,8 +4175,8 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF, // 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() && (match(Op0, m_FSub(m_AnyZero(), m_Specific(Op1))) || - match(Op1, m_FSub(m_AnyZero(), m_Specific(Op0))))) + if (FMF.noNaNs() && (match(Op0, m_FSub(m_AnyZeroFP(), m_Specific(Op1))) || + match(Op1, m_FSub(m_AnyZeroFP(), m_Specific(Op0))))) return ConstantFP::getNullValue(Op0->getType()); return nullptr; @@ -4207,8 +4207,8 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF, return X; // fsub 0.0, (fsub 0.0, X) ==> X if signed zeros are ignored. - if (FMF.noSignedZeros() && match(Op0, m_AnyZero()) && - match(Op1, m_FSub(m_AnyZero(), m_Value(X)))) + if (FMF.noSignedZeros() && match(Op0, m_AnyZeroFP()) && + match(Op1, m_FSub(m_AnyZeroFP(), m_Value(X)))) return X; // fsub nnan x, x ==> 0.0 @@ -4232,8 +4232,8 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF, return Op0; // fmul nnan nsz X, 0 ==> 0 - if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZero())) - return Op1; + if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZeroFP())) + return ConstantFP::getNullValue(Op0->getType()); // sqrt(X) * sqrt(X) --> X Value *X; @@ -4275,8 +4275,8 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF, // 0 / X -> 0 // Requires that NaNs are off (X could be zero) and signed zeroes are // ignored (X could be positive or negative, so the output sign is unknown). - if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZero())) - return Op0; + if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op0, m_AnyZeroFP())) + return ConstantFP::getNullValue(Op0->getType()); if (FMF.noNaNs()) { // X / X -> 1.0 is legal when NaNs are ignored. diff --git a/llvm/test/Transforms/InstSimplify/fast-math.ll b/llvm/test/Transforms/InstSimplify/fast-math.ll index bed39fbc836..493d7e1f60e 100644 --- a/llvm/test/Transforms/InstSimplify/fast-math.ll +++ b/llvm/test/Transforms/InstSimplify/fast-math.ll @@ -20,8 +20,7 @@ define float @mul_zero_2(float %a) { define <2 x float> @mul_zero_nsz_nnan_vec_undef(<2 x float> %a) { ; CHECK-LABEL: @mul_zero_nsz_nnan_vec_undef( -; CHECK-NEXT: [[B:%.*]] = fmul nnan nsz <2 x float> [[A:%.*]], <float 0.000000e+00, float undef> -; CHECK-NEXT: ret <2 x float> [[B]] +; CHECK-NEXT: ret <2 x float> zeroinitializer ; %b = fmul nsz nnan <2 x float> %a, <float 0.0, float undef> ret <2 x float> %b @@ -79,9 +78,7 @@ define <2 x float> @fadd_fnegx_commute_vec(<2 x float> %x) { define <2 x float> @fadd_fnegx_commute_vec_undef(<2 x float> %x) { ; CHECK-LABEL: @fadd_fnegx_commute_vec_undef( -; CHECK-NEXT: [[NEGX:%.*]] = fsub <2 x float> <float undef, float -0.000000e+00>, [[X:%.*]] -; CHECK-NEXT: [[R:%.*]] = fadd nnan <2 x float> [[X]], [[NEGX]] -; CHECK-NEXT: ret <2 x float> [[R]] +; CHECK-NEXT: ret <2 x float> zeroinitializer ; %negx = fsub <2 x float> <float undef, float -0.0>, %x %r = fadd nnan <2 x float> %x, %negx @@ -181,9 +178,7 @@ define float @fsub_0_0_x(float %a) { define <2 x float> @fsub_0_0_x_vec_undef1(<2 x float> %a) { ; CHECK-LABEL: @fsub_0_0_x_vec_undef1( -; CHECK-NEXT: [[T1:%.*]] = fsub <2 x float> <float 0.000000e+00, float undef>, [[A:%.*]] -; CHECK-NEXT: [[RET:%.*]] = fsub nsz <2 x float> zeroinitializer, [[T1]] -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> [[A:%.*]] ; %t1 = fsub <2 x float> <float 0.0, float undef>, %a %ret = fsub nsz <2 x float> zeroinitializer, %t1 @@ -192,9 +187,7 @@ define <2 x float> @fsub_0_0_x_vec_undef1(<2 x float> %a) { define <2 x float> @fsub_0_0_x_vec_undef2(<2 x float> %a) { ; CHECK-LABEL: @fsub_0_0_x_vec_undef2( -; CHECK-NEXT: [[T1:%.*]] = fsub <2 x float> zeroinitializer, [[A:%.*]] -; CHECK-NEXT: [[RET:%.*]] = fsub nsz <2 x float> <float undef, float -0.000000e+00>, [[T1]] -; CHECK-NEXT: ret <2 x float> [[RET]] +; CHECK-NEXT: ret <2 x float> [[A:%.*]] ; %t1 = fsub <2 x float> zeroinitializer, %a %ret = fsub nsz <2 x float> <float undef, float -0.0>, %t1 @@ -229,8 +222,7 @@ define double @fdiv_zero_by_x(double %x) { define <2 x double> @fdiv_zero_by_x_vec_undef(<2 x double> %x) { ; CHECK-LABEL: @fdiv_zero_by_x_vec_undef( -; CHECK-NEXT: [[R:%.*]] = fdiv nnan nsz <2 x double> <double 0.000000e+00, double undef>, [[X:%.*]] -; CHECK-NEXT: ret <2 x double> [[R]] +; CHECK-NEXT: ret <2 x double> zeroinitializer ; %r = fdiv nnan nsz <2 x double> <double 0.0, double undef>, %x ret <2 x double> %r |