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

    <tr>
        <th>Summary</th>
        <td>
            Printing llvm::module instance crashes when removing `llvm.stacksave` and `llvm.stackrestore` intrinsics
        </td>
    </tr>

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

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

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

<pre>
    I found that the llvm crashes when trying to print llvm module like:
```
 std::stringstream ss;
  llvm::raw_os_ostream os(ss);
 llvm_module->print(os, nullptr); <---- crash
 os.flush();
```

The crash only happens when adding `llvm::createJumpThreadingPass()` as one of the optimization steps for the IR.
When investigating the generated IR, I found that it has a phi node having two operands holding values generated from `llvm.stacksave()` intrinsic such as:
```
; Function Attrs: uwtable
define void @... local_unnamed_addr #13 {
.entry:
  ...

.BODY: ; preds = ...
...
  %savedstack = call i8* @llvm.stacksave()
...
  br i1 %13, label %LABEL1.i.i, label %LABEL2.i

EXIT:                                           ; preds = %LABEL1.i, %LABEL2.i.i
  %savedstack.i2 = phi i8* [ %savedstack.i1, %LABEL1.i.i ], [ %savedstack.i, %LABEL2.i ] <----
  call void @llvm.stackrestore(i8* %savedstack.i2)
...
```

If I do not add the optimization pass, the generated IR does not have such a phi node.

The problem is this IR is used to generate a CUDA PTX to process the logic on GPU.
But as far as I know, NVIDIA PTX does not know about such intrinsic provided by llvm, I remove them before calling PTX compilation such as:
```
void cleanup_llvm_ir(...) {
  // optimizations might add attributes to the function
  // and NVPTX doesn't understand all of them; play it
  // safe and clear all attributes
...
 std::vector<llvm::Instruction*> stackrestore_intrinsics;
 std::vector<llvm::Instruction*> stacksave_intrinsics;
 std::vector<llvm::Instruction*> lifetime;
  for (auto& BB : *query_func) {
    for (llvm::Instruction& I : BB) {
      if (const llvm::IntrinsicInst* II = llvm::dyn_cast<llvm::IntrinsicInst>(&I)) {
 std::cout << II->getName().str() << std::endl;
        if (II->getIntrinsicID() == llvm::Intrinsic::stacksave) {
 stacksave_intrinsics.push_back(&I);
        } else if (II->getIntrinsicID() == llvm::Intrinsic::stackrestore) {
 stackrestore_intrinsics.push_back(&I);
        } else if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_start ||
 II->getIntrinsicID() == llvm::Intrinsic::lifetime_end) {
 lifetime.push_back(&I);
        }
      }
    }
  }

  // stacksave and stackrestore intrinsics appear together, and
  // stackrestore uses stacksaved result as its argument
  // so it should be removed first.
  for (auto& II : stackrestore_intrinsics) {
 std::cout << II->getName().str() << std::endl;
 II->eraseFromParent();
  }

  for (auto& II : stacksave_intrinsics) {
    std::cout << II->getName().str() << std::endl;
 II->eraseFromParent();
  }
```

And after removing them, I got the crash.

Overall, 
1) I got a crash when trying to llvm module
2) it looks like a specific llvm IR optimization pass can push `stackrestore` and `stacksave` intrinsic multiple times
3) in the IR, I found a phi node having two operands from `llvm::stacksave` intrinsic
4) after removing any `stackrestore` and `stacksave` intrinsic, the crash happens when accessing llvm module.

