From: Sanjay Patel Date: Thu, 20 Jun 2019 22:55:28 +0000 (+0000) Subject: [InstSimplify] simplify power-of-2 (single bit set) sequences X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=347248d4837e7a8e31eb9103a321414b0a205da8;p=llvm [InstSimplify] simplify power-of-2 (single bit set) sequences As discussed in PR42314: https://bugs.llvm.org/show_bug.cgi?id=42314 Improving the canonicalization for these patterns: rL363956 ...means we should adjust/enhance the related simplification. https://rise4fun.com/Alive/w1cp Name: isPow2 or zero %x = and i32 %xx, 2048 %a = add i32 %x, -1 %r = and i32 %a, %x => %r = i32 0 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363997 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index ba76c5b0479..ce0b8a0fe64 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1845,6 +1845,16 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, return Op1; } + // This is a similar pattern used for checking if a value is a power-of-2: + // (A - 1) & A --> 0 (if A is a power-of-2 or 0) + // A & (A - 1) --> 0 (if A is a power-of-2 or 0) + if (match(Op0, m_Add(m_Specific(Op1), m_AllOnes())) && + isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT)) + return Constant::getNullValue(Op1->getType()); + if (match(Op1, m_Add(m_Specific(Op0), m_AllOnes())) && + isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT)) + return Constant::getNullValue(Op0->getType()); + if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, true)) return V; diff --git a/test/Transforms/InstSimplify/AndOrXor.ll b/test/Transforms/InstSimplify/AndOrXor.ll index e2c17e24028..a5c8108d0a5 100644 --- a/test/Transforms/InstSimplify/AndOrXor.ll +++ b/test/Transforms/InstSimplify/AndOrXor.ll @@ -93,10 +93,7 @@ define i64 @pow2b(i32 %x) { define i32 @pow2_decrement(i32 %p) { ; CHECK-LABEL: @pow2_decrement( -; CHECK-NEXT: [[X:%.*]] = shl i32 1, [[P:%.*]] -; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], -1 -; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[X]] -; CHECK-NEXT: ret i32 [[R]] +; CHECK-NEXT: ret i32 0 ; %x = shl i32 1, %p %a = add i32 %x, -1 @@ -106,10 +103,7 @@ define i32 @pow2_decrement(i32 %p) { define <2 x i32> @pow2_decrement_commute_vec(<2 x i32> %p) { ; CHECK-LABEL: @pow2_decrement_commute_vec( -; CHECK-NEXT: [[X:%.*]] = and <2 x i32> [[P:%.*]], -; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], -; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[X]], [[A]] -; CHECK-NEXT: ret <2 x i32> [[R]] +; CHECK-NEXT: ret <2 x i32> zeroinitializer ; %x = and <2 x i32> %p, %a = add <2 x i32> %x,