@@ -1445,7 +1445,22 @@ static void computeKnownBitsFromOperator(const Operator *I,
14451445 computeKnownBits (I->getOperand (0 ), Known, Depth + 1 , Q);
14461446 // Accumulate the constant indices in a separate variable
14471447 // to minimize the number of calls to computeForAddSub.
1448- APInt AccConstIndices (BitWidth, 0 , /* IsSigned*/ true );
1448+ unsigned IndexWidth = Q.DL .getIndexTypeSizeInBits (I->getType ());
1449+ APInt AccConstIndices (IndexWidth, 0 );
1450+
1451+ auto AddIndexToKnown = [&](KnownBits IndexBits) {
1452+ if (IndexWidth == BitWidth) {
1453+ // Note that inbounds does *not* guarantee nsw for the addition, as only
1454+ // the offset is signed, while the base address is unsigned.
1455+ Known = KnownBits::add (Known, IndexBits);
1456+ } else {
1457+ // If the index width is smaller than the pointer width, only add the
1458+ // value to the low bits.
1459+ assert (IndexWidth < BitWidth &&
1460+ " Index width can't be larger than pointer width" );
1461+ Known.insertBits (KnownBits::add (Known.trunc (IndexWidth), IndexBits), 0 );
1462+ }
1463+ };
14491464
14501465 gep_type_iterator GTI = gep_type_begin (I);
14511466 for (unsigned i = 1 , e = I->getNumOperands (); i != e; ++i, ++GTI) {
@@ -1483,43 +1498,34 @@ static void computeKnownBitsFromOperator(const Operator *I,
14831498 break ;
14841499 }
14851500
1486- unsigned IndexBitWidth = Index->getType ()->getScalarSizeInBits ();
1487- KnownBits IndexBits (IndexBitWidth);
1488- computeKnownBits (Index, IndexBits, Depth + 1 , Q);
1489- TypeSize IndexTypeSize = GTI.getSequentialElementStride (Q.DL );
1490- uint64_t TypeSizeInBytes = IndexTypeSize.getKnownMinValue ();
1491- KnownBits ScalingFactor (IndexBitWidth);
1501+ TypeSize Stride = GTI.getSequentialElementStride (Q.DL );
1502+ uint64_t StrideInBytes = Stride.getKnownMinValue ();
1503+ if (!Stride.isScalable ()) {
1504+ // Fast path for constant offset.
1505+ if (auto *CI = dyn_cast<ConstantInt>(Index)) {
1506+ AccConstIndices +=
1507+ CI->getValue ().sextOrTrunc (IndexWidth) * StrideInBytes;
1508+ continue ;
1509+ }
1510+ }
1511+
1512+ KnownBits IndexBits =
1513+ computeKnownBits (Index, Depth + 1 , Q).sextOrTrunc (IndexWidth);
1514+ KnownBits ScalingFactor (IndexWidth);
14921515 // Multiply by current sizeof type.
14931516 // &A[i] == A + i * sizeof(*A[i]).
1494- if (IndexTypeSize .isScalable ()) {
1517+ if (Stride .isScalable ()) {
14951518 // For scalable types the only thing we know about sizeof is
14961519 // that this is a multiple of the minimum size.
1497- ScalingFactor.Zero .setLowBits (llvm::countr_zero (TypeSizeInBytes));
1498- } else if (IndexBits.isConstant ()) {
1499- APInt IndexConst = IndexBits.getConstant ();
1500- APInt ScalingFactor (IndexBitWidth, TypeSizeInBytes);
1501- IndexConst *= ScalingFactor;
1502- AccConstIndices += IndexConst.sextOrTrunc (BitWidth);
1503- continue ;
1520+ ScalingFactor.Zero .setLowBits (llvm::countr_zero (StrideInBytes));
15041521 } else {
15051522 ScalingFactor =
1506- KnownBits::makeConstant (APInt (IndexBitWidth, TypeSizeInBytes ));
1523+ KnownBits::makeConstant (APInt (IndexWidth, StrideInBytes ));
15071524 }
1508- IndexBits = KnownBits::mul (IndexBits, ScalingFactor);
1509-
1510- // If the offsets have a different width from the pointer, according
1511- // to the language reference we need to sign-extend or truncate them
1512- // to the width of the pointer.
1513- IndexBits = IndexBits.sextOrTrunc (BitWidth);
1514-
1515- // Note that inbounds does *not* guarantee nsw for the addition, as only
1516- // the offset is signed, while the base address is unsigned.
1517- Known = KnownBits::add (Known, IndexBits);
1518- }
1519- if (!Known.isUnknown () && !AccConstIndices.isZero ()) {
1520- KnownBits Index = KnownBits::makeConstant (AccConstIndices);
1521- Known = KnownBits::add (Known, Index);
1525+ AddIndexToKnown (KnownBits::mul (IndexBits, ScalingFactor));
15221526 }
1527+ if (!Known.isUnknown () && !AccConstIndices.isZero ())
1528+ AddIndexToKnown (KnownBits::makeConstant (AccConstIndices));
15231529 break ;
15241530 }
15251531 case Instruction::PHI: {
0 commit comments