[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