[llvm] r290733 - [InstCombine] More thoroughly canonicalize the position of zexts

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 29 19:47:18 PST 2016


Addressed in r290741, thanks.

On Thu, Dec 29, 2016 at 5:18 PM, Craig Topper <craig.topper at gmail.com>
wrote:

> Why does (add (zext x), cst) --> (zext (add x, cst')) check for signed
> overflow but then create an NUW add. That's not valid is it?
>
> ~Craig
>
> On Thu, Dec 29, 2016 at 4:28 PM, David Majnemer via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: majnemer
>> Date: Thu Dec 29 18:28:58 2016
>> New Revision: 290733
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=290733&view=rev
>> Log:
>> [InstCombine] More thoroughly canonicalize the position of zexts
>>
>> We correctly canonicalized (add (sext x), (sext y)) to (sext (add x, y))
>> where possible.  However, we didn't perform the same canonicalization
>> for zexts or for muls.
>>
>> Modified:
>>     llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
>>     llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>> s/InstCombine/InstCombineAddSub.cpp?rev=290733&r1=290732&r2=
>> 290733&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
>> (original)
>> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Thu Dec
>> 29 18:28:58 2016
>> @@ -1226,15 +1226,16 @@ Instruction *InstCombiner::visitAdd(Bina
>>    if (SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) {
>>      // (add (sext x), cst) --> (sext (add x, cst'))
>>      if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
>> -      Constant *CI =
>> -        ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType());
>> -      if (LHSConv->hasOneUse() &&
>> -          ConstantExpr::getSExt(CI, I.getType()) == RHSC &&
>> -          WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI, I)) {
>> -        // Insert the new, smaller add.
>> -        Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
>> -                                              CI, "addconv");
>> -        return new SExtInst(NewAdd, I.getType());
>> +      if (LHSConv->hasOneUse()) {
>> +        Constant *CI =
>> +            ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getTyp
>> e());
>> +        if (ConstantExpr::getSExt(CI, I.getType()) == RHSC &&
>> +            WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI, I)) {
>> +          // Insert the new, smaller add.
>> +          Value *NewAdd =
>> +              Builder->CreateNSWAdd(LHSConv->getOperand(0), CI,
>> "addconv");
>> +          return new SExtInst(NewAdd, I.getType());
>> +        }
>>        }
>>      }
>>
>> @@ -1255,6 +1256,43 @@ Instruction *InstCombiner::visitAdd(Bina
>>        }
>>      }
>>    }
>> +
>> +  // Check for (add (zext x), y), see if we can merge this into an
>> +  // integer add followed by a zext.
>> +  if (auto *LHSConv = dyn_cast<ZExtInst>(LHS)) {
>> +    // (add (zext x), cst) --> (zext (add x, cst'))
>> +    if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
>> +      if (LHSConv->hasOneUse()) {
>> +        Constant *CI =
>> +            ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getTyp
>> e());
>> +        if (ConstantExpr::getZExt(CI, I.getType()) == RHSC &&
>> +            WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI, I)) {
>> +          // Insert the new, smaller add.
>> +          Value *NewAdd =
>> +              Builder->CreateNUWAdd(LHSConv->getOperand(0), CI,
>> "addconv");
>> +          return new ZExtInst(NewAdd, I.getType());
>> +        }
>> +      }
>> +    }
>> +
>> +    // (add (zext x), (zext y)) --> (zext (add int x, y))
>> +    if (auto *RHSConv = dyn_cast<ZExtInst>(RHS)) {
>> +      // Only do this if x/y have the same type, if at last one of them
>> has a
>> +      // single use (so we don't increase the number of zexts), and if
>> the
>> +      // integer add will not overflow.
>> +      if (LHSConv->getOperand(0)->getType() ==
>> +              RHSConv->getOperand(0)->getType() &&
>> +          (LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
>> +          computeOverflowForUnsignedAdd(LHSConv->getOperand(0),
>> +                                        RHSConv->getOperand(0),
>> +                                        &I) ==
>> OverflowResult::NeverOverflows) {
>> +        // Insert the new integer add.
>> +        Value *NewAdd = Builder->CreateNUWAdd(
>> +            LHSConv->getOperand(0), RHSConv->getOperand(0), "addconv");
>> +        return new ZExtInst(NewAdd, I.getType());
>> +      }
>> +    }
>> +  }
>>
>>    // (add (xor A, B) (and A, B)) --> (or A, B)
>>    {
>>
>> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>> s/InstCombine/InstCombineMulDivRem.cpp?rev=290733&r1=290732&
>> r2=290733&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
>> (original)
>> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Thu
>> Dec 29 18:28:58 2016
>> @@ -389,6 +389,79 @@ Instruction *InstCombiner::visitMul(Bina
>>      }
>>    }
>>
>> +  // Check for (mul (sext x), y), see if we can merge this into an
>> +  // integer mul followed by a sext.
>> +  if (SExtInst *Op0Conv = dyn_cast<SExtInst>(Op0)) {
>> +    // (mul (sext x), cst) --> (sext (mul x, cst'))
>> +    if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
>> +      if (Op0Conv->hasOneUse()) {
>> +        Constant *CI =
>> +            ConstantExpr::getTrunc(Op1C, Op0Conv->getOperand(0)->getTyp
>> e());
>> +        if (ConstantExpr::getSExt(CI, I.getType()) == Op1C &&
>> +            WillNotOverflowSignedMul(Op0Conv->getOperand(0), CI, I)) {
>> +          // Insert the new, smaller mul.
>> +          Value *NewMul =
>> +              Builder->CreateNSWMul(Op0Conv->getOperand(0), CI,
>> "mulconv");
>> +          return new SExtInst(NewMul, I.getType());
>> +        }
>> +      }
>> +    }
>> +
>> +    // (mul (sext x), (sext y)) --> (sext (mul int x, y))
>> +    if (SExtInst *Op1Conv = dyn_cast<SExtInst>(Op1)) {
>> +      // Only do this if x/y have the same type, if at last one of them
>> has a
>> +      // single use (so we don't increase the number of sexts), and if
>> the
>> +      // integer mul will not overflow.
>> +      if (Op0Conv->getOperand(0)->getType() ==
>> +              Op1Conv->getOperand(0)->getType() &&
>> +          (Op0Conv->hasOneUse() || Op1Conv->hasOneUse()) &&
>> +          WillNotOverflowSignedMul(Op0Conv->getOperand(0),
>> +                                   Op1Conv->getOperand(0), I)) {
>> +        // Insert the new integer mul.
>> +        Value *NewMul = Builder->CreateNSWMul(
>> +            Op0Conv->getOperand(0), Op1Conv->getOperand(0), "mulconv");
>> +        return new SExtInst(NewMul, I.getType());
>> +      }
>> +    }
>> +  }
>> +
>> +  // Check for (mul (zext x), y), see if we can merge this into an
>> +  // integer mul followed by a zext.
>> +  if (auto *Op0Conv = dyn_cast<ZExtInst>(Op0)) {
>> +    // (mul (zext x), cst) --> (zext (mul x, cst'))
>> +    if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
>> +      if (Op0Conv->hasOneUse()) {
>> +        Constant *CI =
>> +            ConstantExpr::getTrunc(Op1C, Op0Conv->getOperand(0)->getTyp
>> e());
>> +        if (ConstantExpr::getZExt(CI, I.getType()) == Op1C &&
>> +            WillNotOverflowSignedMul(Op0Conv->getOperand(0), CI, I)) {
>> +          // Insert the new, smaller mul.
>> +          Value *NewMul =
>> +              Builder->CreateNUWMul(Op0Conv->getOperand(0), CI,
>> "mulconv");
>> +          return new ZExtInst(NewMul, I.getType());
>> +        }
>> +      }
>> +    }
>> +
>> +    // (mul (zext x), (zext y)) --> (zext (mul int x, y))
>> +    if (auto *Op1Conv = dyn_cast<ZExtInst>(Op1)) {
>> +      // Only do this if x/y have the same type, if at last one of them
>> has a
>> +      // single use (so we don't increase the number of zexts), and if
>> the
>> +      // integer mul will not overflow.
>> +      if (Op0Conv->getOperand(0)->getType() ==
>> +              Op1Conv->getOperand(0)->getType() &&
>> +          (Op0Conv->hasOneUse() || Op1Conv->hasOneUse()) &&
>> +          computeOverflowForUnsignedMul(Op0Conv->getOperand(0),
>> +                                        Op1Conv->getOperand(0),
>> +                                        &I) ==
>> OverflowResult::NeverOverflows) {
>> +        // Insert the new integer mul.
>> +        Value *NewMul = Builder->CreateNUWMul(
>> +            Op0Conv->getOperand(0), Op1Conv->getOperand(0), "mulconv");
>> +        return new ZExtInst(NewMul, I.getType());
>> +      }
>> +    }
>> +  }
>> +
>>    if (!I.hasNoSignedWrap() && WillNotOverflowSignedMul(Op0, Op1, I)) {
>>      Changed = true;
>>      I.setHasNoSignedWrap(true);
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161229/006f66f7/attachment.html>


More information about the llvm-commits mailing list