summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2017-01-17 00:45:57 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2017-01-17 00:45:57 +0000
commit36d382b773bd83daf7304e3a5d11a828e3316e2c (patch)
treec2e98b8f5765991398253af319c619dcc643430e /llvm/lib
parentc8cc2be9f847a8c81ae9f97009b4af1e71eb6e1f (diff)
downloadbcm5719-llvm-36d382b773bd83daf7304e3a5d11a828e3316e2c.tar.gz
bcm5719-llvm-36d382b773bd83daf7304e3a5d11a828e3316e2c.zip
[InstCombine] Fold ((C1-zext(X)) & C2) -> zext((C1-X) & C2)
This is valid if C2 fits within the bitwidth of X thanks to two's complement modulo arithmetic. llvm-svn: 292179
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index da5384a86aa..4a0edf378c4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1331,6 +1331,21 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
if (Value *V = FoldLogicalPlusAnd(Op0LHS, Op0RHS, AndRHS, true, I))
return BinaryOperator::CreateAnd(V, AndRHS);
+ // ((C1-zext(X)) & C2) -> zext((C1-X) & C2) if C2 fits in the bitwidth
+ // of X.
+ if (auto *ZI = dyn_cast<ZExtInst>(Op0RHS)) {
+ auto *X = ZI->getOperand(0);
+ ConstantInt *C1;
+ if (match(Op0LHS, m_ConstantInt(C1)) &&
+ AndRHSMask.isIntN(X->getType()->getScalarSizeInBits())) {
+ auto *TruncC1 = ConstantExpr::getTrunc(C1, X->getType());
+ auto *Sub = Builder->CreateSub(TruncC1, X);
+ auto *TruncC2 = ConstantExpr::getTrunc(AndRHS, X->getType());
+ auto *And = Builder->CreateAnd(Sub, TruncC2);
+ return new ZExtInst(And, I.getType());
+ }
+ }
+
// -x & 1 -> x & 1
if (AndRHSMask == 1 && match(Op0LHS, m_Zero()))
return BinaryOperator::CreateAnd(Op0RHS, AndRHS);
OpenPOWER on IntegriCloud