There were a number of places that calls to math library functions were being constant folded or DCE'd without regard to the nobuiltin attribute. This patch attempts to fix that.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Would it be possible to pass in a CallSite to canConstantFoldCallTo, ConstantFoldCall, and SimplifyCall, to reduce the number of places we check this?
lib/Analysis/ConstantFolding.cpp | ||
---|---|---|
2076 ↗ | (On Diff #100910) | Would it make sense to add an overload of getLibFunc() which takes a CallSite? |
It's certainly possible. The reason I didn't do it was that I didn't want to make assumptions about how the existing functions might be used. They all seem to have deliberately avoided passing the actual call instruction as an argument. In the case of canConstantFoldCallTo it seems like the function is answering the abstract question of can calls to this Function be folded. Including the CallSite changes the semantics of the function, though it is arguably an improvement. In the case of ConstantFoldCall and SimplifyCall the expectation seems to be that they will construct the result of folding the given call, if possible, and the caller will be responsible for making actual changes to the active IR.
That said, I would favor including the CallSite in these calls if there are no objections because the current implementation is definitely vulnerable to future errors.
The other alternative is that you could pass in an AttributeList (the result of getAttributes()) to the functions... that makes it more clear what exactly is getting used, but it's more complicated (and probably involves a bunch of refactoring to expose a function to check isNoBuiltin given a Function/AttributeList pair).
But either way, I would prefer a solution that involves checking for isNoBuiltin() in as few places as possible.
lib/Transforms/Utils/Evaluator.cpp | ||
---|---|---|
363 ↗ | (On Diff #100910) | This isn't doing what you want: we don't call ConstantFoldCall on all paths. |
I'd like to avoid the AttributeList because of the complications when the function declaration is nobuiltin but the CallSite is builtin. I'll implement your first suggestion and post an updated patch. I agree that it is better to have fewer places to check the attributes.
lib/Transforms/Utils/Evaluator.cpp | ||
---|---|---|
363 ↗ | (On Diff #100910) | My reasoning is that if the call is marked as nobuiltin then we can't make any assumptions about what it does. To be honest though, I wasn't sure about this function. Is this used by LLDB and similar clients for live code evaluation? |
lib/Transforms/Utils/Evaluator.cpp | ||
---|---|---|
363 ↗ | (On Diff #100910) | If we have a definition where "isDefinitionExact()" is true, then we know the function does by examining the definition, so nobuiltin isn't relevant. (Actually, looking more closely, I think we're missing the "isDefinitionExact()" check.) This isn't really a general-purpose IR interpreter; it's used by GlobalOpt to simplify C++ global initialization. |
Re-wrote the patch to move the isNoBuiltin checks into canConstantFoldCallTo and ConstantFoldCall.