Skip to content

Commit 646ca7d

Browse files
committed
MipsDelaySlotFiller: Update registers def-uses for BUNDLE instructions
Summary: In commit b91f239 I updated the MipsDelaySlotFiller to skip BUNDLE instructions. However, in addition to not considering BUNDLE instructions for the delay slot, we also need to ensure that the register def-use information is updated. Not updating this information caused run-time crashes (when using the out-of-tree CHERI backend) since later definitions could be overwritten with earlier register values. Reviewers: atanasyan Reviewed By: atanasyan Differential Revision: https://reviews.llvm.org/D72254
1 parent 1444e6e commit 646ca7d

File tree

2 files changed

+114
-2
lines changed

2 files changed

+114
-2
lines changed

llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,14 @@ bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {
416416
for (unsigned I = Begin; I != End; ++I) {
417417
const MachineOperand &MO = MI.getOperand(I);
418418

419-
if (MO.isReg() && MO.getReg())
420-
HasHazard |= checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef());
419+
if (MO.isReg() && MO.getReg()) {
420+
if (checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef())) {
421+
LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found register hazard for operand "
422+
<< I << ": ";
423+
MO.dump());
424+
HasHazard = true;
425+
}
426+
}
421427
}
422428

423429
Defs |= NewDefs;
@@ -698,6 +704,8 @@ bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,
698704
if (CurrI->isBundle()) {
699705
LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring BUNDLE instruction: ";
700706
CurrI->dump());
707+
// However, we still need to update the register def-use information.
708+
RegDU.update(*CurrI, 0, CurrI->getNumOperands());
701709
continue;
702710
}
703711

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
## Check that the delay-slot filler looks at the registers defined by BUNDLE instructions
3+
# RUN: llc %s -run-pass=mips-delay-slot-filler -verify-machineinstrs -o - | FileCheck %s
4+
--- |
5+
; ModuleID = '/Users/alex/cheri/llvm-project/llvm/test/CodeGen/Mips/delay-test.ll'
6+
source_filename = "/Users/alex/cheri/llvm-project/llvm/test/CodeGen/Mips/delay-test.ll"
7+
target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
8+
target triple = "mips64-unknown-freebsd"
9+
10+
; Function Attrs: nounwind
11+
define i64 @test(i1 %cond) local_unnamed_addr #0 {
12+
entry:
13+
br i1 %cond, label %err, label %return
14+
15+
err: ; preds = %entry
16+
unreachable
17+
18+
return: ; preds = %entry
19+
ret i64 1
20+
}
21+
22+
attributes #0 = { nounwind }
23+
24+
...
25+
---
26+
name: test
27+
alignment: 8
28+
exposesReturnsTwice: false
29+
legalized: false
30+
regBankSelected: false
31+
selected: false
32+
failedISel: false
33+
tracksRegLiveness: true
34+
hasWinCFI: false
35+
registers: []
36+
liveins:
37+
- { reg: '$a0_64', virtual-reg: '' }
38+
frameInfo:
39+
isFrameAddressTaken: false
40+
isReturnAddressTaken: false
41+
hasStackMap: false
42+
hasPatchPoint: false
43+
stackSize: 0
44+
offsetAdjustment: 0
45+
maxAlignment: 1
46+
adjustsStack: false
47+
hasCalls: false
48+
stackProtector: ''
49+
maxCallFrameSize: 0
50+
cvBytesOfCalleeSavedRegisters: 0
51+
hasOpaqueSPAdjustment: false
52+
hasVAStart: false
53+
hasMustTailInVarArgFunc: false
54+
localFrameSize: 0
55+
savePoint: ''
56+
restorePoint: ''
57+
fixedStack: []
58+
stack: []
59+
callSites: []
60+
constants: []
61+
machineFunctionInfo: {}
62+
body: |
63+
; CHECK-LABEL: name: test
64+
; CHECK: bb.0.entry:
65+
; CHECK: successors: %bb.2(0x00000001), %bb.1(0x7fffffff)
66+
; CHECK: renamable $at = SLL renamable $a0, 0, implicit killed $a0_64
67+
; CHECK: renamable $at = ANDi killed renamable $at, 1
68+
; CHECK: $v0_64 = DADDiu $zero_64, 1
69+
; CHECK: $v0_64 = DADDiu $v0_64, 1
70+
; CHECK: BUNDLE implicit-def $v0_64 {
71+
; CHECK: $v0_64 = DADDiu $zero_64, 1
72+
; CHECK: $v0_64 = DADDiu $v0_64, 1
73+
; CHECK: }
74+
; CHECK: BNE killed renamable $at, $zero, %bb.2, implicit-def $at {
75+
; CHECK: NOP
76+
; CHECK: }
77+
; CHECK: bb.1.return:
78+
; CHECK: PseudoReturn64 undef $ra_64, implicit killed $v0_64 {
79+
; CHECK: NOP
80+
; CHECK: }
81+
; CHECK: bb.2.err:
82+
bb.0.entry:
83+
successors: %bb.1(0x00000001), %bb.2(0x7fffffff)
84+
liveins: $a0_64
85+
86+
renamable $at = SLL renamable $a0, 0, implicit killed $a0_64
87+
renamable $at = ANDi killed renamable $at, 1
88+
; Check that none of these instructions are hoisted after the BUNDLE to avoid
89+
; incorrect values from being
90+
$v0_64 = DADDiu $zero_64, 1
91+
$v0_64 = DADDiu $v0_64, 1
92+
BUNDLE implicit-def $v0_64 {
93+
$v0_64 = DADDiu $zero_64, 1
94+
$v0_64 = DADDiu $v0_64, 1
95+
}
96+
BNE killed renamable $at, $zero, %bb.1, implicit-def $at
97+
98+
bb.2.return:
99+
liveins: $v0_64
100+
PseudoReturn64 undef $ra_64, implicit killed $v0_64
101+
102+
bb.1.err:
103+
104+
...

0 commit comments

Comments
 (0)