Skip to content

Commit d6e0798

Browse files
authored
[Mips] Add the missing judgment when processing function handleMFLOSlot (#121463)
In function handleMFLOSlot, we may get a variable LastInstInFunction with a value of true from function getNextMachineInstr and IInSlot may be null which would trigger an assert. So we need to skip this case. Fix #118223.
1 parent acc13db commit d6e0798

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

llvm/lib/Target/Mips/MipsBranchExpansion.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ bool MipsBranchExpansion::handleMFLOSlot(Pred Predicate, Safe SafeInSlot) {
767767
std::pair<Iter, bool> Res = getNextMachineInstr(std::next(I), &*FI);
768768
LastInstInFunction |= Res.second;
769769
IInSlot = Res.first;
770+
if (LastInstInFunction)
771+
continue;
770772
if (!SafeInSlot(*IInSlot, *I)) {
771773
Changed = true;
772774
TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc())
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: llc --mtriple=mips-unknown-freebsd -mcpu=mips2 -filetype=asm < %s -mcpu=mips2 | FileCheck %s -check-prefixes=MIPS2
2+
;
3+
; Created from the following test case (PR121463) with
4+
; clang -cc1 -triple mips-unknown-freebsd -target-cpu mips2 -O2 -emit-llvm test.c -o test.ll
5+
; int l2arc_feed_secs, l2arc_feed_min_ms, l2arc_write_interval_wrote, l2arc_write_interval_next;
6+
; void l2arc_write_interval() {
7+
; int interval = 0;
8+
; if (l2arc_write_interval_wrote)
9+
; interval = l2arc_feed_min_ms / l2arc_feed_secs;
10+
; l2arc_write_interval_next = interval;
11+
; }
12+
13+
@l2arc_write_interval_wrote = local_unnamed_addr global i32 0, align 4
14+
@l2arc_feed_min_ms = local_unnamed_addr global i32 0, align 4
15+
@l2arc_feed_secs = local_unnamed_addr global i32 0, align 4
16+
@l2arc_write_interval_next = local_unnamed_addr global i32 0, align 4
17+
18+
define dso_local void @l2arc_write_interval() local_unnamed_addr #0 {
19+
; MIPS2-LABEL: l2arc_write_interval:
20+
; MIPS2: # %bb.0: # %entry
21+
; MIPS2-NEXT: lui $1, %hi(l2arc_write_interval_wrote)
22+
; MIPS2-NEXT: lw $1, %lo(l2arc_write_interval_wrote)($1)
23+
; MIPS2-NEXT: beqz $1, $BB0_2
24+
; MIPS2-NEXT: nop
25+
; MIPS2-NEXT: # %bb.1: # %if.then
26+
; MIPS2-NEXT: lui $1, %hi(l2arc_feed_secs)
27+
; MIPS2-NEXT: lw $1, %lo(l2arc_feed_secs)($1)
28+
; MIPS2-NEXT: lui $2, %hi(l2arc_feed_min_ms)
29+
; MIPS2-NEXT: lw $2, %lo(l2arc_feed_min_ms)($2)
30+
; MIPS2-NEXT: div $zero, $2, $1
31+
; MIPS2-NEXT: teq $1, $zero, 7
32+
; MIPS2-NEXT: mflo $2
33+
; MIPS2-NEXT: j $BB0_3
34+
; MIPS2-NEXT: nop
35+
entry:
36+
%0 = load i32, ptr @l2arc_write_interval_wrote, align 4
37+
%tobool.not = icmp eq i32 %0, 0
38+
br i1 %tobool.not, label %if.end, label %if.then
39+
40+
if.then: ; preds = %entry
41+
%1 = load i32, ptr @l2arc_feed_min_ms, align 4
42+
%2 = load i32, ptr @l2arc_feed_secs, align 4
43+
%div = sdiv i32 %1, %2
44+
br label %if.end
45+
46+
if.end: ; preds = %if.then, %entry
47+
%interval.0 = phi i32 [ %div, %if.then ], [ 0, %entry ]
48+
store i32 %interval.0, ptr @l2arc_write_interval_next, align 4
49+
ret void
50+
}

0 commit comments

Comments
 (0)