Hi, I have some code which has sigsetjmp / longjmp. After a longjmp, unreachable is inserted, which is fine. The problem is that in the backend before calling longjmp, some register was spilled to a stack location which is live across the jmp. I mean, it will be live after jumping. The stack location was initialized before the call to setjmp, and is used afterwards. Is there any bug in handling such a case? I mean, how do LLVM knows about CFG in case of longjmp / setjmp calls? Thanks, -Khaled -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20111004/be10a121/attachment.html>
On Oct 4, 2011, at 3:10 PM, Khaled ElWazeer wrote:> Hi, > > I have some code which has sigsetjmp / longjmp. After a longjmp, unreachable is inserted, which is fine. The problem is that in the backend before calling longjmp, some register was spilled to a stack location which is live across the jmp. I mean, it will be live after jumping. The stack location was initialized before the call to setjmp, and is used afterwards. > > Is there any bug in handling such a case? I mean, how do LLVM knows about CFG in case of longjmp / setjmp calls?It shouldn't need to know because you are only allowed to use volatile variables: All accessible objects have values as of the time longjmp() routine was called, except that the values of objects of automatic storage invocation duration that do not have the volatile type and have been changed between the setjmp() invocation and longjmp() call are indetermi- nate. Are you seeing wrong values in volatile variables after the jump? If so, please file a bug. We may need to disable stack slot sharing in functions that call setjmp. /jakob
On Tue, Oct 4, 2011 at 3:10 PM, Khaled ElWazeer <khalid.alwazeer at gmail.com> wrote:> Hi, > > I have some code which has sigsetjmp / longjmp. After a longjmp, unreachable > is inserted, which is fine. The problem is that in the backend before > calling longjmp, some register was spilled to a stack location which is live > across the jmp. I mean, it will be live after jumping. The stack location > was initialized before the call to setjmp, and is used afterwards. > > Is there any bug in handling such a case? I mean, how do LLVM knows about > CFG in case of longjmp / setjmp calls?No, no handling; we just don't inline anything into functions which call setjmp, and hope we get lucky. In practice, that's generally good enough, given the restrictions on functions that call setjmp, but there are probably some subtle bugs nobody has discovered yet. -Eli
On Oct 4, 2011, at 3:53 PM, Eli Friedman wrote:> On Tue, Oct 4, 2011 at 3:10 PM, Khaled ElWazeer > <khalid.alwazeer at gmail.com> wrote: >> Hi, >> >> I have some code which has sigsetjmp / longjmp. After a longjmp, unreachable >> is inserted, which is fine. The problem is that in the backend before >> calling longjmp, some register was spilled to a stack location which is live >> across the jmp. I mean, it will be live after jumping. The stack location >> was initialized before the call to setjmp, and is used afterwards. >> >> Is there any bug in handling such a case? I mean, how do LLVM knows about >> CFG in case of longjmp / setjmp calls? > > No, no handling; we just don't inline anything into functions which > call setjmp, and hope we get lucky. In practice, that's generally > good enough, given the restrictions on functions that call setjmp, but > there are probably some subtle bugs nobody has discovered yet.We already disable stack slot sharing in functions that callsFunctionThatReturnsTwice(): // If there are calls to setjmp or sigsetjmp, don't perform stack slot // coloring. The stack could be modified before the longjmp is executed, // resulting in the wrong value being used afterwards. (See // <rdar://problem/8007500>.) if (MF.callsSetJmp()) return false; It might be possible for register coalescing to break something as well. /jakob