This is an archive of the discontinued LLVM Phabricator instance.

[Attributor] Check nonnull attribute violation in AAUndefinedBehavior
ClosedPublic

Authored by okura on Jul 28 2020, 1:40 AM.

Details

Summary

This patch makes it possible to handle nonnull attribute violation at callsites in AAUndefinedBehavior.
If null pointer is passed to callee at a callsite and the corresponding argument of callee has nonnull attribute, the behavior of the callee is undefined.
In this patch, violations of argument nonnull attributes is only handled.
But violations of returned nonnull attributes can be handled and I will implement that in a follow-up patch.

Diff Detail

Event Timeline

okura created this revision.Jul 28 2020, 1:40 AM
Herald added a reviewer: homerdin. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
okura requested review of this revision.Jul 28 2020, 1:40 AM
okura edited the summary of this revision. (Show Details)Jul 28 2020, 3:35 AM
baziotis added inline comments.Jul 28 2020, 6:55 AM
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
2048

Please add a third argument specifying the instructions to check, i.e. {Instruction::CallSite}. Also, a fourth argument true as a value, like the other too above.

llvm/test/Transforms/Attributor/value-simplify.ll
409 ↗(On Diff #281140)

Hmm.. We probably need to fix the undefined behavior in this testcase.

This is cool :)

I thought about this again and I think it will expose the problematic case I mentioned on the call. The Attributor derives attributes, then replaces the value with undef because it is dead, then the thing might be folded to UB/unreachable. Let's directly require the noundef attribute as well. We need to split the AAUB behavior accordingly soon but I'm fine with checking it explicitly here first. That will require tests with and without noundef.

llvm/lib/Transforms/IPO/AttributorAttributes.cpp
1991
1996

You don't need a callee, just use the call base.

1998

I somehow feel checking the attribute first is better.

2005

Move this to the beginning to describe what is happening. Maybe elaborate a bit.

2018

Provide a comment before or at the beginning of this lambda explaining it a bit.

2048

No need to specify call site (which is not an opcode) because this is a specialized version of checkForAllInstructions. The CheckBBLivenessOnly can be provided I guess.

baziotis added inline comments.Jul 28 2020, 7:35 AM
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
2048

Oh my bad. The names are big and I missed completely that it is not checkForAllInstructions.

okura updated this revision to Diff 282501.Aug 2 2020, 10:02 PM
  • fix comments
  • check noundef attribute explicitly
  • modify and add tests with noundef attribute
okura marked 4 inline comments as done.Aug 2 2020, 10:24 PM
okura added inline comments.
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
1996

Do you mean that I don't have to be aware of Callee->arg_size() anywhere?
In the case of callbacks, CB.getNumArgOperands() > Callee->arg_size() holds and I got segfault when getArg is called.
Can I get the callee argument position directly from CallBase?

jdoerfert accepted this revision.Aug 3 2020, 12:02 AM

LGTM. Some minor nits below. I guess this doesn't affect other tests because of the noundef restriction. We should really derive that one as well.

llvm/lib/Transforms/IPO/AttributorAttributes.cpp
1996

Oh, OK. For any variadic function the call can have more operands than the callee arguments. I guess what you really want are the abstract call sites you can get from the call base. Let's keep it like this for now.

2007

I guess the easiest is to check if it is a pointer early on. That should avoid running the code below in case it can never trigger.

2021

Not having a value and having the value undef are also all violations if you will. The former means it is dead anyway, and undef can degenerate to null whenever you want it to.

llvm/test/Transforms/Attributor/undefined_behavior.ll
598

Next up, we can derive noundef for this case (amongst others), given that we actually access the pointer for sure. An undef value would cause UB so %a cannot be undef. Basically the same way we should already derive nonnull for this case. Later ;)

This revision is now accepted and ready to land.Aug 3 2020, 12:02 AM
okura updated this revision to Diff 282517.Aug 3 2020, 12:59 AM
  • fix nits
  • add comment