diff options
author | David Majnemer <david.majnemer@gmail.com> | 2017-01-04 02:21:34 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2017-01-04 02:21:34 +0000 |
commit | cb892e9066e53e794ff07247d43e588bfb65d520 (patch) | |
tree | 00f2be1b12781bb4f228799b0ea263e2117fb689 /llvm/lib/Transforms/InstCombine | |
parent | 022d2a563bf81be5c0629ebc9193bcb51b88d0a4 (diff) | |
download | bcm5719-llvm-cb892e9066e53e794ff07247d43e588bfb65d520.tar.gz bcm5719-llvm-cb892e9066e53e794ff07247d43e588bfb65d520.zip |
[InstCombine] Move casts around shift operations
It is possible to perform a left shift before zero extending if the
shift would only shift out zeros.
llvm-svn: 290928
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index bc38c4aca34..5ad2a1c0e3e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -731,6 +731,25 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) { if (ConstantInt *Op1C = dyn_cast<ConstantInt>(I.getOperand(1))) { unsigned ShAmt = Op1C->getZExtValue(); + // Turn: + // %zext = zext i32 %V to i64 + // %res = shl i64 %V, 8 + // + // Into: + // %shl = shl i32 %V, 8 + // %res = zext i32 %shl to i64 + // + // This is only valid if %V would have zeros shifted out. + if (auto *ZI = dyn_cast<ZExtInst>(I.getOperand(0))) { + unsigned SrcBitWidth = ZI->getSrcTy()->getScalarSizeInBits(); + if (ShAmt < SrcBitWidth && + MaskedValueIsZero(ZI->getOperand(0), + APInt::getHighBitsSet(SrcBitWidth, ShAmt), 0, &I)) { + auto *Shl = Builder->CreateShl(ZI->getOperand(0), ShAmt); + return new ZExtInst(Shl, I.getType()); + } + } + // If the shifted-out value is known-zero, then this is a NUW shift. if (!I.hasNoUnsignedWrap() && MaskedValueIsZero(I.getOperand(0), |