Pass TargetLibraryInfo to isSafeToSpeculativelyExecute so that it can understand the behavior of known library functions.
With this patch, pthread_self is known to NOT trap, and therefore can be speculatively executed.
Paths
| Differential D26930
Teach optimizer that pthread_self does not trap. It can be speculatively executed. AbandonedPublic Authored by trentxintong on Nov 21 2016, 1:05 PM.
Details
Summary Pass TargetLibraryInfo to isSafeToSpeculativelyExecute so that it can understand the behavior of known library functions. With this patch, pthread_self is known to NOT trap, and therefore can be speculatively executed.
Diff Detail
Event Timelinetrentxintong retitled this revision from to Teach optimizer that pthread_self does not trap. It can be speculatively executed.. trentxintong updated this object. Comment Actions Why isn't attributing pthread_self as readonly or even readnone enough for this purpose? Comment Actions Because, if pthread_self (or a function) could trap and is not guaranteed to execute. we cant pull it to the preheader. And readonly/readnone + nonunwind function does not imply the function cant trap. The conditions for LI code to be pulled to the preheader is.
Only know pthread_self is readnone+nounwind does not suffice. we need to teach the optimizer that it can not trap. Comment Actions Well, readnone functions are safe to speculatively execute. The question is if pthread_self() does qualify for it, since strictly it does read global memory. My problem with this change is that this seems to add a very stricted form of readnone in a non-systematic and adhoc fashion. Comment Actions readnone - On a function, this attribute indicates that the function computes its result (or decides to unwind an exception) based strictly on its arguments, without dereferencing any pointer arguments or otherwise accessing any mutable state ... what if i have, this function is readnone and nounwind, but it can trap. define int @unsafe_div(int a, int b) { return a/b; } Comment Actions I, too, hope readnone+nounwind functions can be speculatively executed, but it does not seem to be the case =). Thats why i think we need to use TLI to teach the optimizer about functions which can. Comment Actions
You're both right. We cannot speculate functions that might have UB. Thus, we cannot speculate general external functions (even if they're readnone, etc.). See also: D20116 where we're discussing adding a separate attribute for this. Comment Actions
@hfinkel I see, do you think it would be a good to add "speculatable" attribute to pthread_self in FuncAttr once the patch for the attribute lands so that it can be hoisted ? or we can use TLI in isSafeToSpeculativelyExecute function. Comment Actions
I'd prefer just to use the attribute. Comment Actions
@hfinkel Ok, SGTM. Thanks for the pointer. Comment Actions This patch needs to be completely rewritten (different approach) after the speculatable attribute lands.
Revision Contents
Diff 78768 include/llvm/Analysis/TargetLibraryInfo.def
include/llvm/Analysis/ValueTracking.h
include/llvm/Transforms/Utils/LoopUtils.h
lib/Analysis/TargetLibraryInfo.cpp
lib/Analysis/ValueTracking.cpp
lib/Transforms/Scalar/LICM.cpp
lib/Transforms/Scalar/LoopSink.cpp
test/Transforms/LICM/pthread.ll
|