I hope this provides enough information for reproducing the issue.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWFtv67gR_jX0yyCCLcVK_OAHX5JCxeJscHB2u30yaHFksaFIlaQcuL--GOpiWT7ZbovTNjBiS5r7cL6ZEXdOnjTimi23bLmf8caXxq4vxuhKas2r2dGIyzqDwjRagC-5B18iKHWuILfclejgo0QN3l6kPoE3UFupfUtRGdEoBCXfkSUbNt-z-Yal8-4TLsF5Qc-SjfNW6pPzFnkFzrFk21EEWS2N5R8H4w6mozKOxc_OsXh1pSbiQ6v4gSUvwRoWPxPpDnSjVO1tywAs2T08PDy0jnTsxkWFalzJ4uex2InV7f9vJba8YLS6QMnrGnUXDy4ExYOl86v1uUXu8c9NVX8rLXIieONkflCVzoE7MBrBFCHIpvaykv_gXhoNzmPtoDA2PMq-Rq0JfyFdUp_ReXniPqSgRDihRss9Csi-kt83CZQeSu6AQ11K0EYglPwcOD8MmBot18JBaVTw4MxVg24ksbCm6v2KnOf5u-NnvDohNSXSyRxck5fA3WeppxS8NjoP_m28t0QJzYfnR4UticBCaoSzkQLY4zyKIlAm5-rQ0OFEceBCWGBxskiAPXW5ilB7exm0AkRRNE5btP15_1dSRQbUFoUDluyvVMMPABYvyTkR3AxUOVcK5DOLN2TQd2MwFXK0IBckapFQLhQ_oqLLnzbbl58WkYzk_e04kmOTX37LvpHFf_zv1reRNtI10tLrmfgayTgw0hHpvF1upySLsazgCLDlPty8J57oJcq-AHsLQmz7XF9Da9F5Yym6nSUTQ-9j_t1qzQrIQBjQxlN13pdYHWpxd1dAIAy6wFbyM3aneiieaIoItTVHhRVIB76UjgRIB41DQejYCwYOu1_2G3j79lsLmiZH51pwNSeZg9Hwp7dfOunbxhM4FNzSVwbv2nyQqV9-zfZZK2Qwkp4BP5rGt6Ze67G25iwFCjheWkwNyGCxMmckzRUcsTAWQyKo9klubqpaqg6Efr-gQ-pyhVw39SHgsLQsfqa0xKtrfdJRe2Xx6030HVTyVLaZ4d5beWw8OgoNhaToYGIigGsBX37tvdcsfvLQaIHWeXpEx6nF0iqUg-IXkH4iw_ECgyAy3Aaeq_5pLQ_N6oy5N5Yluyu6Z9p527RmxhuWvMD49B6GNIw6238gjk7-D5ClZIFeVjjqstRbWPzMG29YnMKW-iMV2-bvDdrLgVIwSePA84mmFLIgY7u9YwSQBXHmRjsPY_7OMxJExZ5lAYeuFOKiDzl3fuLgmC15CUicZoQMN5qHIOVUHizZsWQHWUaDwgn9F151GB45GhKeA3NLNHCiFmoUtbEzg6CrOftByv7WjYGkH36GHnJr733Ko7px5eHI8_eRl1OD2NMeUDn8QZYNEHxn3P3x_h_b15_kg_PcemBPO_q0yn6EWNTi1u3-yR_1c3zj5nJ0MfycglOf_4BQ44BfYd0BzZ3cgjcn9CVagnWuxfdE9cyNQ3cVLsCia1RoMdI74PbUVKjvkNLQ6OhK0ygBR-wah4BCWuejT2AkayHgMyj871Zny4uWO3y1pnrjFsMycJupu-D_jgtT-J3i2v_dhe9NPhvqhYVH26asWxK69n8y7UoXFpmbYebnM1quVBjcwo0Fmdty8G7xmex-o62vZaHhjE6NMubdhUUQOLgac1nIvCXPvt6PYZBzDVRftGjcIBBtSVoMtwNk3iwdVaO8rBUC1WjXwJNghe5Wp_FC9C-WoPGuMwXqsdZWzSOpmQSa68u_7UM_hLYhvl0rcxoTSfAo1DdZy6A0NbajZzfwOUBtmhONgoWxVRtmOuQWa2tEk_dro3SuwWgm1olYJSs-w_UifVo9JsvH9HFWrtNV-iiKIlkcxVOaHPkqTYtlIjgek5jP0-VMruN5nMyTeBEvlot5EiUi5Uu-fMrnj4t0mSfscY4VlyoK072xp1lQuU4Xy9VqFlYg17-LsGsiejg2J0frgHTeXdm89ArXb7Tc98Fo89O9cpCaRsAcb19SDFm5X1-vOblfPMa5cbPGqnXpfR3G4ICMJ-nL5hjlpmLxaztYh6-H2pq_Ye5Z_BrcdCx-DZ7-MwAA__8l7lF8">