[llvm] [llubi] Add support for poison-generating/UB-implying annotations (PR #195339)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sun May 3 10:06:11 PDT 2026
================
@@ -484,13 +573,86 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
case Intrinsic::assume:
switch (Args[0].asBoolean()) {
case BooleanKind::True:
+ for (unsigned Idx = 0; Idx < CB.getNumOperandBundles(); Idx++) {
+ OperandBundleUse OBU = CB.getOperandBundleAt(Idx);
+ auto GetBundleArg = [&](uint32_t Offset) -> Value * {
+ return OBU.Inputs[Offset];
+ };
+ if (OBU.Inputs.empty())
+ continue;
+ Value *WasOnVal = GetBundleArg(0);
+ // Bail out on unrecognized operand bundles.
+ if (!WasOnVal->getType()->isPointerTy())
+ continue;
+ unsigned AS = WasOnVal->getType()->getPointerAddressSpace();
+ const AnyValue &WasOn = getValue(WasOnVal);
+ if (WasOn.isPoison()) {
+ reportImmediateUB() << "Assume on poison pointer.";
+ break;
+ }
+ const Pointer &WasOnPtr = WasOn.asPointer();
+ Attribute::AttrKind Kind =
+ Attribute::getAttrKindFromName(OBU.getTagName());
+ switch (Kind) {
+ case Attribute::Alignment: {
+ // Alignment assumptions should have 2 or 3 arguments.
+ // If there are two integer arguments, use the largest power of 2
+ // that divides them as the alignment.
+ APInt Alignment = getIntNonPoison(getValue(GetBundleArg(1)));
+ if (OBU.Inputs.size() == 3) {
+ APInt Offset = getIntNonPoison(getValue(GetBundleArg(2)));
+ if (!Alignment.isZero() || !Offset.isZero())
+ Alignment = APInt::getOneBitSet(
+ std::max(Alignment.getBitWidth(), Offset.getBitWidth()),
+ std::min(Alignment.countr_zero(), Offset.countr_zero()));
+ }
+ if (!Alignment.isPowerOf2()) {
+ if (!WasOnPtr.isNullPtr(AS, DL))
+ reportImmediateUB() << "Assume on nonnull pointer " << WasOn
+ << " with a "
+ "non-power-of-two alignment "
+ << Alignment << '.';
+ break;
+ }
+ if (WasOnPtr.address().countr_zero() < Alignment.logBase2())
+ reportImmediateUB()
+ << "The pointer " << WasOn << " violates align(" << Alignment
+ << ") assumption.";
+ break;
+ }
+ case Attribute::NonNull:
+ if (WasOnPtr.isNullPtr(AS, DL))
+ reportImmediateUB()
+ << "The pointer " << WasOn << " violates nonnull assumption.";
+ break;
+ case Attribute::Dereferenceable:
+ case Attribute::DereferenceableOrNull: {
+ APInt DereferenceableBytes =
+ getIntNonPoison(getValue(GetBundleArg(1)));
+ // Only n > 0 implies that the pointer is dereferenceable.
+ if (!DereferenceableBytes.isStrictlyPositive())
----------------
nikic wrote:
Hm, I'm pretty sure the intent here was just `!isZero()`, as the `dereferenceable` argument is unsigned.
https://github.com/llvm/llvm-project/pull/195339
More information about the llvm-commits
mailing list