[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