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

    <tr>
        <th>Summary</th>
        <td>
            Wrong LICM of expression involving pointer to `alloca` object in coroutine function
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            loopoptim,
            coroutines
      </td>
    </tr>

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

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

<pre>
    Compile following code
```
;  opt -passes=licm t19.ll -S

define ptr @f(i32 %n) presplitcoroutine {    
entry:    
  %pointer1 = alloca ptr    
 %pointer2 = alloca ptr    
  %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)    
  %size = call i32 @llvm.coro.size.i32()    
 %alloc = call ptr @malloc(i32 %size)    
  %hdl = call noalias ptr @llvm.coro.begin(token %id, ptr %alloc)    
  br label %loop    
 
loop:    
  %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ]    
  %inc = add nsw i32 %n.val, 1    
  call void @print(i32 %n.val)    
  %0 = call i8 @llvm.coro.suspend(token none, i1 false)    
  switch i8 %0, label %suspend [i8 0, label %resume    
                                i8 1, label %cleanup]    
    
resume:    
  %fca.0 = insertvalue [2 x ptr] poison, ptr %pointer1, 0    // These 2 instructions
  %fca.1 = insertvalue [2 x ptr] %fca.0, ptr %pointer2, 1    // should not be hoisted
  call void @foo([2 x ptr] %fca.1)    
  br label %loop    
    
cleanup:    
  %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)    
  call void @free(ptr %mem)    
  br label %suspend    
suspend:    
  %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none)    
  ret ptr %hdl    

    
declare void @free(ptr)    
declare ptr @malloc(i32)    
declare void @print(i32)    
declare void @foo([2 x ptr])    

```
I got
```
entry:
  %pointer1 = alloca ptr, align 8
  %pointer2 = alloca ptr, align 8
  %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
  %size = call i32 @llvm.coro.size.i32()
  %alloc = call ptr @malloc(i32 %size)
  %hdl = call noalias ptr @llvm.coro.begin(token %id, ptr %alloc)
  %fca.0 = insertvalue [2 x ptr] poison, ptr %pointer1, 0 // %pointer1 and %pointer2 points to 
  %fca.1 = insertvalue [2 x ptr] %fca.0, ptr %pointer2, 1           // stack objects in ramp function
  br label %loop

loop:                                             ; preds = %resume, %entry
  %n.val = phi i32 [ %n, %entry ], [ %inc, %resume ]
  %inc = add nsw i32 %n.val, 1
  call void @print(i32 %n.val)
  %0 = call i8 @llvm.coro.suspend(token none, i1 false)
  switch i8 %0, label %suspend.loopexit [
    i8 0, label %resume
    i8 1, label %cleanup
 ]

resume:                                           ; preds = %loop
 call void @foo([2 x ptr] %fca.1)                                      // This instruction is in the resume function, it can't access ramp function stack objects
  br label %loop

cleanup: ; preds = %loop
  ...
```

In the original code, two pointers are passed to function foo, so they can be accessed by foo, all of the related instructions (construction of %fca.1 and function call) will be placed in resume function of a coroutine, so there is no problem.

After LICM, the construction of %fca.1 is hoisted out of the loop, and later these instructions will be placed into ramp function. The pointers contained in %fca.1 points to stack objects of ramp function. Later %fca.1 is passed to resume function through coroutine frame, and used by function foo, unfortunately the ramp function frame does not exist at this time, so the pointers passed to foo are invalid.


</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0V9Fvoz4S_mucl1EROCEhD3lIW1Vaae_pTrpnA0PwrbGRbdJ2__rTGAiQJrvdVX9RJQoej2e-bzyfLZyTJ414YOkjS59XovO1sYdXlKfO_KzlKjfl--HJNK1UCJVRyrxKfYLClMjiI9vGw198ZOtHANN6eGiFc-jY-lnJogGf7COl4OHfZBMfS6ykRmi9BbaJK8YzuebAeKoZ30Nr0bVK-sJY03kyZLtHAAAWH1F7-87Wx-EVaFJrpPZoE2DrZxBKmUIE14PJZMHvWJCJLMNgIZQCb36gpsiUOjcRhRHJcggyZvwpzNWdUvf_3899O_kTJ-8h1blvGo7kmjOezSYynoZIp4kDXE34PGFG068WrEs1TdNGKCncOH1aN8eT1IxnQ7qEwZjEuPjcb25BiRwVDSpj2kug8ZFer0jR0Vn0QbS17HNOHweKn-gZmASWPof3fkzqYhi16LoGaXhBku7hEGUJ2r3CWDW0Fk1MLsYh87MhVjdxa6X2syLrzReIxTN-sit6OteiLi9AaaORFpMJVEK5BfbuVfqiDi54GkrlAtnghlKVGSzHhmxHL7_-yQySxexCodBdO8cqPHqvV7xUhYj6ZKV2aP1ZqI5wfuTwRtSTl9ZIZ_SsFsYdRp_i4I2_MP4C_6nRIXBy5W1XeGm0my-U_GahMZ6PS_GJzn4pV5tOlaCNhxyhNtJ5LD9SXRlD2-jWKslnirl_jIguoWuw-bAZpzKpLOLdzVSXi4JbhtxPHCwbbO7FOVZQPzaW5TLGTncOZ61MJsso-0KeRzUv5CeYl_gUhUU_y2T4zHbPM8hKLJSweCOrydFoc6ORfTS6sXnvG92gfTK-0qhvcDL-6tsoK7-RFEJIKHnSkF1ZXkvLDcuvVpi_Updx0h9Jyz8hK1_Yj4YOMadNUKOdkRP-ceANfHV7Gn5jl_Ki-AEm_x8W3oHUYEXTQtXp0Btvdp6-QGcK-ukfHbZai6ULaVxkZK6vX67Gn1biT6vw1yjwJ9U3IpzxTXrKcWhed9R4Gr2ttnTyCXhcK-3fsjcUwx_r2SeWGtVaurlUQ3gFXyMMBF8KlcD1UAjN-M6DKAp0blnLy1L_RWXPtPRuyhBF0fVNIj5-62MzVp6kFqq_b5BGvRoY9qGDoCd01yhpd1-iC7g9gTPk4p0yoWNDnwiWkL-PFgS2qQYQlPBYLk4zwHhWmBlmppq6B3WZy4pEGzHyKpWitVoliuDsGlxyIeByuZnCtEiMaAOtNbnCJuphOFYeLXz_9vSvkHyNcDcg6caTEZjOj3kFlClVXQJlaOmrw2WeH8L2Zkl4RKe9CffCaC-k7jO8BDD12WUnNNW1s-8hkHnkE4vXgPnamu5UT5hBZUXf6CinbmT0ivxOV8b6TguP6r1neFHBwQmUBl04VuKbdB6EB0_7xMtmRs2U96zWjAnVJ_VZKFkObK3Kw7rcr_dihYdkl_Jst0132ao-bDbJOttX2Xa7z5NMJNtNycW6zDfbXZryNFnJA495Gu-SjPN4v84inu-SLK92WZ5s091uyzYxNkKqKHRGY08r6VyHh2Sz38abVdh7LlziOSfOTetlwzhpFeP8Ap6jT-nzyh7Iz0PenRx1W-m8mzx76RUe_muNPoXSIwbxjW7mLnQOfTbqLPVpBCZI6zbuD0BsGw_MU3HMWBuQX3VWHWrvW0dHrtCcTtLXXR4VpmH8haIYHg-tNeSI8ZeQrGP8Zcj3fOD_DwAA___yrPxz">