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

    <tr>
        <th>Summary</th>
        <td>
            [AArch64] Miscompilation with -mbranch-protection=standard since LLVM 15.0
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:AArch64,
            regression,
            miscompilation
      </td>
    </tr>

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

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

<pre>
    Since LLVM 15.0, or more precisely, 7c13ae6490b102a7d14d75c8f502f3e003118f49 (reviewed at https://reviews.llvm.org/D125335), there's a regression when compiling code for aarch64 with `-mbranch-protection=standard`, causing a miscompilation, leading to crashes at runtime.

The issue can be observed with a very reduced testcase like this:
```c
void _setjmp();
void a(int b) {
  _setjmp();
  for (; b;)
 ;
}
```
If compiled with Clang after the regressing commit, 
```console
$ clang -target aarch64-linux-gnu -S -O3 test.c -mbranch-protection=standard -o - -fno-asynchronous-unwind-tables
 .globl  a                               // -- Begin function a
a: // @a
        hint    #25
        stp x29, x30, [sp, #-32]!           // 16-byte Folded Spill
        str x19, [sp, #16]                  // 8-byte Folded Spill
        mov x29, sp
        mov     w19, w0
        bl      _setjmp
        hint #36
        cbz     w0, .LBB0_2
.LBB0_1: // %for.cond
                                        // =>This Inner Loop Header: Depth=1
        b       .LBB0_1
.LBB0_2: // %for.end
        ldr     x19, [sp, #16] // 8-byte Folded Reload
        ldp     x29, x30, [sp], #32             // 16-byte Folded Reload
        hint    #29
 ret
```
(`-fno-asynchronous-unwind-tables` is only included to improve readability of the output code, it's irrelevant for the actual issue at hand.)

The breakage exists in this part of the compiler output:
```
        mov     w19, w0
        bl      _setjmp
 hint    #36
        cbz     w0, .LBB0_2
```
Before the regression, the output was:
```
        mov     w19, w0
        bl _setjmp
        hint    #36
        cbz     w19, .LBB0_2
```

The value in `w0` is backed up in `w19`, before calling the function `_setjmp`. After calling another function, the registers `x0`- `x15` are to be considered clobbered - but the `cbz` instruction inspects the register `w0`, while it was supposed to be read from `w19` instead.

CC @davemgreen who reviewed it. (The patch author doesn't seem to be reachable on github any longer.) I'm unsure if this is an issue with the patch itself at hand, or if this was a preexisting issue that was uncovered by the new pass.

If inspecting the output with `-mllvm -print-after-all`, the first difference in the output (after the new pass) is this:
```diff
 bb.0.entry:
   successors: %bb.2(0x30000000), %bb.1(0x50000000); %bb.2(37.50%), %bb.1(62.50%)
   liveins: $w0, $lr, $x19
   frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp
 early-clobber $sp = frame-setup STPXpre $fp, killed $lr, $sp(tied-def 0), -4 :: (store (s64) into %stack.2), (store (s64) into %stack.1)
   frame-setup STRXui killed $x19, $sp, 2 :: (store (s64) into %stack.0)
   $fp = frame-setup ADDXri $sp, 0, 0
-  $w19 = ORRWrs $wzr, killed $w0, 0
+ $w19 = ORRWrs $wzr, $w0, 0
   BUNDLE implicit-def $lr, implicit-def $w30, implicit $sp {
     BL @_setjmp, implicit-def $lr, implicit $sp
 HINT 36
   }
-  CBZW killed renamable $w19, %bb.2
+  CBZW $w0, %bb.2
```

For function calls other than `_setjmp`, there wouldn't be a bundled `HINT` instruction following it, which might be causing the issue.

Also attached is the full original, unreduced test file where the issue was triggered: [setjmp-bti-breakage.zip](https://github.com/llvm/llvm-project/files/13500294/setjmp-bti-breakage.zip)

When compiling that file, with the flags above, there's the following diff in the output:
```diff
--- good        2023-11-29 14:06:55.907069198 +0200
+++ bad 2023-11-29 14:06:57.343074970 +0200
@@ -369,21 +369,21 @@
        mov     w21, w5
        str     x1, [sp, #352] // 8-byte Folded Spill
        mov     w20, w3
        ldr     x0, [x0, :got_lo12:checkasm_context_buf]
        mov     w19, w2
        bl _setjmp
        hint    #36
        mov     w8, w19
        lsl w19, w19, #2
-       str     w21, [sp, #364]                 // 4-byte Folded Spill
+       str     w5, [sp, #364]                  // 4-byte Folded Spill
        str     w8, [sp, #348]                  // 4-byte Folded Spill
-       cbz     w21, .LBB1_2
+       cbz     w5, .LBB1_2
```


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWF1v47jO_jXqDeFAlj-SXPQiabbYAWY_MDPvu4tzM5BtOtZWkQxJTtr59QeS7Hy1aXfPOUbRuqZEkY_Eh6S4tWKrEO9JsSbF5o4PrtPmfmedNvYvfVfp5uX-q1A1wufP__8LpMWMEvYA2sBOG4TeYC0syhf_cV6nGccyX9IqpYzPmzRv5kW9aAvK2gwpzdJ00eZLIGxhcC_wgA1wB51zvSXZirBHwh6jxM6k3O9m2mwJe9ykrMiygrClX8Z1aJCwuQUOBrcGrRVawaFDBbXe9UIKtYVaNwitNsC5qbsyh4NwHZCSJrvKcFV3SW-0w9oJrUi2sY6rhpuGlMG_mg_Wa-GwEzYq5WEkewCJvPEyp6E23HZovRNmUE7scEbohtBV_P2tQxDWDgg1V1Ah6Mqi2WMTjeGwR_MCBpuhxgYcWldziyDFE4LrRMAkqitp_Knj_3stGvhu0f216wlbeGCy9ZmIE7YQykFF2BLIfBTBjSkQcPIfszVU_jNbjpLjGDLfXJkS__3UjphPTj1I7nFrHRq_U8cdCluy2wnnIbz2SiurJY5fWQ51UJI4brboph1MpFDDc7JVAyRfIfktC4jNanh_RyHRkEDSKp1w-6LqzmilB5sM6iBUkzheSbSju7Ot1JUE4PD-E08qJAmscSsUtIMKywKPijjJVtMgklM-4Ryfzm9N0JKx4lJkXQ_P8Zg_Z-EkkmJt-_DCsiRjpNgQlr42JS2T6sUhPGrZYANfeyHltWoDz-nyWmdakmJz08PFR1p3ej8ZbPvXIv8c4qIHein2OPtnOpOvISIsy8rL73X1I-oM2Mw-r9f0O4tD4j_pOfKsaLWZ1Vo1l1o-eqb52YZkP33rhIVPSqGBz1r38DPyBo1fZoO960i2Sa8cG_9OBp1Zx15bh9fGycaEvzf36s2t-YJS81ea-qjpjQPlj1HQmbG3XL86Tm9pPz_FE10YdG-yhOeWkn4UgyUFYUEr-QJC1XLwKzsNYtcbvfdMwhteCSncC-g2kIseXD-4wPXeHU8ucwvCGJS458oFYvMDee0GLkcy9imHq2Z2pLkTW1cG-RPfIuCzsM6CUIGIoefGTYuOfGfG1V-T9P8gDM7A_QchcGXBGlufo89ZOGawM-gO_I0s808duB3CH7gQNb7nw2lr9lwO6DeElPRAx8NS8foJGxj6SZAuxwxeRedrLkM54F0-sjQp6WRySWewCslqGsmV9hXGcfQEmMGtsA6N9dOfvQFJeEsLbwv3QGuf430yEw0abKCWuqrCWwLV4IIan-6qH8F8ZZ0ZokVC2R5rZy9WOnoaYO-ERBBhx8AOfa9tDI8qRga0Ru9OEATtyJuLeuThwWejhu9xtzWIvmbScKzEhJv5IsBj3XNXdxCLQWg0WkXY3IFF3J2WrDsftqAVbIXrhgq4egGp1RaNDy34RNh8B4Oyg0EQbQwkYYGrMQ5DveCOywlnUbZTdI5V5jTPe819uRkC0-9T1OE6HiEZVK33AevqJShVeICeW3uBwKd2gno6FFMcHKtDX3dC0huhXBLKmIRLOW5COEXCWAeNaFs06AvjwBFHRYQtTsXPZIOHQ9gbNZ1XNcZHVc3oDJUzL8dhPnMPdY3WamNj-iiqasYIW9DnjMZnrIyjKA2i4kyUrc9mZfNZQQkrXs0p2UkwLS3FHoUa180j5RCWSzO--CQ1jW0N32Fi0Q09_L56-LT6-rvnbilq4ZIG29PE6Ss8CekLx9cCwvJjOYHcyJdkjKUo8an5Yr2v337_szfopW3Ilteao0K2cAKbYMyEWZKDxzo4uPBtD4aXMg97ppz2CFnH6yeP3gjZBwPTcwgvzfzy5yDOjJuSfLTuAdjfNoaerxHcfgXKarP504iTchp_hUlJmHRIl2HWb1--_OGJjeWHH-YSvsP5LMLW7067Hg8A6__7dfP5pw8OwvT1EEuUy2Nw3sB4hZ89iR07mddK3jlKP3_69RucZaNjV5MAPKz_9cfkt0HFd4HdorenQGEnIOKMs7A4l7-VxR71KauEdGMhphrX8aukdOxz4aAH2UT6rRA4VINqwtaU1HtznUhaLaU-BH50Y9qoO9iJbRfmT32tmzrTC3ZcSauBO8frzucDO2ZNKUEbsRWKS69yUOcdK7Q-Lx2CrUetgZGdEdutZ-Rwnot1dC6pnEimMmv2Q8RSdHF5BxATyqzWO8IePSGPf3yH9xfWjrBHv6wl7DHNCkrZMifs8dYCl2XeH5f3BCGBeGUBrSkjtZJvLfBK7_HyyiEIjxh76r7k__foPUkS2GrdTGUQoyxL0jRhS0hzkq1oSbJVUcyWdE7LZbpcAGFryugp-OIPVLy5MXk-y_KMzvPlnF5NzinJKSRZ6Q8zS7309B6EN6o-lgZkXjWqU5dy3aRkBbvZpdxoIOM6sczJbnRDU-8yvmSrrXbfpU59S1V3WD9xu_tea-Xw2X2vhtYfq3fLWPZfl7FHjYug8CwVRtOtPC42UUjGjnxzAeOI8gWOZf5WZz7imt_CNTDTpe7ib6r-UPf15kfHLzTni_9I84THsTOIePjOIP3Orj07jipeD3qLeO-a-6xZZkt-h_fpnKaspDQr77r7OaMtw7JIy2KRpjStsU6Luq1YiViVS3on7n2cpSlbpizNimKWN7ypK8rKquSLklYkp7jjQh6vK-8CAd7Ps_lifid5hdKGy1XGQq-iPBuuVuFCizBG2ANh7Lw7Gz9dXzv6mLoz94EEq2FrSU6l71BP6zrhZLjHnbQXG_jlQkuktw9uy-zlZe_dYOT9PybngIFn5wDDvwMAAP__zdNVrg">