From: Chen Zheng Date: Thu, 12 Jul 2018 03:06:04 +0000 (+0000) Subject: [InstSimplify] simplify add instruction if two operands are negative X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d5acd8e56ef3314536265837fed5ce53558acd7;p=llvm [InstSimplify] simplify add instruction if two operands are negative Differential Revision: https://reviews.llvm.org/D49216 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336881 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 249f0fdbd42..0b6bdf38cbf 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -101,6 +101,9 @@ class Value; const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); + /// Return true if the two given values are negation. + bool isKnownNegation(const Value *X, const Value *Y); + /// Returns true if the give value is known to be non-negative. bool isKnownNonNegative(const Value *V, const DataLayout &DL, unsigned Depth = 0, diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 061ce8f0bd1..87b1fc5b8ee 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -540,6 +540,10 @@ static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, if (match(Op1, m_Zero())) return Op0; + // If two operands are negative, return 0. + if (isKnownNegation(Op0, Op1)) + return Constant::getNullValue(Op0->getType()); + // X + (Y - X) -> Y // (Y - X) + X -> Y // Eg: X + -X -> 0 diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index bdfd1783236..88ed6562c38 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -4511,6 +4511,26 @@ static SelectPatternResult matchMinMax(CmpInst::Predicate Pred, return {SPF_UNKNOWN, SPNB_NA, false}; } +bool llvm::isKnownNegation(const Value *X, const Value *Y) { + assert(X && Y && "Invalid operand"); + + // X = sub (0, Y) + if (match(X, m_Neg(m_Specific(Y)))) + return true; + + // Y = sub (0, X) + if (match(Y, m_Neg(m_Specific(X)))) + return true; + + // X = sub (A, B), Y = sub (B, A) + Value *A, *B; + if (match(X, m_Sub(m_Value(A), m_Value(B))) && + match(Y, m_Sub(m_Specific(B), m_Specific(A)))) + return true; + + return false; +} + static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, FastMathFlags FMF, Value *CmpLHS, Value *CmpRHS, diff --git a/test/Transforms/InstSimplify/add.ll b/test/Transforms/InstSimplify/add.ll index d32b2551ab1..21cc905688b 100644 --- a/test/Transforms/InstSimplify/add.ll +++ b/test/Transforms/InstSimplify/add.ll @@ -30,10 +30,7 @@ define <2 x i32> @negated_operand_commute_vec(<2 x i32> %x) { define i8 @knownnegation(i8 %x, i8 %y) { ; CHECK-LABEL: @knownnegation( -; CHECK-NEXT: [[XY:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[YX:%.*]] = sub i8 [[Y]], [[X]] -; CHECK-NEXT: [[R:%.*]] = add i8 [[XY]], [[YX]] -; CHECK-NEXT: ret i8 [[R]] +; CHECK-NEXT: ret i8 0 ; %xy = sub i8 %x, %y %yx = sub i8 %y, %x @@ -43,10 +40,7 @@ define i8 @knownnegation(i8 %x, i8 %y) { define <2 x i8> @knownnegation_commute_vec(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @knownnegation_commute_vec( -; CHECK-NEXT: [[XY:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[YX:%.*]] = sub <2 x i8> [[Y]], [[X]] -; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[YX]], [[XY]] -; CHECK-NEXT: ret <2 x i8> [[R]] +; CHECK-NEXT: ret <2 x i8> zeroinitializer ; %xy = sub <2 x i8> %x, %y %yx = sub <2 x i8> %y, %x