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

    <tr>
        <th>Summary</th>
        <td>
            Incorrect stack coloring for alloca in SEH cleanuppad
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation,
            platform:windows
      </td>
    </tr>

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

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

<pre>
    Consider the following example (https://llvm.godbolt.org/z/h1WovoPMG):
```llvm
@type_info = external global ptr

define void @test(ptr %arg) personality ptr @__CxxFrameHandler3 {
bb:
  %a1 = alloca ptr, align 4
  %a2 = alloca ptr, align 4
  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a2)
  invoke void @throw()
          to label %bb14 unwind label %bb8

bb8:                                              ; preds = %bb7
  %i9 = cleanuppad within none []
  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a1)
  store ptr %arg, ptr %a1, align 4
  call fastcc void @foo(ptr %a1) [ "funclet"(token %i9) ]
 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a1)
  cleanupret from %i9 unwind label %bb15

bb14: ; preds = %bb7
  unreachable

bb15: ; preds = %bb13, %bb5
  %cs = catchswitch within none [label %bb17] unwind to caller

bb17: ; preds = %bb15
  %cp = catchpad within %cs [ptr @type_info, i32 8, ptr %a2]
  %p = load ptr, ptr %a2, align 4
  call fastcc void @cleanup(ptr %p) [ "funclet"(token %cp) ]
  catchret from %cp to label %exit

exit:
  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a2)
  ret void
}

declare i32 @__CxxFrameHandler3(...)
declare void @throw()
declare void @cleanup(ptr)
declare void @foo(ptr)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
```

Here `%a1` has a lifetime fully contained within the `cleanuppad`, while `%a2` has a lifetime across the whole function. However, the first use of `%a2` is inside the `catchpad`. `%a2` here is the pointer into which the exception object for the catchpad gets written.

With `stackcoloring-lifetime-start-on-first-use` (the default), `%a1` and `%a2` are allocated to the same stack slot. On the surface, this looks fine (because `%a2` is only used after the cleanuppad). However, there is a quirk of SEH exception handling that makes this incorrect: The exception will be copied into `%a2` by the personality function *before* both the `cleanuppad` and `catchpad` are called. As such, the write to `%a2` happens earlier than our IR modeling implies.

There has been a patch to fix this issue in https://reviews.llvm.org/D86673. Unfortunately, that patch does not handle this case, because it checks for `NumLoadInCatchPad[slot] > 1` -- I think the intention might have been to write `> 0`. (Funnily, just completely undoing the changes from that patch doesn't make the patch test case fail...)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV1tv27gS_jX0y8CCTFm2_OCHXOqTAOdSnO2ijwVFjSzWFKklqTjZX78YSrZlb9N2sWsESUQP5_J93wwp4b3aG8Qty-8Z50YdlGScs_xxJvrQWLeNS7PSVm_bB2u8qtBBaBBqq7U9KrMHfBVtpxEYL5oQOs-yO8Z3jO-0fmmTva1Kq0Ni3Z7x3e-M75rFZ_tiP_7nX4xvyDZ9ZOkdW6XDD20al5ZpeOvwizK1BZY9Ar4GdEZo2GtbCg1dcKNl_F1hrQzCi1UV0F70gfGiCw4YzwWF30CHzlsjtApvEL9Zpl--PLy-7pxo8UmYSqPLgK3vB5dleU4QopdFTERobaWI8fkDCK32BpZTM_5jMym0PucakdKqxqBaTHwQLiRdynihVktY0m5K1lhjeq2HCATe6EqZF3uYFN44e2S8mFicPsGCFiVGF2W5WEJvjspU08ViCik9ZpP9P_Nh2T10DisfMYg-1xNs1CauS43C9F0nKjiq0ChD1SGQDPPHfwijxQQBH6xDmIrh4fy0eI-eWvgg5TmD2tqJoMg75QuM87o3UmOgzuFFsAc0Q6mDyame75SDpvoLxYzgOQxQO9uOsP6Zy0V-TeZiSWx-j6DeOBSyEaXGm635O1sXGWUb_80nNMvBRIogG39UQTa3PE_zXLP88ZR_sBEodDcJrN9L4Cpsdwk70daYUH4_9vx5rlDuKuNQTPXAJxJkPB9caiuqUytfDH9OOCNfF_F0P9SO7K61M5Q0ZVx2V-2MrypMEYvPl-H1t7Q3HTaUAvkZY60fr0ew1MJhhPSbo5XxIkmSs7uT_buj69bgCsl3rc6N-q7Fd4eJatvJhDBWii70Dn_S2RWcP3J1PvamKD6hQ6C12ParFBrhQcApAtS91m8grQlCGTyLnE5ltkovkzW6eIBjo_TZH_-GPyGd9T7uPzZWUwAjg7ImgSd7xBeMoo-HvnI-QO8RbH3lUXlQ8XJwzmLsQLZKk-vYVJwaonVWmYAOlAmW0pRNXMZXiR3FB1t-RRmgtsOd49zWewwejk6FgCaZQvdZhYbC-SDkQVptnTL7-anSeSR6bs08FjLvPVJK1HcNQoW16HUgbmiiTfAXprqqgcgfDveAcWDRdi9ahBgXvLYhgf8NlPje1ULiAKHyoK09eIhXFcaLEqUgPG_AtEa_Ec4ViDqMN64JsXxzS80AqoDfeuUOxM4vH54mQDbUf3RZC40I0IoD-iEbZaR1DiXNCvh0Bf5RaQ0lgrSdwmogaZpm-TaQOLlSnYQDjN-VWFtS-h2UNjTfVOcJ2IlYIrZx_lcJ3HnwvWxO6iPCEW6yaETXofGAwmkVkRIGbO_g-f_Q2gpj1arttEJ_JZVPETRqhRLRgICOsiD3tXodwfG-R1AGru-1Dl8UHn0S-3641z4Wq9U6S-BXU1sXeiMC6rchbxFGz5VFD8aGgQwcQkjhozROOlABZIOSFGIdFfrfvv23FdWzeSAnH0XF8nvSF52YLPsAUaDzOTyTP3OIQFFXmchDq_YNBXzBoUrqs4giQZh9gHToT17semPUkPLX3geQlu70VAX0prKDdBBkI8we_XAI3dRmGF8P2hp0McCJ5Ex4hFooPcz-WbXNqk22ETPcLlabnBdpul7Pmm2dFQI3fFEUyOsFz2WG5bLCTMqqyvOVnKktT3mWbvgiXafrfJ2sRIV8tdpUWZ7J5UKyZYotBTpxM4scblerTbGcxcPSj-86rfJUpNKCkIrH7wPjvNMi1Na1LLuj64g9-vF9yG3J57zs955mvvLhooBZUEHj9vnUTOMcOA2gyOX4NqBMbM1LH8x6p7fXAtur0PRlIm07vkWNf-adszQQGd_Fsjzju1jZHwEAAP__AxRCag">