Validation of the found runtime library functions declarations types (return and argument types) with the expected types.
Details
Diff Detail
Event Timeline
Thanks for the patch!
(Check out the phabricator documentation on llvm.org to see how to upload patches with full context)
Two things that are missing are:
- clear the RFI, or not create it in the first place if the types not match, e.g., use _ReturnType and __VA_ARGS__ directly.
- Add test cases for the different problems, too many/few arguments, wrong return or argument type. You can for example test it via the statistics or by verifying an optimization does not happen, e.g., deduplication.
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
398 ↗ | (On Diff #249893) | You can use pointer comparison on llvm::Type directly, they are unique. |
400 ↗ | (On Diff #249893) | You also need to make sure if the function is varidic as we might expect less arguments. There should be a test as well, we already have known functions that are variadic __kmpc_fork_call or something similar. |
404 ↗ | (On Diff #249893) | This is a good case for auto (IMHO). The kind of container is an implementation detail that should not escape and is not helpful, auto RTFTyIt = ...; should do the trick :) |
413 ↗ | (On Diff #249893) | Make this a (static) class function if possible. |
- RFI is not created unless the declaration found matches the runtime function type.
- Conditional modified to check when a function is variadic.
- Comparison between Type* made directly.
- The function that checks if the types matches was moved to a class static function.
Added regression test that uses the statistics to show that "runtime functions" declarations with different types than the expected are not matched.
You need to squash the commits locally into one or diff against the base or you only upload the latest ;)
Regression test modified to match a proper use of a runtime library function.
PD: Sorry for all that mess before.
llvm/test/Transforms/OpenMP/rtf_type_checking.ll | ||
---|---|---|
65 | The pass is run as many times as functions exist in the file. Is that the expected behavior? |
Almost there :) some comments below.
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
413 ↗ | (On Diff #250426) | Nit: Add a TODO at the beginning of this function reminding us that we should output information to the user (under debug output and via remarks). |
464 ↗ | (On Diff #250426) | Nit: = std::move(ArgsTypes) |
400 ↗ | (On Diff #249893) | I think what is said here was not helpful. For the var arg case we have the function and a function type basically, both should be var arg and have the same number of arguments. I was thinking call vs function decl but that is not the case. My bad. |
llvm/test/Transforms/OpenMP/rtf_type_checking.ll | ||
2 | Nit: leave the RUN line at the top | |
65 | Yes, but part of the pass should not be run as often I guess. Though that is a problem for later. |
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
400 ↗ | (On Diff #249893) | I don't understand what you mean. You were thinking on comparing the function call against the declaration?. Because the optimizer does that for you. The idea was to compare the declaration against the real runtime function declaration, wasn't it?. Then is this ok?, or what should I do? |
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
400 ↗ | (On Diff #249893) | I mean, add two tests for var-args functions. One where there are not enough arguments, one where there are too many. Both should be flagged as bad. That is, the size needs to match perfectly. |
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
400 ↗ | (On Diff #249893) | IMHO, I think adding a test case for when there are too many arguments in a variadic function wouldn't be useful since we can only compare against the arguments that are mandatory. Check out how the number of arguments are being compared (Note that the argument types are checked only if the number of arguments is valid). There are 5 possible function declarations: Variadic Function:
if (F->arg_size() < RTFArgTypes.size()) Non-variadic function:
if (!IsVarArg && F->arg_size() > RTFArgTypes.size()) Together with the if statement above, that checks if has less arguments, covers the second case for non-variadic functions. |
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
400 ↗ | (On Diff #249893) |
Sure, but we can (and should) change the way we check here so we can detect bad signatures of variadic functions that have too many or too few mandatory arguments.
I disagree. We compare the declaration against an expected declaration, they should match. The number of optional arguments at the call sites is a different story though. |
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | ||
---|---|---|
400 ↗ | (On Diff #249893) | Ohhh, sure, I got you. Sorry. I was confusing function call with function declaration. Now fixed. But I cannot have two function declarations with the same function name, opt complains, and the only variadic function inside OMPKinds.def is __kmpc_fork_call. But I have a function declaration with fewer arguments than necessary which also covers the test case you are asking for. Or do you think I might need to create another test file?. |
Thanks for your time.
I don't have commit permissions. Does it have to pass kind of another check to be pushed?.
This change broke the msan buildbot: http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/39755
==70358==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x5a602b2 in deleteParallelRegions /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/lib/Transforms/IPO/OpenMPOpt.cpp:127:9 #1 0x5a602b2 in (anonymous namespace)::OpenMPOpt::run() /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/lib/Transforms/IPO/OpenMPOpt.cpp:116:16 #2 0x5a94252 in (anonymous namespace)::OpenMPOptLegacyPass::runOnSCC(llvm::CallGraphSCC&) /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/lib/Transforms/IPO/OpenMPOpt.cpp:559:19 #3 0x3f53893 in RunPassOnSCC /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/lib/Analysis/CallGraphSCCPass.cpp:139:23
; REQUIRES: asserts
is needed so this works in builds that do not track statistics.