This is an archive of the discontinued LLVM Phabricator instance.

[safestack] Rewrite isAllocaSafe using SCEV.
ClosedPublic

Authored by eugenis on Nov 11 2015, 4:59 PM.

Details

Reviewers
pcc
Summary

Use ScalarEvolution to calculate memory access bounds.
Handle function calls based on readnone/nocapture attributes.
Handle memory intrinsics with constant size.
Handle lifetime intrinsics.

This change improves both recall and precision of IsAllocaSafe.
See the new tests (ex. BitCastWide) for the kind of code that was wrongly
classified as safe.

SCEV efficiency seems to be limited by the fact the SafeStack runs late
(in CodeGenPrepare), and many loops are unrolled or otherwise not in LCSSA.

Diff Detail

Repository
rL LLVM

Event Timeline

eugenis updated this revision to Diff 39993.Nov 11 2015, 4:59 PM
eugenis retitled this revision from to [safestack] Rewrite isAllocaSafe using SCEV..
eugenis updated this object.
eugenis added a reviewer: pcc.
eugenis set the repository for this revision to rL LLVM.
eugenis added a subscriber: llvm-commits.

This version also attempts to protect against information leaks.
A function that returns an address of a stack variable (or some value computed based on that) would get a readnone attribute, which means we can not rely on that. This was the last use of AliasAnalysis in SafeStack, so it is now gone.

pcc edited edge metadata.Nov 11 2015, 5:53 PM

This is great, thanks for working on this. A few mostly minor comments.

lib/Transforms/Instrumentation/SafeStack.cpp
111

Why did you change this? The comment was correct before, I believe?

186

Isn't this equivalent to just SE->getUnsignedRange(Expr)?

188

Nit: you don't need to supply a third argument here (and below); false is the default.

301

Should this be the default behaviour? It seems like it would be safer to use explicit whitelisting of instructions as the old code does.

595–596

Did you leave this in intentionally?

eugenis updated this revision to Diff 39999.Nov 11 2015, 6:15 PM
eugenis updated this object.
eugenis edited edge metadata.
eugenis marked an inline comment as done.
eugenis added inline comments.
lib/Transforms/Instrumentation/SafeStack.cpp
111

I don't recall changing this. Weird.
Reverted.

186

The second one is supposed to be getSignedRange. This is actually quite inefficient as these calls do a lot of duplicate work.

301

This sounds like a awful lot of whitelisting. Unlike the previous algorithm where we explicitly supported a few instructions, ScalarEvolution can handle almost anything, and if not it would just say that the access range is full-set.

I think blacklisting would be a better approach.

595–596

Removed.

sanjoy added inline comments.Nov 11 2015, 6:24 PM
lib/Transforms/Instrumentation/SafeStack.cpp
186

I don't think you need to intersect here -- if the intersection returns a "better" (i.e. strictly smaller) range than either getUnsignedRange or getSignedRange, then it is a bug in ScalarEvolution. :)

Reading the surrounding code, I think you really only need getUnsignedRange.

eugenis updated this revision to Diff 40094.Nov 12 2015, 4:06 PM
eugenis added inline comments.Nov 12 2015, 4:09 PM
lib/Transforms/Instrumentation/SafeStack.cpp
186

Is it because we are comparing it with a non-negative alloca range, and even if the signed range is "smaller", it would still overflow in the negative direction?

Switched to getUnsignedRange.

pcc accepted this revision.Nov 12 2015, 4:54 PM
pcc edited edge metadata.

LGTM

lib/Transforms/Instrumentation/SafeStack.cpp
186

I agree that you just need getUnsignedRange. My understanding is that the two functions are supposed to return essentially the same thing but return slightly different results in the negative range for unknowns (e.g. for unknowns with m trailing zeros [0,2^n-2^m) vs [-2^(n-1)..2^(n-1)-2^m) ) which we don't care about here.

301

After sleeping on it I agree that your approach is correct.

This revision is now accepted and ready to land.Nov 12 2015, 4:54 PM
eugenis closed this revision.Nov 13 2015, 1:24 PM

Submitted as r253083, thanks!