diff options
| author | Silviu Baranga <silviu.baranga@arm.com> | 2016-11-30 17:04:22 +0000 |
|---|---|---|
| committer | Silviu Baranga <silviu.baranga@arm.com> | 2016-11-30 17:04:22 +0000 |
| commit | aab65b155e5bec8d89bde61276a37268e0c22d1d (patch) | |
| tree | bbd0e4f98a5c4f0434ddda7b1bc509c82f625a59 /llvm/lib | |
| parent | 2c6f75ddc51f486f17c07f6215bca0848d3d84fe (diff) | |
| download | bcm5719-llvm-aab65b155e5bec8d89bde61276a37268e0c22d1d.tar.gz bcm5719-llvm-aab65b155e5bec8d89bde61276a37268e0c22d1d.zip | |
[AArch64] Fix useful bits detection for BFM instructions
Summary:
When computing useful bits for a BFM instruction, we need
to take into consideration the case where both operands
of the BFM are equal and provide data that we need to track.
Not doing this can cause us to miss useful bits.
Fixes PR31138 (https://llvm.org/bugs/show_bug.cgi?id=31138)
Reviewers: t.p.northover, jmolloy
Subscribers: evandro, gberry, srhines, pirama, mcrosier, aemerson, llvm-commits, rengolin
Differential Revision: https://reviews.llvm.org/D27130
llvm-svn: 288253
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index b075b76c8e9..3099383e5b3 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -1875,23 +1875,52 @@ static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, uint64_t MSB = cast<const ConstantSDNode>(Op.getOperand(3).getNode())->getZExtValue(); - if (Op.getOperand(1) == Orig) - return getUsefulBitsFromBitfieldMoveOpd(Op, UsefulBits, Imm, MSB, Depth); - APInt OpUsefulBits(UsefulBits); OpUsefulBits = 1; + APInt ResultUsefulBits(UsefulBits.getBitWidth(), 0); + ResultUsefulBits.flipAllBits(); + APInt Mask(UsefulBits.getBitWidth(), 0); + + getUsefulBits(Op, ResultUsefulBits, Depth + 1); + if (MSB >= Imm) { - OpUsefulBits = OpUsefulBits.shl(MSB - Imm + 1); + // The instruction is a BFXIL. + uint64_t Width = MSB - Imm + 1; + uint64_t LSB = Imm; + + OpUsefulBits = OpUsefulBits.shl(Width); --OpUsefulBits; - UsefulBits &= ~OpUsefulBits; - getUsefulBits(Op, UsefulBits, Depth + 1); + + if (Op.getOperand(1) == Orig) { + // Copy the low bits from the result to bits starting from LSB. + Mask = ResultUsefulBits & OpUsefulBits; + Mask = Mask.shl(LSB); + } + + if (Op.getOperand(0) == Orig) + // Bits starting from LSB in the input contribute to the result. + Mask |= (ResultUsefulBits & ~OpUsefulBits); } else { - OpUsefulBits = OpUsefulBits.shl(MSB + 1); + // The instruction is a BFI. + uint64_t Width = MSB + 1; + uint64_t LSB = UsefulBits.getBitWidth() - Imm; + + OpUsefulBits = OpUsefulBits.shl(Width); --OpUsefulBits; - UsefulBits = ~(OpUsefulBits.shl(OpUsefulBits.getBitWidth() - Imm)); - getUsefulBits(Op, UsefulBits, Depth + 1); + OpUsefulBits = OpUsefulBits.shl(LSB); + + if (Op.getOperand(1) == Orig) { + // Copy the bits from the result to the zero bits. + Mask = ResultUsefulBits & OpUsefulBits; + Mask = Mask.lshr(LSB); + } + + if (Op.getOperand(0) == Orig) + Mask |= (ResultUsefulBits & ~OpUsefulBits); } + + UsefulBits &= Mask; } static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, |

