diff options
| author | Shuxin Yang <shuxin.llvm@gmail.com> | 2012-11-26 21:44:25 +0000 |
|---|---|---|
| committer | Shuxin Yang <shuxin.llvm@gmail.com> | 2012-11-26 21:44:25 +0000 |
| commit | 6ea79e864d089d7795a03ecb30125cfcc7f06fff (patch) | |
| tree | 3db7168e9b5b90dd030e7023352d6fa00b544adc /llvm/lib/Transforms | |
| parent | b0916015aead352d441373db0c2ecbf06427a00d (diff) | |
| download | bcm5719-llvm-6ea79e864d089d7795a03ecb30125cfcc7f06fff.tar.gz bcm5719-llvm-6ea79e864d089d7795a03ecb30125cfcc7f06fff.zip | |
rdar://12329730 (defect 2)
Enhancement to InstCombine. Try to catch this opportunity:
---------------------------------------------------------------
((X^C1) >> C2) ^ C3 => (X>>C2) ^ ((C1>>C2)^C3)
where the subexpression "X ^ C1" has more than one uses, and
"(X^C1) >> C2" has single use.
----------------------------------------------------------------
Reviewed by Nadav (with minor change per his request).
llvm-svn: 168615
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 494cc7d1517..12faedb0ffe 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2159,6 +2159,27 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { I.setOperand(1, NewRHS); return &I; } + } else if (Op0I->getOpcode() == Instruction::LShr) { + // ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3) + // E1 = "X ^ C1" + BinaryOperator *E1; + ConstantInt *C1; + if (Op0I->hasOneUse() && + (E1 = dyn_cast<BinaryOperator>(Op0I->getOperand(0))) && + E1->getOpcode() == Instruction::Xor && + (C1 = dyn_cast<ConstantInt>(E1->getOperand(1)))) { + // fold (C1 >> C2) ^ C3 + ConstantInt *C2 = Op0CI, *C3 = RHS; + APInt FoldConst = C1->getValue().lshr(C2->getValue()); + FoldConst ^= C3->getValue(); + // Prepare the two operands. + Value *Opnd0 = Builder->CreateLShr(E1->getOperand(0), C2); + Opnd0->takeName(Op0I); + cast<Instruction>(Opnd0)->setDebugLoc(I.getDebugLoc()); + Value *FoldVal = ConstantInt::get(Opnd0->getType(), FoldConst); + + return BinaryOperator::CreateXor(Opnd0, FoldVal); + } } } } |

