Skip to content

Commit 2f0fb93

Browse files
anmolparalkar-nxptru
authored andcommitted
[RISCV] Add bounds check before use on returned iterator.
Check iterator validity before use; fixes a crash seen in the RISC-V Zcmp Push/Pop optimization pass when compiling an internal benchmark. Reviewed By: asb, wangpc Differential Revision: https://reviews.llvm.org/D157674 (cherry picked from commit 53e89f5)
1 parent 3c0e8be commit 2f0fb93

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

llvm/lib/Target/RISCV/RISCVPushPopOptimizer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ bool RISCVPushPopOpt::runOnMachineFunction(MachineFunction &Fn) {
132132
for (auto &MBB : Fn) {
133133
MachineBasicBlock::iterator MBBI = containsPop(MBB);
134134
MachineBasicBlock::iterator NextI = next_nodbg(MBBI, MBB.end());
135-
if (MBBI != MBB.end() && NextI->getOpcode() == RISCV::PseudoRET)
135+
if (MBBI != MBB.end() && NextI != MBB.end() &&
136+
NextI->getOpcode() == RISCV::PseudoRET)
136137
Modified |= usePopRet(MBBI, NextI, adjustRetVal(MBBI));
137138
}
138139
return Modified;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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
7+
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
10+
; iterator.
11+
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:
28+
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:
42+
entry:
43+
br i1 poison, label %if.T, label %if.F
44+
45+
if.T:
46+
tail call void @f1()
47+
br label %if.F
48+
49+
if.F:
50+
tail call void @f2()
51+
ret void
52+
}

0 commit comments

Comments
 (0)