This is an archive of the discontinued LLVM Phabricator instance.

[Loads/SROA] Remove blatantly incorrect code and fix a bug revealed in the process
ClosedPublic

Authored by reames on Aug 26 2019, 5:38 PM.

Details

Summary

The code we had isSafeToLoadUnconditionally was blatantly wrong. This function takes a "Size" argument which is supposed to describe the span loaded from. Instead, the code use the size of the pointer passed (which may be unrelated!) and only checks that span. For any Size > LoadSize, this can and does lead to miscompiles.

Worse, the generic code just a few lines above correctly handles the cases which *are* valid. So, let's delete said code.

(Note: There's another occurrence of the same bug in the same function in the scan code. I'll get that next.)

Removing this exposes a bits vs bytes confusion in SROA + one other test change where the semantics of the test aren't clear to me. I propose to simply change the test output (as in the diff) and move on.

Diff Detail

Repository
rL LLVM

Event Timeline

reames created this revision.Aug 26 2019, 5:38 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 26 2019, 5:38 PM
jdoerfert accepted this revision.Aug 26 2019, 6:50 PM

I think ByteOffset is used *but* the logic you remove is just a copy of what isDereferenceableAndAlignedPointer is doing already only worse and also wrong (see my comment below).

LGTM.

test/Transforms/SROA/addrspacecast.ll
287 ↗(On Diff #217284)

Maybe add something like ; Note that the external linkage of @gv doesn't guarantee dereferenceable memory to make sure people will not fall into the same trap again and understand easily what is happening.

This revision is now accepted and ready to land.Aug 26 2019, 6:50 PM
reames updated this revision to Diff 217437.Aug 27 2019, 11:06 AM
reames edited the summary of this revision. (Show Details)

Updating patch, and requesting re-review.

I screwed up in posting the original patch. I managed to leave out part of the diff, and my patch description was unclear.

reames requested review of this revision.Aug 27 2019, 11:06 AM
reames updated this revision to Diff 217443.Aug 27 2019, 11:17 AM

Fix the other occurrence of the Size vs LoadSize bug.

reames updated this revision to Diff 217450.Aug 27 2019, 11:31 AM

Improve test coverage to make bugs being fixed clear.

jdoerfert accepted this revision.Aug 27 2019, 12:06 PM

Removing the duplicated (wrong) logic is still fine. Using Size is also the right thing. The bits/bytes size mixup seems unrelated but given that bytes is the right thing I'm OK with it.

The one thing I would like to add is a test for the Size vs PtrSize issue, see my comment below. Otherwise, LGTM.

lib/Analysis/Loads.cpp
268 ↗(On Diff #217450)

Can we have a test for this? I would hope something where we want to pre-loads a 64 bit pointer but only have a 32 bit access?

This revision is now accepted and ready to land.Aug 27 2019, 12:06 PM
reames marked an inline comment as done.Aug 27 2019, 12:15 PM
reames added inline comments.
lib/Analysis/Loads.cpp
268 ↗(On Diff #217450)

I've been sitting here trying to write that test for most of the morning. :)

Most existing callers pass a size which is the pointer size. The sole exception is the phi-speculation code in SROA, and I haven't figured out how to trigger it there just yet. My previously added select tests demonstrate the *spirit* of the problem, but don't actually expose the current bug.

This revision was automatically updated to reflect the committed changes.