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 ilp64 < %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: .LBB0_2: # %if.F
26 ; RV32IZCMP-NEXT: tail f2
27 ; RV32IZCMP-NEXT: .Lfunc_end0:
29 ; RV64IZCMP-LABEL: f0:
30 ; RV64IZCMP: .cfi_startproc
31 ; RV64IZCMP-NEXT: # %bb.0: # %entry
32 ; RV64IZCMP-NEXT: bnez zero, .LBB0_2
33 ; RV64IZCMP-NEXT: # %bb.1: # %if.T
34 ; RV64IZCMP-NEXT: cm.push {ra}, -16
35 ; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
36 ; RV64IZCMP-NEXT: .cfi_offset ra, -8
37 ; RV64IZCMP-NEXT: call f1
38 ; RV64IZCMP-NEXT: cm.pop {ra}, 16
39 ; RV64IZCMP-NEXT: .LBB0_2: # %if.F
40 ; RV64IZCMP-NEXT: tail f2
41 ; RV64IZCMP-NEXT: .Lfunc_end0:
43 br i1 poison, label %if.T, label %if.F