[llvm] r290733 - [InstCombine] More thoroughly canonicalize the position of zexts
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 29 17:18:33 PST 2016
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/
> Transforms/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)->
> getType());
> + 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)->
> getType());
> + 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/
> Transforms/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)->
> getType());
> + 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)->
> getType());
> + 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/a08478ef/attachment.html>
More information about the llvm-commits
mailing list