This is an archive of the discontinued LLVM Phabricator instance.

[ValueTracking] Take poison-generating metadata into account (PR59888)
ClosedPublic

Authored by nikic on Jan 19 2023, 7:16 AM.

Details

Summary

In canCreateUndefOrPoison(), take not only poison-generating flags, but also poison-generating metadata into account. The helpers are written generally, but I believe the only case that can actually matter is !range on calls -- !nonnull and !align are only valid on loads, can those can create undef/poison anyway.

Unfortunately, this negatively impacts logical to bitwise and/or conversion: For ctpop/ctlz/cttz we always attach !range metadata, which will now block the transform, because it might introduce poison. Of course, the metadata we attach cannot actually produce new poison, but this is not generally the case (it could be an incorrect range).

I'm a bit unsure on what to do about this. A possibility would be to update the impliesPoison() helper to support ConsiderFlagsAndMetadata=false mode, and collect instructions that it has checked, and then drop poison generating flags/metadata on all those instructions.

Fixes https://github.com/llvm/llvm-project/issues/59888.

Diff Detail

Event Timeline

nikic created this revision.Jan 19 2023, 7:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 19 2023, 7:16 AM
nikic requested review of this revision.Jan 19 2023, 7:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 19 2023, 7:16 AM
nikic added inline comments.Jan 19 2023, 7:30 AM
llvm/test/Transforms/InstCombine/ispow2.ll
921

As a side note, we are missing the "select value equivalence" class folds for and/or.

LGTM, except for the align metadata.

llvm/lib/IR/Instruction.cpp
217

not sure about align.
If a pointer is not sufficiently aligned, a load may crash. Returning poison in that case is not strong enough for the hardware behavior.

nikic added inline comments.Jan 19 2023, 9:06 AM
llvm/lib/IR/Instruction.cpp
217

This is the same semantics we use for the param attribute. I think it's okay because any kind of speculation requires dereferenceable and align, and dereferenceable implies noundef.

(Note that this is the align metadata that specifies the alignment of the returned pointer, not the alignment of the load itself.)

nlopes accepted this revision.Jan 19 2023, 10:32 AM
nlopes added inline comments.
llvm/lib/IR/Instruction.cpp
217

Oh, I see.
I didn't have that implemented in Alive. Just added support.

This revision is now accepted and ready to land.Jan 19 2023, 10:32 AM
This revision was landed with ongoing or failed builds.Jan 20 2023, 3:18 AM
This revision was automatically updated to reflect the committed changes.