This is an archive of the discontinued LLVM Phabricator instance.

[FunctionAttrs] Fix an iterator wraparound bug
ClosedPublic

Authored by sanjoy on Nov 4 2015, 2:37 PM.

Details

Summary

This change fixes an iterator wraparound bug in
determinePointerReadAttrs.

Ideally, ++'ing off the end() of an iplist should result in a failed
assert, but currently iplist seems to silently wrap to the head of the
list on end()++. This is why the bad behavior is difficult to
demonstrate.

Diff Detail

Repository
rL LLVM

Event Timeline

sanjoy updated this revision to Diff 39260.Nov 4 2015, 2:37 PM
sanjoy retitled this revision from to [FunctionAttrs] Fix an iterator wraparound bug.
sanjoy updated this object.
sanjoy added reviewers: chandlerc, reames.
sanjoy added a subscriber: llvm-commits.
reames added inline comments.Nov 4 2015, 2:40 PM
lib/Transforms/IPO/FunctionAttrs.cpp
445 ↗(On Diff #39260)

I would rather we just gave up on VarArg callsites unless you have a compelling reason we need to handle them here. Return a conservative answer, and let someone else refine it later.

p.s. Does the other patch have the same issue?

sanjoy added a subscriber: nlewycky.Nov 4 2015, 2:50 PM
sanjoy added inline comments.
lib/Transforms/IPO/FunctionAttrs.cpp
445 ↗(On Diff #39260)

I didn't add the code, so I'm not in a position to judge whether there is a compelling reason for this optimization or not. :)

Moreover, bailing out unconditionally on varargs functions breaks test/Transforms/FunctionAttrs/readattrs.ll (added by @nlewycky in Jul 2013), and I'd rather not pessimize transforms that have in-tree tests.

p.s. Does the other patch have the same issue?

If you mean D14306, then I don't think so -- that change is fine as far as I can tell.

+Duncan, who's been mucking about with llvm's ilist issues recently

reames accepted this revision.Nov 4 2015, 7:43 PM
reames edited edge metadata.

LGTM. Minor comment below on an improved structured, but the current code is correct and strictly better than what we have.

lib/Transforms/IPO/FunctionAttrs.cpp
446 ↗(On Diff #39260)

I think this would be far clearer as:
for (non var arg arguments) { do previous code)
for (var arg arguments) { return nope! }

This revision is now accepted and ready to land.Nov 4 2015, 7:43 PM
sanjoy added inline comments.Nov 4 2015, 8:24 PM
lib/Transforms/IPO/FunctionAttrs.cpp
446 ↗(On Diff #39260)

Yeah, that's a good idea. I'll do that restructuring and check in.

sanjoy added a comment.Nov 5 2015, 1:25 PM

Actually, I think it will be cleaner to do the same fix I did in D14363 here as well, since we have a direct pointer to the Use * here as well. It won't quite be NFC, since we'll enter the worklist loop multiple times for the same value in cases like

call void @f(i32* readonly nocapture %x, i32* %x)

so it may slightly regress compile time if the second use of %x was a vararg argument. But I think it will make the code easier to read.

sanjoy edited edge metadata.Nov 5 2015, 4:28 PM
sanjoy updated this revision to Diff 39445.Nov 5 2015, 4:32 PM
  • A cleaner fix. Sending for re-review since this is different from what was LGTM'ed earlier
reames added inline comments.Nov 5 2015, 5:28 PM
lib/Transforms/IPO/FunctionAttrs.cpp
444 ↗(On Diff #39445)

What prevents the U from being the callee?

reames requested changes to this revision.Nov 5 2015, 5:29 PM
reames edited edge metadata.
This revision now requires changes to proceed.Nov 5 2015, 5:29 PM
sanjoy added inline comments.Nov 6 2015, 12:42 AM
lib/Transforms/IPO/FunctionAttrs.cpp
444 ↗(On Diff #39445)

Since we're exploring transitive uses of an argument, if such a value was a callee the call would be an indirect call; and we'd take the early return on line 431.

I can change the assertion failure message to be more specific if you think that will make things clearer.

reames accepted this revision.Nov 6 2015, 4:54 PM
reames edited edge metadata.

LGTM

This revision is now accepted and ready to land.Nov 6 2015, 4:54 PM
This revision was automatically updated to reflect the committed changes.