setjmp - longjmp

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

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

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

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

That code should do it, but I realized you only detect setjmp functions by name. My code is calling “__sigsetjmp” not “segsetjmp”. You only support these functions:

static const char *ReturnsTwiceFns = {
“_setjmp”,
“setjmp”,
“sigsetjmp”,
“setjmp_syscall”,
“savectx”,
“qsetjmp”,
“vfork”,
“getcontext”
};

I think if I add mine to this list, it should work. I will try that.

Thanks,
-Khaled

Actually my problem is solved when I added “__sigsetjmp” to this list.

Thanks,
-Khaled

Rafael just added a returns_twice function attribute to LLVM IR.

I expect he will update the callsFunctionThatReturnsTwice() function soon.

/jakob