This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyCFG] Improve the precision of `PtrValueMayBeModified`
ClosedPublic

Authored by DianQK on Feb 22 2023, 7:04 AM.

Details

Summary

The result value of getelementptr inbounds (TY, null, not zero) is a poison value. We can think of it as undefined behavior.

Please let me know if there is anything I don't understand correctly.

Diff Detail

Event Timeline

DianQK created this revision.Feb 22 2023, 7:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 22 2023, 7:04 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
DianQK requested review of this revision.Feb 22 2023, 7:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 22 2023, 7:04 AM
DianQK edited the summary of this revision. (Show Details)Feb 22 2023, 7:07 AM
DianQK added reviewers: nikic, xbolva00, jdoerfert.
DianQK edited the summary of this revision. (Show Details)Feb 22 2023, 7:10 AM
nikic added inline comments.Feb 22 2023, 7:16 AM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7128

This is only the case if !NullPointerIsDefined(GEP->getFunction(), GEP->getPointerAddressSpace()).

nikic added inline comments.Feb 22 2023, 7:27 AM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7128

Though we should probably just move that check to the start of the function, because we end up repeating it everywhere anyway.

jdoerfert added inline comments.Feb 22 2023, 8:34 AM
llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
517

I'm worried because I didn't see a test with inbounds gep and @fn_noundef_arg call.
!GEP->hasAllZeroIndices() does not imply non zero. It means we don't know it's all zero.
Can we make sure we don't accidentally read poison into the situation where it could as well be null.

DianQK updated this revision to Diff 499832.Feb 23 2023, 6:27 AM

Add NullPointerIsDefined check and fn_noundef_arg case

nikic added inline comments.Feb 23 2023, 6:30 AM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7142

The first block probably isn't supposed to be there?

DianQK added inline comments.Feb 23 2023, 6:53 AM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7128

I think it would be fine to call NullPointerIsDefined directly on each gep, load and store, because we still have to query address space.

Would it be cleaner to just use NullPointerIsDefined?

7142

Sorry I didn't get.
First, we only focus two cases:
a. getelementptr (TY, null, not zero) -> maybe be modified
a. getelementptr inbounds (TY, null, not zero) -> poison?

The first

if (!GEP->isInBounds()) {
   PtrValueMayBeModified = true;
}

is the "a" case.

7142

These two cases are:
a. getelementptr (TY, null, not zero) -> maybe be modified
b. getelementptr inbounds (TY, null, not zero) -> poison?

llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
517

I have added the fn_noundef_arg case.
For all ptr cases, PtrValueMayBeModified is used to check if it always be null.

DianQK added inline comments.Feb 24 2023, 4:41 AM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7142

Ping? Is there something I misunderstood?

StephenFan added inline comments.Feb 24 2023, 8:39 PM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7143–7145

This condition equivalent to

if (!GEP->isInBounds() ||
      NullPointerIsDefined(GEP->getFunction(),
                            GEP->getPointerAddressSpace())) {

which repeats the above if statement.

DianQK updated this revision to Diff 500356.Feb 24 2023, 9:37 PM

Simplify the branch logic

DianQK added inline comments.Feb 24 2023, 9:41 PM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7143–7145

Thank you so much, you saved me.
I was getting wrapped up in this pile of if branches.

Missing a test with inbounds + null_pointer_is_valid, I think?

DianQK updated this revision to Diff 500389.Feb 25 2023, 1:24 AM

Add some tests with inbounds + null_pointer_is_valid.

nikic accepted this revision.Feb 25 2023, 2:09 AM

LGTM

This revision is now accepted and ready to land.Feb 25 2023, 2:09 AM
xbolva00 accepted this revision.Feb 25 2023, 2:14 AM

Precommit tests?

Otherwise looks good.

llvm/lib/Transforms/Utils/SimplifyCFG.cpp
7126

may be?

7128

poison? (only if null is undefined)

why question mark? Maybe:

poison iff null is undefined?

Thank you very much for your review!

Further, we should remove the bool GetElementPtrInst::hasAllZeroIndices() method altogether. Then we don't need to consider the gep zero case anymore.
What do you think?

Although this may require additional work, possibly:

  • add assertions created by GEP instructions or automatically convert them to other instructions
  • automatically convert GEP directives after optimizations like constant propagation
DianQK updated this revision to Diff 500399.Feb 25 2023, 2:27 AM

Fixed typo

DianQK marked 2 inline comments as done.Feb 25 2023, 2:31 AM

Precommit tests?

Otherwise looks good.

Thanks, it should look better now.
I'm going to run ninja check-all with clang.

This revision was landed with ongoing or failed builds.Feb 25 2023, 3:44 AM
This revision was automatically updated to reflect the committed changes.