<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hi<div><br></div><div>there have been reports on Ruby segfaults triggered by inlining functions with block label address taken like</div><div><br></div><div><br></div><div>//Ruby code snippet</div><div><div style="margin: 0px; font-family: Menlo;">vm_exec_core<span style="color: #ce7924">()</span> {</div><div style="margin: 0px; font-family: Menlo;">  finish_insn_seq_0 <span style="color: #ce7924">=</span> &&INSN_LABEL_finish<span style="color: #ce7924">;</span></div><div style="margin: 0px; font-family: Menlo;">INSN_LABEL_finish<span style="color: #ce7924">:</span></div><div style="margin: 0px; font-family: Menlo;">  <span style="color: #ce7924">;</span>       </div><div style="margin: 0px; font-family: Menlo;">}     </div></div><div style="margin: 0px; font-family: Menlo;"><br></div><div style="margin: 0px;"><span style="font-family: Menlo;">T</span>his kind of scenario can also happen when LLVM picks a subset of blocks for inlining,</div><div style="margin: 0px;">which is the case with the actual code in the Ruby environment.</div><div style="margin: 0px;"><br></div><div style="margin: 0px;">Background:</div><div style="margin: 0px;">LLVM suppresses inlining for such functions when there is an indirect branch. The attached</div><div style="margin: 0px;">patch does so even when there is no indirect branch. Note that user code like above would not</div><div style="margin: 0px;">make much sense: using the global for jumping across function boundaries would be illegal. </div><div style="margin: 0px;"><br></div><div style="margin: 0px;">Why is there a segfault:</div><div style="margin: 0px;"><br></div><div style="margin: 0px;">In the snipped above the block with the label is recognized as dead. So it is eliminated. Instead </div><div style="margin: 0px;">of a block address the cloner stores a constant (sic!) into the global resulting in the segfault (when</div><div style="margin: 0px;">the global is used in a goto).</div><div style="margin: 0px;"><br></div><div style="margin: 0px;">Why did it work in the past then:</div><div style="margin: 0px;"><br></div><div style="margin: 0px;">By luck. In older versions vm_exec_core was also inlined but the label address used</div><div style="margin: 0px;">was the block label address in vm_exec_core. So the global jump ended up in the original function </div><div style="margin: 0px;">rather than in the caller which accidentally happened to work.</div><div style="margin: 0px;"><br></div><div style="margin: 0px;"><br></div><div style="margin: 0px;">-Gerolf</div><div style="margin: 0px; font-family: Menlo;"><br></div><div style="margin: 0px; font-family: Menlo;"></div></body></html>