diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index f276902d2e6..cbe5a2454ce 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2148,6 +2148,50 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero, } break; } + case ISD::BITCAST: { + SDValue N0 = Op.getOperand(0); + unsigned SubBitWidth = N0.getScalarValueSizeInBits(); + + // Ignore bitcasts from floating point. + if (!N0.getValueType().isInteger()) + break; + + // Fast handling of 'identity' bitcasts. + if (BitWidth == SubBitWidth) { + computeKnownBits(N0, KnownZero, KnownOne, DemandedElts, Depth + 1); + break; + } + + // Support big-endian targets when it becomes useful. + bool IsLE = getDataLayout().isLittleEndian(); + if (!IsLE) + break; + + // Bitcast 'small element' vector to 'large element' scalar/vector. + if ((BitWidth % SubBitWidth) == 0) { + assert(N0.getValueType().isVector() && "Expected bitcast from vector"); + + // Collect known bits for the (larger) output by collecting the known + // bits from each set of sub elements and shift these into place. + // We need to separately call computeKnownBits for each set of + // sub elements as the knownbits for each is likely to be different. + unsigned SubScale = BitWidth / SubBitWidth; + APInt SubDemandedElts(NumElts * SubScale, 0); + for (unsigned i = 0; i != NumElts; ++i) + if (DemandedElts[i]) + SubDemandedElts.setBit(i * SubScale); + + for (unsigned i = 0; i != SubScale; ++i) { + computeKnownBits(N0, KnownZero2, KnownOne2, SubDemandedElts.shl(i), + Depth + 1); + KnownOne |= KnownOne2.zext(BitWidth).shl(SubBitWidth * i); + KnownZero |= KnownZero2.zext(BitWidth).shl(SubBitWidth * i); + } + } + + // TODO - support ((SubBitWidth % BitWidth) == 0) when it becomes useful. + break; + } case ISD::AND: // If either the LHS or the RHS are Zero, the result is zero. computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, DemandedElts, |