@@ -1426,7 +1426,22 @@ static void computeKnownBitsFromOperator(const Operator *I,
14261426 computeKnownBits (I->getOperand (0 ), Known, Depth + 1 , Q);
14271427 // Accumulate the constant indices in a separate variable
14281428 // to minimize the number of calls to computeForAddSub.
1429- APInt AccConstIndices (BitWidth, 0 , /* IsSigned*/ true );
1429+ unsigned IndexWidth = Q.DL .getIndexTypeSizeInBits (I->getType ());
1430+ APInt AccConstIndices (IndexWidth, 0 );
1431+
1432+ auto AddIndexToKnown = [&](KnownBits IndexBits) {
1433+ if (IndexWidth == BitWidth) {
1434+ // Note that inbounds does *not* guarantee nsw for the addition, as only
1435+ // the offset is signed, while the base address is unsigned.
1436+ Known = KnownBits::add (Known, IndexBits);
1437+ } else {
1438+ // If the index width is smaller than the pointer width, only add the
1439+ // value to the low bits.
1440+ assert (IndexWidth < BitWidth &&
1441+ " Index width can't be larger than pointer width" );
1442+ Known.insertBits (KnownBits::add (Known.trunc (IndexWidth), IndexBits), 0 );
1443+ }
1444+ };
14301445
14311446 gep_type_iterator GTI = gep_type_begin (I);
14321447 for (unsigned i = 1 , e = I->getNumOperands (); i != e; ++i, ++GTI) {
@@ -1464,43 +1479,34 @@ static void computeKnownBitsFromOperator(const Operator *I,
14641479 break ;
14651480 }
14661481
1467- unsigned IndexBitWidth = Index->getType ()->getScalarSizeInBits ();
1468- KnownBits IndexBits (IndexBitWidth);
1469- computeKnownBits (Index, IndexBits, Depth + 1 , Q);
1470- TypeSize IndexTypeSize = GTI.getSequentialElementStride (Q.DL );
1471- uint64_t TypeSizeInBytes = IndexTypeSize.getKnownMinValue ();
1472- KnownBits ScalingFactor (IndexBitWidth);
1482+ TypeSize Stride = GTI.getSequentialElementStride (Q.DL );
1483+ uint64_t StrideInBytes = Stride.getKnownMinValue ();
1484+ if (!Stride.isScalable ()) {
1485+ // Fast path for constant offset.
1486+ if (auto *CI = dyn_cast<ConstantInt>(Index)) {
1487+ AccConstIndices +=
1488+ CI->getValue ().sextOrTrunc (IndexWidth) * StrideInBytes;
1489+ continue ;
1490+ }
1491+ }
1492+
1493+ KnownBits IndexBits =
1494+ computeKnownBits (Index, Depth + 1 , Q).sextOrTrunc (IndexWidth);
1495+ KnownBits ScalingFactor (IndexWidth);
14731496 // Multiply by current sizeof type.
14741497 // &A[i] == A + i * sizeof(*A[i]).
1475- if (IndexTypeSize .isScalable ()) {
1498+ if (Stride .isScalable ()) {
14761499 // For scalable types the only thing we know about sizeof is
14771500 // that this is a multiple of the minimum size.
1478- ScalingFactor.Zero .setLowBits (llvm::countr_zero (TypeSizeInBytes));
1479- } else if (IndexBits.isConstant ()) {
1480- APInt IndexConst = IndexBits.getConstant ();
1481- APInt ScalingFactor (IndexBitWidth, TypeSizeInBytes);
1482- IndexConst *= ScalingFactor;
1483- AccConstIndices += IndexConst.sextOrTrunc (BitWidth);
1484- continue ;
1501+ ScalingFactor.Zero .setLowBits (llvm::countr_zero (StrideInBytes));
14851502 } else {
14861503 ScalingFactor =
1487- KnownBits::makeConstant (APInt (IndexBitWidth, TypeSizeInBytes ));
1504+ KnownBits::makeConstant (APInt (IndexWidth, StrideInBytes ));
14881505 }
1489- IndexBits = KnownBits::mul (IndexBits, ScalingFactor);
1490-
1491- // If the offsets have a different width from the pointer, according
1492- // to the language reference we need to sign-extend or truncate them
1493- // to the width of the pointer.
1494- IndexBits = IndexBits.sextOrTrunc (BitWidth);
1495-
1496- // Note that inbounds does *not* guarantee nsw for the addition, as only
1497- // the offset is signed, while the base address is unsigned.
1498- Known = KnownBits::add (Known, IndexBits);
1499- }
1500- if (!Known.isUnknown () && !AccConstIndices.isZero ()) {
1501- KnownBits Index = KnownBits::makeConstant (AccConstIndices);
1502- Known = KnownBits::add (Known, Index);
1506+ AddIndexToKnown (KnownBits::mul (IndexBits, ScalingFactor));
15031507 }
1508+ if (!Known.isUnknown () && !AccConstIndices.isZero ())
1509+ AddIndexToKnown (KnownBits::makeConstant (AccConstIndices));
15041510 break ;
15051511 }
15061512 case Instruction::PHI: {
0 commit comments