summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/PatternMatch.h22
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp16
-rw-r--r--llvm/test/Transforms/InstSimplify/fast-math.ll18
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
OpenPOWER on IntegriCloud