diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-12-10 17:00:00 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-12-10 17:00:00 +0000 |
| commit | 54945a12ecbb9575f57d147c48a158fc612c6ded (patch) | |
| tree | c0809721d5549a35d8b388ed4d70befa3c49966a /llvm/lib/CodeGen/SelectionDAG | |
| parent | 9181e7750465bf645dbf761125ec12f846236cd3 (diff) | |
| download | bcm5719-llvm-54945a12ecbb9575f57d147c48a158fc612c6ded.tar.gz bcm5719-llvm-54945a12ecbb9575f57d147c48a158fc612c6ded.zip | |
[SelectionDAG] Add ability for computeKnownBits to peek through bitcasts from 'large element' scalar/vector to 'small element' vector.
Extension to D27129 which already supported bitcasts from 'small element' vector to 'large element' scalar/vector types.
llvm-svn: 289329
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d80048c1396..45c9c59fe21 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2186,7 +2186,29 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero, } } - // TODO - support ((SubBitWidth % BitWidth) == 0) when it becomes useful. + // Bitcast 'large element' scalar/vector to 'small element' vector. + if ((SubBitWidth % BitWidth) == 0) { + assert(Op.getValueType().isVector() && "Expected bitcast to vector"); + + // Collect known bits for the (smaller) output by collecting the known + // bits from the overlapping larger input elements and extracting the + // sub sections we actually care about. + unsigned SubScale = SubBitWidth / BitWidth; + APInt SubDemandedElts(NumElts / SubScale, 0); + for (unsigned i = 0; i != NumElts; ++i) + if (DemandedElts[i]) + SubDemandedElts.setBit(i / SubScale); + + computeKnownBits(N0, KnownZero2, KnownOne2, SubDemandedElts, Depth + 1); + + KnownZero = KnownOne = APInt::getAllOnesValue(BitWidth); + for (unsigned i = 0; i != NumElts; ++i) + if (DemandedElts[i]) { + unsigned Offset = (i % SubScale) * BitWidth; + KnownOne &= KnownOne2.lshr(Offset).trunc(BitWidth); + KnownZero &= KnownZero2.lshr(Offset).trunc(BitWidth); + } + } break; } case ISD::AND: |

