From 613f1a3994ef6f009c93264f6708830249130896 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 23 May 2011 00:32:19 +0000 Subject: [PATCH] rearrange two transforms, since one subsumes the other. Make the shift-exactness xform recurse. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131888 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineMulDivRem.cpp | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index f3d10611ad2..a9b60d373c3 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -29,23 +29,8 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) { // code. if (!V->hasOneUse()) return 0; - - // (PowerOfTwo >>u B) --> isExact since shifting out the result would make it - // inexact. Similarly for <<. - if (BinaryOperator *I = dyn_cast(V)) - if (I->isLogicalShift() && - isPowerOfTwo(I->getOperand(0), IC.getTargetData())) { - if (I->getOpcode() == Instruction::LShr && !I->isExact()) { - I->setIsExact(); - return I; - } - - if (I->getOpcode() == Instruction::Shl && !I->hasNoUnsignedWrap()) { - I->setHasNoUnsignedWrap(); - return I; - } - } - + bool MadeChange = false; + // ((1 << A) >>u B) --> (1 << (A-B)) // Because V cannot be zero, we know that B is less than A. Value *A = 0, *B = 0, *PowerOf2 = 0; @@ -57,12 +42,34 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) { return IC.Builder->CreateShl(PowerOf2, A); } + // (PowerOfTwo >>u B) --> isExact since shifting out the result would make it + // inexact. Similarly for <<. + if (BinaryOperator *I = dyn_cast(V)) + if (I->isLogicalShift() && + isPowerOfTwo(I->getOperand(0), IC.getTargetData())) { + // We know that this is an exact/nuw shift and that the input is a + // non-zero context as well. + if (Value *V2 = simplifyValueKnownNonZero(I->getOperand(0), IC)) { + I->setOperand(0, V2); + MadeChange = true; + } + + if (I->getOpcode() == Instruction::LShr && !I->isExact()) { + I->setIsExact(); + MadeChange = true; + } + + if (I->getOpcode() == Instruction::Shl && !I->hasNoUnsignedWrap()) { + I->setHasNoUnsignedWrap(); + MadeChange = true; + } + } + // TODO: Lots more we could do here: - // "1 >> X" could get an "isexact" bit. // If V is a phi node, we can call this on each of its operands. // "select cond, X, 0" can simplify to "X". - return 0; + return MadeChange ? V : 0; }