[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 03:46:37 PDT 2026
================
@@ -484,13 +581,78 @@ 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;
+ 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.
+ uint64_t Alignment = getUInt64NonPoison(getValue(GetBundleArg(1)));
+ if (OBU.Inputs.size() == 3)
+ Alignment = MinAlign(
+ Alignment, getUInt64NonPoison(getValue(GetBundleArg(2))));
+ if (!isPowerOf2_64(Alignment)) {
+ if (!WasOn.asPointer().address().isZero())
+ reportImmediateUB() << "Assume on nonnull pointer " << WasOn
+ << " with a "
+ "non-power-of-two alignment "
+ << Alignment << '.';
+ break;
+ }
+ if (WasOnPtr.address().countr_zero() < Log2_64(Alignment))
+ reportImmediateUB()
+ << "The pointer " << WasOn << " violates align(" << Alignment
+ << ") assumption.";
+ break;
+ }
+ case Attribute::NonNull:
+ if (WasOnPtr.address().isZero())
+ reportImmediateUB()
+ << "The pointer " << WasOn << " violates nonnull assumption.";
+ break;
+ case Attribute::Dereferenceable:
+ case Attribute::DereferenceableOrNull: {
+ uint64_t DereferenceableBytes =
+ getUInt64NonPoison(getValue(GetBundleArg(1)));
+ if (applyDereferenceableBytesAttr(
+ WasOn, DereferenceableBytes,
+ Kind == Attribute::DereferenceableOrNull))
----------------
nikic wrote:
I think this will incorrectly handle dereferenceable 0?
> Only n > 0 implies that the pointer is dereferenceable.
I believe the applyDereferenceableBytesAttr implementation still checks some things for 0.
https://github.com/llvm/llvm-project/pull/195339
More information about the llvm-commits
mailing list