<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yui_3_16_0_1_1496439047371_22094">Hi,</div><div id="yui_3_16_0_1_1496439047371_22094" dir="ltr">I'm trying to prevent llvm instruction motion around an intrinsic function call. Throughout my experimenting, I was told that setjmp could create fake entry points into a region of code and that might prevent code motion.</div><div id="yui_3_16_0_1_1496439047371_22094" dir="ltr">What I found is something surprising, and probably is a misuse of setjmp but I couldn't find an explanation for it.</div><div id="yui_3_16_0_1_1496439047371_22094" dir="ltr">Consider this:</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30378">#include <csetjmp></div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30379"><br id="yui_3_16_0_1_1496439047371_30380"></div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30381">std::jmp_buf jb;</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30384">int main() {</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30385">  int s = 1;</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30386">  setjmp(jb); </div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30387">  if (s) {</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30388">    s = 0;</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30389">    std::longjmp(jb, 1);</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30390">    return 2;</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30391">  }</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30392">  return 1;</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_30393">}</div><div id="yui_3_16_0_1_1496439047371_22094" dir="ltr"><br></div><div id="yui_3_16_0_1_1496439047371_22094" dir="ltr">One would expect that the load of s in the if condition is not optimized away (by being replaced with if(1)), but clang at -O3 (on linux) generates this:</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32628">define signext i32 @main() local_unnamed_addr #0 {</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32629">entry:</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32630">  %call = call signext i32 @_setjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @jb, i64 0, i64 0)) #3</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32631">  call void @longjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @jb, i64 0, i64 0), i32 signext 1) #4</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32632">  unreachable</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32633">}</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634"><br id="yui_3_16_0_1_1496439047371_32635"></div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634">which leads to an infinite loop execution at runtime.</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634">Aren't we breaking the as-if rule because the semantics of the program imply that the value of s is unknown after the setjmp (because you can enter main from the location of setjmp in the program).</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634"><br></div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634">Thanks.</div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634"><br></div><div dir="ltr" id="yui_3_16_0_1_1496439047371_32634">Wael</div></div></body></html>