[llvm] r290733 - [InstCombine] More thoroughly canonicalize the position of zexts
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 12 13:33:32 PST 2017
Have any tests been added for these transforms?
On Thu, Dec 29, 2016 at 8:47 PM, David Majnemer via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> 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)->getTyp
>>> e());
>>> - 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
>>>
>>
>>
>
> _______________________________________________
> 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/20170112/91fdc053/attachment.html>
More information about the llvm-commits
mailing list