This is an archive of the discontinued LLVM Phabricator instance.

Take alignment into account for speculative loads
ClosedPublic

Authored by apilipenko on May 15 2015, 5:41 AM.

Details

Summary

Take alignment into account in isSafeToSpeculativelyExecute and isSafeToLoadUnconditionally.

I assume that pointers without explicit alignment have ABI alignment. I'm not sure that it's correct but for now it reduces the impact of the change. Otherwise we can't speculate on pointers without explicit alignment because loads without explicit alignment require ABI aligned pointers.

As a next step I'm going to common isDereferenceableAndAlignedPointer and isSafeToLoadUnconditionally code.

Diff Detail

Repository
rL LLVM

Event Timeline

apilipenko updated this revision to Diff 25858.May 15 2015, 5:41 AM
apilipenko retitled this revision from to Take alignment into account for speculative loads.
apilipenko updated this object.
apilipenko edited the test plan for this revision. (Show Details)
apilipenko added reviewers: hfinkel, reames, sanjoy.
apilipenko added a subscriber: Unknown Object (MLST).
sanjoy added inline comments.May 17 2015, 11:25 PM
include/llvm/Analysis/ValueTracking.h
230 ↗(On Diff #25858)

The alignment (of the code, I mean :) ) is odd here -- can you please run this change through clang-format?

lib/Analysis/Loads.cpp
147 ↗(On Diff #25858)

If you're using getPointerElementType then I don't think you need to cast<PointerType>.

lib/Analysis/ValueTracking.cpp
2912 ↗(On Diff #25858)

I'd put an assert(isPowerOf2_32(Align)) here.

2923 ↗(On Diff #25858)

Nit: spacing. There are whitespace issues elsewhere too, please run through clang-format.

2924 ↗(On Diff #25858)

No need to cast to PointerType if you're going ti call getPointerElementType.

2933 ↗(On Diff #25858)

Consider this comment deleted -- for some reason Phabricator is unable to delete this comment.

2994 ↗(On Diff #25858)

I think refactoring the index calculation logic to a call to accumulateConstantOffset should be a separate (NFC?) change.

sanjoy requested changes to this revision.May 17 2015, 11:25 PM
sanjoy edited edge metadata.
This revision now requires changes to proceed.May 17 2015, 11:25 PM

Forgot to add: this change definitely needs test cases.

apilipenko updated this revision to Diff 26154.May 20 2015, 8:14 AM
apilipenko edited edge metadata.

Fixed review findings, added tests.

MatzeB added a subscriber: MatzeB.May 20 2015, 10:05 AM

Generally looks fine to me, but I better leave the final judgement to someone more familiar with this part of the code.

Some comments:

include/llvm/Analysis/ValueTracking.h
231 ↗(On Diff #26154)

Don't repeat the method name in the documentation comment, this practice is in widespread use in llvm but discouraged.

lib/Analysis/Loads.cpp
146 ↗(On Diff #26154)

"Type *AccessedTy" would be clearer to the reader.

lib/Analysis/MemDerefPrinter.cpp
60–62 ↗(On Diff #26154)

So you print dereferenceableAndAligned pointers twice? It would probably look nicer if you only print each value, you could still indicate the alignment by printing something like " (unaligned)" behind unaligned pointers.

70 ↗(On Diff #26154)

"Value *" would be more clear for the reader and that makes it obvious that the reference is unnecessary here. Same in the following loop.

lib/Analysis/ValueTracking.cpp
2943 ↗(On Diff #26154)

The second part could be slightly optimized (although I wish we had a method named APInt::isZero()):
assert(Alignment.isPowerOf2());
return ... && !(Offset & (Alignment-1)).getBoolValue();

2960 ↗(On Diff #26154)

maybe add an "if aligned".

apilipenko updated this revision to Diff 26219.May 21 2015, 4:51 AM
apilipenko edited edge metadata.

Fix review findings, prettier MemDerefPrinter output.

sanjoy requested changes to this revision.Jun 3 2015, 7:09 PM
sanjoy edited edge metadata.

Some comments inline.

This change is still too large, do you think it makes sense to separate out the changes to lib/Analysis/Loads.cpp?

You should also make sure you can bootstrap clang with this change in place.

include/llvm/Analysis/ValueTracking.h
231 ↗(On Diff #26219)

Nit: this should be V.

lib/Analysis/Loads.cpp
68 ↗(On Diff #26219)

I'd put an assert here that Align is a power of 2.

lib/Analysis/MemDerefPrinter.cpp
26 ↗(On Diff #26219)

Use DenseSet or SmallPtrSet.

72 ↗(On Diff #26219)

Use .count (both DenseSet and SmallPtrSet have it).

lib/Analysis/ValueTracking.cpp
2927 ↗(On Diff #26219)

The braces are unnecessary here.

3003 ↗(On Diff #26219)

Why do we have a restriction on Bases alignment here? We check below that Base + Offset is properly aligned, right? I'm not strongly opposed to keeping it like this, but please add a comment.

This revision now requires changes to proceed.Jun 3 2015, 7:09 PM
apilipenko updated this revision to Diff 27759.Jun 16 2015, 6:29 AM
apilipenko edited edge metadata.

Loads.cpp changes moved to another review (D10475). Review findings fixed.

hfinkel added inline comments.Jun 22 2015, 7:05 PM
lib/Analysis/ValueTracking.cpp
2934 ↗(On Diff #27759)

Don't need two new lines here.

2935 ↗(On Diff #27759)

You don't need the getBoolValue() here, APInt has an operator !.

2943 ↗(On Diff #27759)

Don't need getBoolValue() here either (or below either).

apilipenko updated this revision to Diff 28238.Jun 23 2015, 7:15 AM
apilipenko edited edge metadata.

Address Hal's comments.

Sorry for taking so long to get back to this one. This change looks good to me, but I'll wait for @hfinkel to take a final look since I haven't really contributed code to this area of LLVM.

hfinkel accepted this revision.Aug 17 2015, 1:25 AM
hfinkel edited edge metadata.

Sorry for taking so long to get back to this one. This change looks good to me, but I'll wait for @hfinkel to take a final look since I haven't really contributed code to this area of LLVM.

LGTM too.

This revision was automatically updated to reflect the committed changes.