You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Compiling the following code with `-O` can sometimes result in `foo` just returning `undef`, that is, LLVM removes the infinite recursion because there's no side-effects.
This is a safety hole: any manipulations of the return value could be working with random data (if the function isn't inlined), or LLVM inlines the function and propagates the undef deeper through the program.
This behavior is somewhat inconsistent across compilers, e.g. it doesn't seem to happen with my local 3.0 compiler (it has the recursive call), but it does with my current development build which is a week or two old, I think.
Notably this transformation is valid in C (more specifically, this sort of recursion is UB), and it may be hard for LLVM to avoid doing this without inhibiting its ability to delete finite side-effect free loops. https://llvm.org/bugs/show_bug.cgi?id=965 is possibly a relevant LLVM bug. Other languages have encountered this problem too, e.g. Rust, which "solved" it by introducing a warning for obvious cases of infinite recursion.
(Certain phrasings of infinite loops are possibly problematic too.)
The text was updated successfully, but these errors were encountered:
If we were to optimize away a loop like this at the SIL level, I think we would turn it into a trap, since Swift's runtime failure semantics allow still allow for undef-like propagation of the trap condition. From past discussion about this issue in the LLVM sphere, it sounds like LLVM might benefit from being able to represent a similar non-strict trap concept, so that cases like this can be folded away to traps instead of UB without interfering with optimization.
Additional Detail from JIRA
md5: 424b71570cfa0cd2d4dab65ecb9ca00f
relates to:
Issue Description:
Compiling the following code with `-O` can sometimes result in `foo` just returning `undef`, that is, LLVM removes the infinite recursion because there's no side-effects.
The IR is:
This is a safety hole: any manipulations of the return value could be working with random data (if the function isn't inlined), or LLVM inlines the function and propagates the undef deeper through the program.
This behavior is somewhat inconsistent across compilers, e.g. it doesn't seem to happen with my local 3.0 compiler (it has the recursive call), but it does with my current development build which is a week or two old, I think.
Notably this transformation is valid in C (more specifically, this sort of recursion is UB), and it may be hard for LLVM to avoid doing this without inhibiting its ability to delete finite side-effect free loops. https://llvm.org/bugs/show_bug.cgi?id=965 is possibly a relevant LLVM bug. Other languages have encountered this problem too, e.g. Rust, which "solved" it by introducing a warning for obvious cases of infinite recursion.
(Certain phrasings of infinite loops are possibly problematic too.)
The text was updated successfully, but these errors were encountered: