[llvm] r290733 - [InstCombine] More thoroughly canonicalize the position of zexts
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 12 13:40:12 PST 2017
Yes, I added them in r290929. They were accidentally omitted in the
original commit.
On Thu, Jan 12, 2017 at 1:33 PM, Sanjay Patel <spatel at rotateright.com>
wrote:
> 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.c
>>>> pp
>>>> 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/6528f54c/attachment.html>
More information about the llvm-commits
mailing list