This is an archive of the discontinued LLVM Phabricator instance.

ValueTracking: Fix isKnownNonZero for non-0 null pointers for byval
ClosedPublic

Authored by arsenm on Jun 25 2020, 4:53 PM.

Details

Summary

The IR doesn't have a proper concept of invalid pointers, and "null"
constants are just all zeros (though it really needs one).

The nonnull attribute blurs this distinction, and handling in it
isKnownNonZero without checking for the default address space is also
simply wrong. However, it seems some statepoint/gc.relocate users are
relying on the current behavior in addrspace(1). This will probably
need fixing as well, since I believe I recently saw a case where this
was suspect.

Diff Detail

Event Timeline

arsenm created this revision.Jun 25 2020, 4:53 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 25 2020, 4:53 PM
efriedma added inline comments.Jun 25 2020, 5:25 PM
llvm/lib/Analysis/ValueTracking.cpp
2378

LangRef says nonnnull means "not the value null", and the value null is an all-zero bit pattern. That's maybe not ideal for some targets, sure, but I don't think there's a reason to call it out here specifically. If we decide to change the meaning of the attributes in question, we'll audit all the users.

2379

Please use NullPointerIsDefined.

Honestly, nonnull should only mean != 0. I guess not deducing nonnull from byval is reasonable for any AS != 0.
I'm not really in favor of making nonnull mean "valid pointer", dereferenceable is already way closer to that and nonnull is used as "not 0" too often already.

Honestly, nonnull should only mean != 0. I guess not deducing nonnull from byval is reasonable for any AS != 0.
I'm not really in favor of making nonnull mean "valid pointer", dereferenceable is already way closer to that and nonnull is used as "not 0" too often already.

Without a marker for a known-invalid pointer, I don't see how you can repurpose dereferenceable to optimize out "null" checks for other invalid pointer values. The useful property is this pointer is known to never be a valid object; we don't have an isKnownNotDereferenceable

Honestly, nonnull should only mean != 0. I guess not deducing nonnull from byval is reasonable for any AS != 0.
I'm not really in favor of making nonnull mean "valid pointer", dereferenceable is already way closer to that and nonnull is used as "not 0" too often already.

Without a marker for a known-invalid pointer, I don't see how you can repurpose dereferenceable to optimize out "null" checks for other invalid pointer values. The useful property is this pointer is known to never be a valid object; we don't have an isKnownNotDereferenceable

Fair, but reusing nonnull is not the solution. A "null" check, i.a. ptr == 0, is where nonnull comes in. For the lack of an alternative people started to overload the meaning. This is problematic but I guess already happening. I mean, nonnull cannot be equivalent to != 0 and at the same time equivalent to "not a valid pointer" because that would mean != 0 is equivalent to "not a valid pointer" (which it is not). I think both interpretations have been used in the past. I argue we need to fix it to one and introduce something else for the other. I would strongly favor != 0 as the canonical meaning of nonnull, basically how I read the langref right now. Unclear if "not a valid pointer" needs to be an attribute but maybe.

arsenm updated this revision to Diff 274124.Jun 29 2020, 7:45 AM

Use NullPointerIsDefined. I realized it's not actually possible to break this for AMDGPU due to the implicit copy, but I think this is still probably wrong by the IR rules as written. I guess your stack address space could wrap around?

jdoerfert accepted this revision.Jun 29 2020, 9:28 AM

I think this is conceptually the right thing to do. Short from us finally adding more target knowledge hooks for AS questions we should include this.

This revision is now accepted and ready to land.Jun 29 2020, 9:28 AM