-
Notifications
You must be signed in to change notification settings - Fork 85
Refactor/improve LLVM intrinsic handling #451
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
I'm not sure what the intended scope of this is. I would like to move the Rust functions out into something like |
I think they are out of the scope of this PR. |
@keram88 : Please create a separate pull request for that. I guess the function should be called |
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 then I'll merge it in. |
Shouldn't we also add the handling of intrinsics like |
I thought you wanted to do that as a separate pull request, which maybe would not be a bad idea. |
I think we should implement them in this PR so that we have a better comprehensive picture about what's a good way to implement them. |
I thought it was separate too. |
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.
This looks fine if we're just moving intrinsics out.
When you started working on the intrinsics, I said we should try to handle them uniformly, meaning either put all of them into Looking at the bvswap implementation, to me it seems it would be hard to implement it nicely in Hence, my proposal for refactoring is as follows:
|
By talking about handling LLVM intrinsics uniformly, I thought we meant to choose one between the two design choices,
I voted for the first option because I thought models of LLVM intriniscs can be much more easily expressed using C. For example, there are a lot of resources online about how to implement counting the leading zeros in loop-free C code. But Mark figures out ways to implement these models using Boogie functions, which is more efficient than C code. So the second option is more promising because we do not need The bottom line is that there is nothing in |
ea85127
to
7ac96f0
Compare
In spite of our ongoing discussion, I squashed the commits so it's ready to be merged. |
Well, note that your option (1) can be implemented in the following two ways:
So I think our options for implementing models for intrinsics are as follows:
My main goal has been uniformity, meaning to avoid (4). I actually don't have a strong preference among options (1)-(3). I like (2), which is what @shaobo-he implemented. But then it seems that I have my doubts about (1). On one hand, it generates Boogie code directly and already inlined, and so there are no extraneous procedure invocations and definitions. That might be good for performance. On the other hand, we lose procedure boundaries that might be leveraged by Corral to abstract away intrinsics that are not needed to prove a property, which might be bad for performance. Ultimately, I would choose between (1)-(3) based on which approach we think will lead to uniform and clean implementation of models of intrinsics. |
Let's use a concrete example to illustrate the differences between the four approaches. For example, we want to handle
Am I right here? It so, isn't option 1 and option 3 essentially the same since Another example is Now I'm inclined to 3 because we are able to avoid C functions which, to me can reduce performance significantly. Moreover, we only write C++ code. |
You are comparing them based on their Boogie syntax. I am more interested in comparing them based on their SMACK implementations. Meaning, I suggest we pick whichever solution is the easiest and cleanest to implement in SMACK, as opposed to picking them based on how the generated code looks like at the Boogie level. I hope this makes sense. |
I see. Let me push a version that I thought is ideal. |
I pushed a new version. We will follow the option 3. |
@keram88 and @shaobo-he : could we do |
7b6694b
to
0d49a1d
Compare
Yes, we can. The models for
|
0d49a1d
to
0350892
Compare
@keram88 It seems LLVM even has fixed point arithmetic intrinsics: https://llvm.org/docs/LangRef.html#id1924. You can put your fixed point encoding here. |
Just saw this:
in: |
Does it mean we can also let the result be the size of bits even if |
Pretty much. Apparently some architectures return garbage when the input is zero. Modern x86 and ARM evidently work as expected. Maybe we should just leave it alone since I can only imagine it appearing with higher optimization levels. |
Why do they have both |
We should implement the semantics as fateful as we can, based on the LLVM documentation. So I think that in these situations this function should return an unconstrained value. |
I left my review. Just as a reminder, our goal is to write code that is easy to understand and follow by others. That often does not equate to having the smallest implementation or having the smallest number of branches or using fancy C++ features or anything like that. In fact, it is often quite the opposite. So please think about this when implementing features in SMACK. |
More precisely are we talking about these two? The former truncates a higher precision floating-point type to a lower precision one such as double -> float. The latter rounds a floating-point value to an integer value that is less than or equal to the floating-point value. So they are different. |
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 this and I'll merge it once @michael-emmi approves it. |
This commit contains the following changes, 1. Legacy LLVM intrinsic handling such as those for llvm.expect and llvm.dbg is moved to the designated function. 2. Added handling of LLVM float intrinsics. 3. Added handling of LLVM byte swap intrinsics which leads to adding two Boogie AST classes, BvExtract and BvConcat. 4. Regressions are added to test handling of the aforementioned LLVM intrinsics. Co-authored-by: Mark Stanislaw Baranowski <mark.s.baranowski@gmail.com> Co-authored-by: Shaobo He <polarishehn@gmail.com>
c82c45e
to
156c2a1
Compare
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.
This PR looks good overall, but could use a few simplifications in the stmtMap
construction.
lib/smack/SmackInstGenerator.cpp
Outdated
{llvm::Intrinsic::bswap, bswap}, | ||
{llvm::Intrinsic::expect, identity}, | ||
{llvm::Intrinsic::fabs, | ||
[] (CallInst* ci){ assignUnFPFuncApp(ci,"$abs"); }}, |
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.
Seems like you could simplify the following cases quite a bit by currying. For instance, rather than defining the assignUnFPFuncApp
closure above, define the following function:
std::function<void(CallInst*)> SmackInstGenerator::assignUnFPFuncApp(std::string fnBase) {
return [this, fnBase] (CallInst* ci) {
// translation: $res := $<func>.bv*($arg1);
if (SmackOptions::FloatEnabled)
emit(Stmt::assign(
rep->expr(ci),
Expr::fn(indexedName(fnBase,
{rep->type(ci->getArgOperand(0)->getType())}),
rep->expr(ci->getArgOperand(0)))));
else
generateUnModeledCall(ci);
};
}
Then you could replace the current line with simply:
assignUnFPFuncApp("$abs")},
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.
Good suggestion. Is there a particular reason that this function is made as a member method instead of a local variable?
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.
That’s probably just stylistic preferences; either way resolves the issue.
Uh oh!
There was an error while loading. Please reload this page.