<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [MergeFuncs] Thunk calls may be invalid under calling convention"
   href="https://bugs.llvm.org/show_bug.cgi?id=40232">40232</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[MergeFuncs] Thunk calls may be invalid under calling convention
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Interprocedural Optimizations
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>nikita.ppv@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Originally reported at <a href="https://github.com/rust-lang/rust/pull/57268">https://github.com/rust-lang/rust/pull/57268</a>.

Running

define ptx_kernel i32 @func1(i32 %a, i32 %b) {
  %x = add i32 %a, %b
  %y = add i32 %x, %b
  ret i32 %y
}
define ptx_kernel i32 @func2(i32 %a, i32 %b) {
  %x = add i32 %a, %b
  %y = add i32 %x, %b
  ret i32 %y
}

through opt -mergefunc results in

define ptx_kernel i32 @func1(i32 %a, i32 %b) {
  %x = add i32 %a, %b
  %y = add i32 %x, %b
  ret i32 %y
}

define ptx_kernel i32 @func2(i32, i32) {
  %3 = tail call ptx_kernel i32 @func1(i32 %0, i32 %1)
  ret i32 %3
}

However, while LLVM does not validate this an error, calling a ptx_kernel
function from another ptx_kernel function is not legal and will error while
assembling.

Leaving aside the question of whether merging functions on the NVPTX target
makes sense, the correct way to merge these functions is probably the same as
for interposable functions:

define i32 @0(i32 %a, i32 %b) {
  %x = add i32 %a, %b
  %y = add i32 %x, %b
  ret i32 %y
}

define ptx_kernel i32 @func1(i32, i32) {
  %3 = tail call i32 @0(i32 %0, i32 %1)
  ret i32 %y
}

define ptx_kernel i32 @func2(i32, i32) {
  %3 = tail call i32 @0(i32 %0, i32 %1)
  ret i32 %3
}

Apart from ptx_kernel, there are probably other cases that are affected by this
as well (I'd imagine amdgpu_kernel and spir_kernel may have similar
restrictions.)</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>