[llvm-branch-commits] [llvm] release/23.x: [RISCV] Ensure Shadow Stack checks correct RA (PR #231323)

Mitch Briles via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Oct 21 01:22:16 PDT 2026


================
@@ -0,0 +1,136 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+
+; RUN: llc -mtriple=riscv32 -mattr=+v,+zimop,+save-restore %s -o - | FileCheck %s --check-prefixes=RV32V
+; RUN: llc -mtriple=riscv64 -mattr=+v,+zimop,+save-restore %s -o - | FileCheck %s --check-prefixes=RV64V
+
+
+declare void @g()
+
+define <vscale x 4 x i32> @w(<vscale x 4 x i32> %a) shadowcallstack {
+; RV32V-LABEL: w:
+; RV32V:       # %bb.0:
+; RV32V-NEXT:    addi gp, gp, 4
+; RV32V-NEXT:    sw ra, -4(gp)
+; RV32V-NEXT:    .cfi_escape 0x16, 0x03, 0x02, 0x73, 0x7c #
+; RV32V-NEXT:    call t0, __riscv_save_0
+; RV32V-NEXT:    .cfi_def_cfa_offset 16
+; RV32V-NEXT:    .cfi_offset ra, -4
+; RV32V-NEXT:    addi sp, sp, -16
+; RV32V-NEXT:    .cfi_def_cfa_offset 32
+; RV32V-NEXT:    csrr a0, vlenb
+; RV32V-NEXT:    slli a0, a0, 1
+; RV32V-NEXT:    sub sp, sp, a0
+; RV32V-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 2 * vlenb
+; RV32V-NEXT:    addi a0, sp, 32
+; RV32V-NEXT:    vs2r.v v8, (a0) # vscale x 16-byte Folded Spill
+; RV32V-NEXT:    call g
+; RV32V-NEXT:    addi a0, sp, 32
+; RV32V-NEXT:    vl2r.v v8, (a0) # vscale x 16-byte Folded Reload
+; RV32V-NEXT:    csrr a0, vlenb
+; RV32V-NEXT:    slli a0, a0, 1
+; RV32V-NEXT:    add sp, sp, a0
+; RV32V-NEXT:    .cfi_def_cfa sp, 32
+; RV32V-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32V-NEXT:    .cfi_restore ra
+; RV32V-NEXT:    addi sp, sp, 32
+; RV32V-NEXT:    .cfi_def_cfa_offset 0
+; RV32V-NEXT:    lw ra, -4(gp)
+; RV32V-NEXT:    addi gp, gp, -4
+; RV32V-NEXT:    .cfi_restore gp
+; RV32V-NEXT:    ret
+;
+; RV64V-LABEL: w:
+; RV64V:       # %bb.0:
+; RV64V-NEXT:    addi gp, gp, 8
+; RV64V-NEXT:    sd ra, -8(gp)
+; RV64V-NEXT:    .cfi_escape 0x16, 0x03, 0x02, 0x73, 0x78 #
+; RV64V-NEXT:    call t0, __riscv_save_0
+; RV64V-NEXT:    .cfi_def_cfa_offset 16
+; RV64V-NEXT:    .cfi_offset ra, -8
+; RV64V-NEXT:    addi sp, sp, -16
+; RV64V-NEXT:    .cfi_def_cfa_offset 32
+; RV64V-NEXT:    csrr a0, vlenb
+; RV64V-NEXT:    slli a0, a0, 1
+; RV64V-NEXT:    sub sp, sp, a0
+; RV64V-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 2 * vlenb
+; RV64V-NEXT:    addi a0, sp, 32
+; RV64V-NEXT:    vs2r.v v8, (a0) # vscale x 16-byte Folded Spill
+; RV64V-NEXT:    call g
+; RV64V-NEXT:    addi a0, sp, 32
+; RV64V-NEXT:    vl2r.v v8, (a0) # vscale x 16-byte Folded Reload
+; RV64V-NEXT:    csrr a0, vlenb
+; RV64V-NEXT:    slli a0, a0, 1
+; RV64V-NEXT:    add sp, sp, a0
+; RV64V-NEXT:    .cfi_def_cfa sp, 32
+; RV64V-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64V-NEXT:    .cfi_restore ra
+; RV64V-NEXT:    addi sp, sp, 32
+; RV64V-NEXT:    .cfi_def_cfa_offset 0
+; RV64V-NEXT:    ld ra, -8(gp)
+; RV64V-NEXT:    addi gp, gp, -8
+; RV64V-NEXT:    .cfi_restore gp
+; RV64V-NEXT:    ret
+  call void @g()
+  ret <vscale x 4 x i32> %a
+}
+
+define <vscale x 4 x i32> @z(<vscale x 4 x i32> %a) "hw-shadow-stack" {
+; RV32V-LABEL: z:
+; RV32V:       # %bb.0:
+; RV32V-NEXT:    sspush ra
+; RV32V-NEXT:    call t0, __riscv_save_0
+; RV32V-NEXT:    .cfi_def_cfa_offset 16
+; RV32V-NEXT:    .cfi_offset ra, -4
+; RV32V-NEXT:    addi sp, sp, -16
+; RV32V-NEXT:    .cfi_def_cfa_offset 32
+; RV32V-NEXT:    csrr a0, vlenb
+; RV32V-NEXT:    slli a0, a0, 1
+; RV32V-NEXT:    sub sp, sp, a0
+; RV32V-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 2 * vlenb
+; RV32V-NEXT:    addi a0, sp, 32
+; RV32V-NEXT:    vs2r.v v8, (a0) # vscale x 16-byte Folded Spill
+; RV32V-NEXT:    call g
+; RV32V-NEXT:    addi a0, sp, 32
+; RV32V-NEXT:    vl2r.v v8, (a0) # vscale x 16-byte Folded Reload
+; RV32V-NEXT:    csrr a0, vlenb
+; RV32V-NEXT:    slli a0, a0, 1
+; RV32V-NEXT:    add sp, sp, a0
+; RV32V-NEXT:    .cfi_def_cfa sp, 32
+; RV32V-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32V-NEXT:    .cfi_restore ra
+; RV32V-NEXT:    addi sp, sp, 32
+; RV32V-NEXT:    .cfi_def_cfa_offset 0
+; RV32V-NEXT:    sspopchk ra
+; RV32V-NEXT:    ret
+;
+; RV64V-LABEL: z:
+; RV64V:       # %bb.0:
+; RV64V-NEXT:    sspush ra
+; RV64V-NEXT:    call t0, __riscv_save_0
+; RV64V-NEXT:    .cfi_def_cfa_offset 16
+; RV64V-NEXT:    .cfi_offset ra, -8
+; RV64V-NEXT:    addi sp, sp, -16
+; RV64V-NEXT:    .cfi_def_cfa_offset 32
+; RV64V-NEXT:    csrr a0, vlenb
+; RV64V-NEXT:    slli a0, a0, 1
+; RV64V-NEXT:    sub sp, sp, a0
+; RV64V-NEXT:    .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x20, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 32 + 2 * vlenb
+; RV64V-NEXT:    addi a0, sp, 32
+; RV64V-NEXT:    vs2r.v v8, (a0) # vscale x 16-byte Folded Spill
----------------
MitchBriles wrote:

Does this overwrite the saved `ra`? Also, out of curiosity, if `ra` doesn't match the SS on `ret`, is hw supposed to trap? Same thing on lines 25, 57, 91.

https://github.com/llvm/llvm-project/pull/231323


More information about the llvm-branch-commits mailing list