<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/74483>74483</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            asm goto miscompilation
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          dvyukov
      </td>
    </tr>
</table>

<pre>
    As far as I understand `asm goto` now supports output arguments on all paths. If I am reading this correctly, in this case `asm goto` corrupts local state (output variable has incorrect value). The code is:

```
#include <stdio.h>

long foo(long a, long b) {
    long x, y, z;
    asm goto(
      "movq %[a], %[x]; testq %[a], %[a]; jnz %l[label1]"
 : [x] "=&r"(x), [y] "=&r"(y), [z] "=&r"(z)
        : [a]"r"(a), [b]"r"(b)
        : "memory" : label1, label2);
    return 0;
 {
        label1:
        return x;
    }
    label2:
 return 1;
}

int main() {
  printf("%lu\n", foo(11, 22));
}
```

With `-O3` the program correctly prints 11:
https://godbolt.org/z/x17GnP4nK

But with `-O0` it prints 0:
https://godbolt.org/z/h7MM9YTfP

The generated code is:
```
foo(long, long):                               # @foo(long, long)
        pushq   %rbp
        movq    %rsp, %rbp
        movq %rdi, -16(%rbp)
        movq    %rsi, -24(%rbp)
        movq -16(%rbp), %rsi
        movq    -24(%rbp), %rdi
        movq    %rsi, %rax
        testq   %rsi, %rsi
        jne     .LBB0_2
        movq %rdx, -96(%rbp)                 # 8-byte Spill
        movq    %rcx, -88(%rbp)                 # 8-byte Spill
        movq    %rax, -80(%rbp) # 8-byte Spill
        movq    %rdx, -72(%rbp) # 8-byte Spill
        movq    %rcx, -64(%rbp)                 # 8-byte Spill
        movq    %rax, -56(%rbp)                 # 8-byte Spill
 jmp     .LBB0_1
.LBB0_1:
        movq    -72(%rbp), %rax # 8-byte Reload
        movq    -64(%rbp), %rcx                 # 8-byte Reload
        movq    -56(%rbp), %rdx                 # 8-byte Reload
        movq    %rdx, -32(%rbp)
        movq    %rcx, -40(%rbp)
        movq    %rax, -48(%rbp)
        movq    $0, -8(%rbp)
        jmp     .LBB0_6
.LBB0_2: # Block address taken
        movq    %rdx, -96(%rbp)                 # 8-byte Spill
        movq    -80(%rbp), %rdx                 # 8-byte Reload
        movq    %rcx, -88(%rbp)                 # 8-byte Spill
 movq    -88(%rbp), %rcx                 # 8-byte Reload
        movq %rax, -80(%rbp)                 # 8-byte Spill
        movq -96(%rbp), %rax                 # 8-byte Reload
        movq    %rdx, -32(%rbp)
        movq    %rcx, -40(%rbp)
        movq    %rax, -48(%rbp)
        jmp     .LBB0_4
.LBB0_3: # Block address taken
        movq    %rdx, -96(%rbp)                 # 8-byte Spill
        movq    -80(%rbp), %rdx                 # 8-byte Reload
        movq    %rcx, -88(%rbp)                 # 8-byte Spill
 movq    -88(%rbp), %rcx                 # 8-byte Reload
        movq %rax, -80(%rbp)                 # 8-byte Spill
        movq -96(%rbp), %rax                 # 8-byte Reload
        movq    %rdx, -32(%rbp)
        movq    %rcx, -40(%rbp)
        movq    %rax, -48(%rbp)
        jmp     .LBB0_5
.LBB0_4:
        movq -32(%rbp), %rax
        movq    %rax, -8(%rbp)
        jmp .LBB0_6
.LBB0_5:
        movq    $1, -8(%rbp)
.LBB0_6:
 movq    -8(%rbp), %rax
        popq    %rbp
 retq
```


