; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -mattr=+zcmp -verify-machineinstrs \ ; RUN: -mtriple=riscv32 -target-abi=ilp32 < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32IZCMP ; RUN: llc -mattr=+zcmp -verify-machineinstrs \ ; RUN: -mtriple=riscv64 -target-abi=lp64 < %s \ ; RUN: | FileCheck %s -check-prefixes=RV64IZCMP ; This source code exposed a crash in the RISC-V Zcmp Push/Pop optimization ; pass. The root cause was: Not doing a bounds check before using a returned ; iterator. declare dso_local void @f1() local_unnamed_addr declare dso_local void @f2() local_unnamed_addr define dso_local void @f0(i1 %c) local_unnamed_addr { ; RV32IZCMP-LABEL: f0: ; RV32IZCMP: # %bb.0: # %entry ; RV32IZCMP-NEXT: andi a0, a0, 1 ; RV32IZCMP-NEXT: beqz a0, .LBB0_2 ; RV32IZCMP-NEXT: # %bb.1: # %if.T ; RV32IZCMP-NEXT: cm.push {ra}, -16 ; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16 ; RV32IZCMP-NEXT: .cfi_offset ra, -4 ; RV32IZCMP-NEXT: call f1 ; RV32IZCMP-NEXT: cm.pop {ra}, 16 ; RV32IZCMP-NEXT: .cfi_restore ra ; RV32IZCMP-NEXT: .cfi_def_cfa_offset 0 ; RV32IZCMP-NEXT: .LBB0_2: # %if.F ; RV32IZCMP-NEXT: tail f2 ; ; RV64IZCMP-LABEL: f0: ; RV64IZCMP: # %bb.0: # %entry ; RV64IZCMP-NEXT: andi a0, a0, 1 ; RV64IZCMP-NEXT: beqz a0, .LBB0_2 ; RV64IZCMP-NEXT: # %bb.1: # %if.T ; RV64IZCMP-NEXT: cm.push {ra}, -16 ; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16 ; RV64IZCMP-NEXT: .cfi_offset ra, -8 ; RV64IZCMP-NEXT: call f1 ; RV64IZCMP-NEXT: cm.pop {ra}, 16 ; RV64IZCMP-NEXT: .cfi_restore ra ; RV64IZCMP-NEXT: .cfi_def_cfa_offset 0 ; RV64IZCMP-NEXT: .LBB0_2: # %if.F ; RV64IZCMP-NEXT: tail f2 entry: br i1 %c, label %if.T, label %if.F if.T: tail call void @f1() br label %if.F if.F: tail call void @f2() ret void }