1 ; RUN: llc -mattr=+zcmp -verify-machineinstrs \
2 ; RUN: -mtriple=riscv32 -target-abi=ilp32 < %s \
3 ; RUN: | FileCheck %s -check-prefixes=RV32IZCMP
4 ; RUN: llc -mattr=+zcmp -verify-machineinstrs \
5 ; RUN: -mtriple=riscv64 -target-abi=lp64 < %s \
6 ; RUN: | FileCheck %s -check-prefixes=RV64IZCMP
8 ; This source code exposed a crash in the RISC-V Zcmp Push/Pop optimization
9 ; pass. The root cause was: Not doing a bounds check before using a returned
12 declare dso_local void @f1() local_unnamed_addr
13 declare dso_local void @f2() local_unnamed_addr
14 define dso_local void @f0() local_unnamed_addr {
15 ; RV32IZCMP-LABEL: f0:
16 ; RV32IZCMP: .cfi_startproc
17 ; RV32IZCMP-NEXT: # %bb.0: # %entry
18 ; RV32IZCMP-NEXT: bnez zero, .LBB0_2
19 ; RV32IZCMP-NEXT: # %bb.1: # %if.T
20 ; RV32IZCMP-NEXT: cm.push {ra}, -16
21 ; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16
22 ; RV32IZCMP-NEXT: .cfi_offset ra, -4
23 ; RV32IZCMP-NEXT: call f1
24 ; RV32IZCMP-NEXT: cm.pop {ra}, 16
25 ; RV32IZCMP-NEXT: .cfi_restore ra
26 ; RV32IZCMP-NEXT: .cfi_def_cfa_offset 0
27 ; RV32IZCMP-NEXT: .LBB0_2: # %if.F
28 ; RV32IZCMP-NEXT: tail f2
29 ; RV32IZCMP-NEXT: .Lfunc_end0:
31 ; RV64IZCMP-LABEL: f0:
32 ; RV64IZCMP: .cfi_startproc
33 ; RV64IZCMP-NEXT: # %bb.0: # %entry
34 ; RV64IZCMP-NEXT: bnez zero, .LBB0_2
35 ; RV64IZCMP-NEXT: # %bb.1: # %if.T
36 ; RV64IZCMP-NEXT: cm.push {ra}, -16
37 ; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
38 ; RV64IZCMP-NEXT: .cfi_offset ra, -8
39 ; RV64IZCMP-NEXT: call f1
40 ; RV64IZCMP-NEXT: cm.pop {ra}, 16
41 ; RV64IZCMP-NEXT: .cfi_restore ra
42 ; RV64IZCMP-NEXT: .cfi_def_cfa_offset 0
43 ; RV64IZCMP-NEXT: .LBB0_2: # %if.F
44 ; RV64IZCMP-NEXT: tail f2
45 ; RV64IZCMP-NEXT: .Lfunc_end0:
47 br i1 poison, label %if.T, label %if.F