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

    <tr>
        <th>Summary</th>
        <td>
            machine-cse pass breaks __builtin_setjmp on powerpc
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    The following code is simplified from a program in which `__builtin_setjmp` always returns 0 (at optimization level -Og, not all optimization levels tested).
```
typedef enum memory_order {
 memory_order_relaxed = 0,
  memory_order_consume = 1,
 memory_order_acquire = 2,
  memory_order_release = 3,
 memory_order_acq_rel = 4,
  memory_order_seq_cst = 5
} memory_order;

struct G {
    volatile _Atomic(_Bool) init;
 void *ctx[5];
};

extern void first(void), second(void);

void bad_setjmp(struct G *g) {

    __c11_atomic_store(&g->init, 1, memory_order_release);

    if (__builtin_setjmp(g->ctx) == 0) {
 first();
    } else {
        second();
 }
}
```

In the assembly code I find
```
        bcl 20, 31, .LBB0_5
        #EH_SjLj_Setup  .LBB0_5
```

This is wrong.  The correct code, which you get if you change the constant `1` to `0` in the `__c11_atomic_store` call, is
```
        bcl 20, 31, .LBB0_3
        li 3, 1
        #EH_SjLj_Setup  .LBB0_3
```

The `bcl` instruction saves the address of the following instruction in a register.  A call to `__builtin_longjmp` resumes at that address.  The instruction there should set the return value of `__builtin_setjmp` to 1.  The instruction was moved out of place by the machine-cse pass, which took
```
  SYNC 1
 %1:gprc = LI 1
  STB killed %1:gprc, 0, %0:g8rc_and_g8rc_nox0 :: (volatile store monotonic (s8) into %ir.g, align 8)
  ...
  BCLalways %bb.4, <regmask $zero $zero8>, implicit-def $lr, implicit $rm
  %8:gprc = LI 1
  EH_SjLj_Setup %bb.4
  B %bb.5
```
and eliminated the set of `%8` in favor of reusing `%1`:
```
  SYNC 1
  %1:gprc = LI 1
 STB %1:gprc, 0, %0:g8rc_and_g8rc_nox0 :: (volatile store monotonic (s8) into %ir.g, align 8)
  ...
  BCLalways %bb.4, <regmask $zero $zero8>, implicit-def $lr, implicit $rm
  EH_SjLj_Setup %bb.4
  B %bb.5
```
This transformation is invalid.  The instruction after BCLalways is reachable by __builtin_longjmp and moving the instruction earlier causes it not to execute at the right time.

The instruction description for this particular `bcl` may need to indicate that the instruction overwrites all registers and memory (except SP, FP, BP, and TOC, which revert to their saved values).

An IR file for testing is attached.
[invoke.txt](https://github.com/llvm/llvm-project/files/10514256/invoke.txt)

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkV11v47oR_TX0yyCGTFmO_OCHONm0Cyx6i2ZRoE8CRY0lbihSlxw5yf31xVD-Sta57aKPDQJZJoczZ2YOD2kVo2kd4kYUW1E8zNRInQ-bf_rXJ23G4MPYz2rfvG2-dwg7b61_Ma4F7RsEEyGafrBmZ7CBXfA9KBiCb4PqwTh46YzuQKyyqqpHY8m4KiL96AexykDZF_UWISCNwUXIQMhSEfiBTG_-UGS8A4t7tHDzWyvkPThPoKy9YhGBMBI2Qq7nInsQ2Z1YZYf_9JXeBmxwB-jGHnrsfXirfGgwgLjdTibvhquAVr1iAyJ_gEzI-4PNeyPtXRx7TEaLs9E7G6V_H02YbORnjgJaVHEyyj93xHbJZvmZo4i_VzpSMioOlbh9eGcj8kPC0zNSGDXBXy4KAQB7bxUZi1Ddke-NFrKstt5bIddgnKGTE9h704CQd5peRbEtRPFwDnD78CEYvhIGN63ZmRBJyJK_CLnmBkfU3jUXY-9Xp2W1ao4ckuUZvLxrGdspiXMqVaUXi0qlNKpIPqCQpZCr9kbkX1Iu8j5172pLfkbBPs2OyfoTqWWZnHIpGEv-cGDPBa5T2peO2SW3CS1z4LIP_HeqyrslXNxTla9Rfnp-dUAdgooR-9q-Tdv2K-yMaz5Zta61BcmchzyVZf5tu82q4jQvZP7lr9XTj28_qiekcRDZ-r3JNRzfOxNZLl6Cd-0cgMVE-xBQU8LEgSa1ePMjtEhcY37VnXItpiR4u5FyxIKyYAUhz68cisWGTZLU_NTvVQZaWcsxTPy1tPPTvDVpa8LiPxci_9NCJJS1thPsicKsZFHtMU7dapqAMYLfpa9n0b00Nw4UBGxNJAxzgLuU46EmZ2pa79qD4AZktYqgCKhTdAxz6Malb-owIMTOj7aBiJRgTEINe2VHZGifyDp5WFxx-aIi9H6PDfiRePlglUao35LvXunOOLzREWFQMZ7pQN4_Xy0nwNO__nZqBwhZLER-1w5BJ_X79vU0BU_ft_BsrGU9P5txjNRvIYuMx8qgK-WaKr04_5qByO9Ezr7LkyAmRkHvnSfvjOa5WE6yyKWXhQnzdFopa1oHadMeYMzn8-Pr9v7b4fgTsqjr-TLhyO8Dtr2KzyDk8g8M_vhZivxLYi-ftdrQDZ9lQi5tuBzlkdAfQwhZlJ8V5B1tTxCO2A4D17ezcg2gNb1xirBJzWOCTHxIMafduFN7H3g44BiZu9M071uu6n_R0T9rKXf0_6eV_0O7ku5SUC7ufOinKxMrsdsra5or-1TtCMNFUoZvaEp3qrZpt_6kLMCM6P2ee0wfnKEK1mAArcaIEQylOxx5wFfUI-EkRQjBtB0BmR7nH7Xy0l2DUQczpPedD0Cc3KACGT1aFS50tVdv4JD56cG4xmhFOIneR4h-j-ElGGJdtPYkqHFKK90ImBj4qnEgePo7d-kxPbfpyWbff7s_C1bAPYaUJHVoQpL1ZlLNeHE_Tc87B1__ATsmY8oHIyWZZ40mpTtsjubF1ri9f8Y5vRLfsWTZEQ2RWS0fhXxsDXVjPde-F_LR2v3x42YI_gdqEvKRw0QhHxdZsVjKYiXk44XPI7dnzSZv1vlazXCzWN0ub29Xcp3Nuk1eLnW5XhXZQsl8gWWpNK4ztW7WdVPcLsuZ2chM5tlCrmSel4tsXusiKwqZKaWL3bIpxDLDXhk7Z2BzH9qZiXHEzSrLZTazqkYb068QKR2-QJoUUvKPkrBJydRjG8UysyZSPHshQxY3H48QqAOq5wgfzyjwDgb_gmHQszHYzS_XMeHiQibc_w4AAP__7ToG4w">