[llvm] [InferAS] Infer the address space of inttoptr (PR #173244)

Luo Yuanke via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 8 04:03:32 PST 2026


================
@@ -369,15 +384,56 @@ getPointerOperands(const Value &V, const DataLayout &DL,
     return {II.getArgOperand(0)};
   }
   case Instruction::IntToPtr: {
-    assert(isNoopPtrIntCastPair(&Op, DL, TTI));
-    auto *P2I = cast<Operator>(Op.getOperand(0));
-    return {P2I->getOperand(0)};
+    if (isNoopPtrIntCastPair(&Op, DL, TTI)) {
+      auto *P2I = cast<Operator>(Op.getOperand(0));
+      return {P2I->getOperand(0)};
+    }
+    assert(isSafeToCastPtrIntPair(&Op, DL));
+    return {PtrIntCastPairs[&Op]};
   }
   default:
     llvm_unreachable("Unexpected instruction type.");
   }
 }
 
+bool InferAddressSpacesImpl::isSafeToCastPtrIntPair(
+    const Operator *I2P, const DataLayout &DL) const {
+  assert(I2P->getOpcode() == Instruction::IntToPtr);
+  if (PtrIntCastPairs.count(I2P))
+    return true;
+
+  if (I2P->getType()->isVectorTy())
+    return false;
+
+  auto *Xor = dyn_cast<Operator>(I2P->getOperand(0));
+  if (!Xor || Xor->getOpcode() != Instruction::Xor)
+    return false;
----------------
LuoYuanke wrote:

> Do we have to restrict everything to Xor only?
> All that matters is that we can figure out the changed bits, and that those bits are "safe". Whether the changes is done with xor or any other op is irrelevant.

I don't think we have to restrict to Xor only. Xor is just one case.  It can be some other computation (e.g., `And x & (-4)`; `Or x & 4`).

> I wonder if we could do something along the lines of `changedBits = computeKnownBits(Xor(PtrToIntValue, IntToPtrValue))`

Sure, we can implement such function as below.

```
int InferAddressSpacesImpl::computeKnownChangedLSB(const Operator *Op,
                                                   const Operator *P2I,
                                                   const Value *Other,
                                                   const DataLayout &DL) const {
  KnownBits Known = computeKnownBits(Other, DL, &AC, nullptr, DT);
  switch (Op->getOpcode()) {
  case Instruction::Xor:
  case Instruction::Or:
    return DL.getPointerSizeInBits() - Known.Zero.countLeadingOnes();
  case Instruction::And:
    return DL.getPointerSizeInBits() - Known.One.countLeadingOnes();
  default:
    return -1;
  }
}
```

https://github.com/llvm/llvm-project/pull/173244


More information about the llvm-commits mailing list