-
Notifications
You must be signed in to change notification settings - Fork 83
[WIP] Optionally model the LLVM assume statement in Boogie #478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
My primary impetus to add this is that Rust generates these in just about every program. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Travis is failing this because of Perhaps we should merge this after LLVM 7.1 lands. |
I’m curious about knowing more; is there a reference on this? Overall, I wonder whether it might instead be a good idea to take advantage of these assumptions by modeling them as boogie assumes. Depending on why they’re added. For instance, if they correspond to things the rust type checker has already proven, then why not use them? |
@michael-emmi That's a good point, I should have discussed how Rust uses this function. Rust doesn't appear to do anything interesting with
Basically, Rust is telling LLVM its booleans are The strongest thing I think Rust has ever done with respect to its type-system is add the Another approach is to make generating Boogie assumptions opt-in or opt-out through a command line argument. Something like We should update #53 regardless. |
I think without evident benefits of leveraging the LLVM assume intrinsic, the current PR is the better option. |
Please fix formatting so that CI is passing. It is an easy fix. Also, please address this compilation warning if possible:
|
I see. Formatting got broken elsewhere. I'll fix it. You still have to take care of the warning though. |
Could we at least understand whether the assumes here represent facts that have been “proven” by previous analysis, or whether e.g., they represent speculative optimization hints that may be invalidated and require unoptimized fallback? |
From the LLVM language spec (https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic):
and also
So to me it seems that the purpose of I think we should ultimately have a command line switch |
From https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic:
LLVM appears to treat these as axioms, so it won't generate any code to handle an invalid assumption. I think the uses of I'm starting to fall on the side of generating boogie assumes for these; they can't hurt verification time and might help. My biggest concern is that the compiler will generate an |
This seems reasonable. We should try generating assumes to see how they behave before enabling or disabling them generally. I want to update this PR with your proposal. |
Yea, I agree that experimenting with whether these generated One small note: it’s not obvious to me that additional assumes “can’t hurt verification time”, but perhaps that is another conversation altogether :-) |
This is worth investigating. I know some of our floating-point axioms slowed down verification. Solvers are complex beasts and it's hard to know what hurts or helps. |
I implemented Zvonimir's suggestion. I witnessed one interesting case along the lines of this (translated from Rust):
SMACK is able to verify this with Rust also generates some useful assume statements, namely it states that its pointers are not null. |
What do you think of also adding a "strict" assume mode? Clang has |
I see. So there should be a command line argument with 3 options: ignore assumes, assume assumes, and assert assumes. I like that. Please add the assert assumes option as well then. Good suggestion. |
Also, could you create a regression that checks for this? |
@keram88 : What's the status of this pull request? Any chance you could finish it this week? |
I have implemented the following:
I added the regressions here: https://github.com/smackers/smack/tree/no-warn-assume/test/special. But as I found in Rust, using the assumes generated by the compiler could help us avoid running bit-precise. |
I addressed @zvonimir's comments. I don't like force pushing, so if this looks good, I can squash the commits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Please squash and clean up your commits and then I'll merge it.
Done. Thanks, @michael-emmi for driving this toward what I think is a much better solution. |
d55cf00
to
be1a5d1
Compare
LLVM has the llvm.assume intrinsic which is intended to allow a compiler to communicate facts about a program to LLVM's optimizers. These facts may be useful for verification, so this allows them to be used. Additionally, checking of assumptions is possible in order to diagnose faulty assumptions arising from source code or compiler bugs. Specifically, a new flag "--llvm-assumes" is added with three modes: - "none": This ignores the llvm.assume intrinsic and is the default mode. - "use": This enables generation of Boogie assumes from llvm.assume instructions. - "check": This enables assertion checking of the validity of assumed statements.
Currently we don't do anything with LLVM's assume statement. This is because we
need to be sure that the assumption provided to the function is correct. At best
it might help with verification, but it could also lead SMACK to report erroneous
bugs (or no bugs!). For now, this removes this intrinsic, preventing a warning about an unsound
call to this function.
I could add the closure in the stmtMap, but I think it's valuable to have the rationale somewhere in this function.