If we track the `x` variable, it's spilled to `-80(%rbp)`, but then loaded from `-32(%rbp)`:
```
foo(long, long): # @foo(long, long)
...
        movq    %rsi, %rax
...
        jne     .LBB0_2
...
.LBB0_2: # Block address taken
...
        movq    %rax, -80(%rbp) # 8-byte Spill
...
        jmp .LBB0_4
...
.LBB0_4:
        movq    -32(%rbp), %rax
        movq %rax, -8(%rbp)
        jmp     .LBB0_6
...
.LBB0_6:
 movq    -8(%rbp), %rax
        popq    %rbp
 retq
```


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWM1u4zYQfhr6MoghjSRbOviwTuoiaBddtAsUPRWURFtMJFFLUl47T1-Qkq2fyFknG7Q9bBDIFDnzzQznG4okVYrvSsZWJFiT4G5Ga50JuUr3x_pR7GexSI-rDwq2VAJVcA91mTKpNC1TIAuHqgJ2QguycKAUX0HVVSWkViBqXdUaqNzVBStNRwk0z6GiOlNzuN_CPdACJKMpL3egM64gEVKyROdHgrfAy7aTKja2ZATrSivIRUJzUJpqBgTD1uieSk7jnEFGFfCyhYU9zWtGMJrD54xBIlIGXBHvA3HuiHN6Lpz2v3lFj5dJXqcMiHerdMrFPCPeT32VXJQ72ApBMLRNary3rZhgBGS5buQAoOk-GAEb4xPxeoPnCDHsOgEIYiH2X4BgQII1JcGdUW3eDubNW4NmSk9L0FbioXwyPTkJ1jmNWe5aKWwNEe8DtHDGHvHuCC6kaWF4IBhZvGB9nBo_duNPU-NPZrwXD5ysNY5iK0Y7mHgwEE_rIxasEPJIEG1HG5WZe9NCo9WfXcl0LUtwus5BZmx2GogTI07dreZhAEeWd720NhbPiq2Ge9Y4SzdPXmooKC9NpocUqSQv9db2o0lXTYLb0rZvW465Nka08fVC7CyMGGyff3KdmSK6-c0z9aMzBpUUO0mLruga2wrcbgYyrStbIbghuNmJNBa5ngu5I7h5Irg5uMufy09--Uvf1rrW8PVsz3gCXJ_Anauxs-XHj9Ffn7ef-timcHesZJJqlj4v4WHoXU2eKtJO2DmvF_4IekB8Z1p7QIyqVtkXqxHIuBqO2ZJtx1TV1uO0lBlIuRG5cRc29VZwbG2A2Iij_w3xMWDrhuLT0GPAVjy9IN55Ylr0MJRq1qSx1Nj0Q8ns7_zX9dr5Gy9Nj10zb6JBNJOZC2_io2bwR8Xz_LLXSYMXhu-ER1s8Z4B3vX4b3xLfqN_Gs_DfN57gTfP9UFS9lLpN7-llvLieqTeMvSNV38rvLBc0vQCwmORucnjJ7RcBg8naSd8M2Eu0h9fVeZtX37lOvE2bH14jbkANZy_LDhO56CcSm2-wB-tcJI9A01QypUDTR1Z-M_p3KeNRsb1Per5rXeg8C9-RiZeXlzfM22jqe1X2HZP2n3N6yFO_z1PvB09_8PT_ydOgz1N_-sM4dvbCVmtqK_KyGxNLenDx20zQdy-BnoDOuh27rvG8EtXZ8_PmWDL95YXDTPO838JXBlrS5NGeZ8jCOZizxunwb-8QNMGlAmVYxlLQwp5JRgW5sN_BuNYGpgTDIZbCVorCSo8ysHBefdz49oFiPp-_Zof9THxyE32WuvaL_aIXr9nhPvfvzDh_0rcL7DcsekUBXM9-eLapGfrzr9J5lq68NPIiOmMrd-m4yzAM0Zllqwj9mHpbLwiiwEV0F7HvJ-hFEToBTROc8RU66LnoBG7gLB1nHvtxsNzGEQt8z3cjRnyHFZTn8zzfF-ZsPeNK1Wy19P3Qm9lbC2Xv_RALrhJRVDynmgt74xDczeTKKN7E9U4R38m50qqD0lznbHW6tIIhwKyW-Wp0xOc6q-N5IgqCG4PS_txUUjywRBPcWO8UwY118J8AAAD__xbAL_I">