diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index f1e9b159d3c..a1f9de62b05 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -4456,6 +4456,26 @@ bool PPCDAGToDAGISel::tryAndWithMask(SDNode *N) { CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Ops); return true; } + + // It is not 16-bit imm that means we need two instructions at least if + // using "and" instruction. Try to exploit it with rotate mask instructions. + if (isRunOfOnes64(Imm64, MB, ME)) { + if (MB >= 32 && MB <= ME) { + // MB ME + // +----------------------+ + // |xxxxxxxxxxx00011111000| + // +----------------------+ + // 0 32 64 + // We can only do it if the MB is larger than 32 and MB <= ME + // as RLWINM will replace the content of [0 - 32) with [32 - 64) even + // we didn't rotate it. + SDValue Ops[] = { Val, getI64Imm(0, dl), getI64Imm(MB - 32, dl), + getI64Imm(ME - 32, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLWINM8, MVT::i64, Ops); + return true; + } + // TODO - handle it with rldicl + rldicl + } } return false; |