Skip to content

Commit 44c4ba3

Browse files
committed
[MachineSink] Fix for breaking phi edges with instructions with multiple defs
BreakPHIEdge would be set based on whether the instruction needs to insert a new critical edge to allow sinking into a block where the uses are PHI nodes. But for instructions with multiple defs it would be reset on the second def, allowing the instruciton to sink where it should not. Fixes PR44981 Differential Revision: https://reviews.llvm.org/D78087
1 parent ea88dd8 commit 44c4ba3

File tree

2 files changed

+69
-17
lines changed

2 files changed

+69
-17
lines changed

llvm/lib/CodeGen/MachineSink.cpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -269,30 +269,26 @@ MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
269269
// into and they are all PHI nodes. In this case, machine-sink must break
270270
// the critical edge first. e.g.
271271
//
272-
// %bb.1: derived from LLVM BB %bb4.preheader
272+
// %bb.1:
273273
// Predecessors according to CFG: %bb.0
274274
// ...
275-
// %reg16385 = DEC64_32r %reg16437, implicit-def dead %eflags
275+
// %def = DEC64_32r %x, implicit-def dead %eflags
276276
// ...
277277
// JE_4 <%bb.37>, implicit %eflags
278278
// Successors according to CFG: %bb.37 %bb.2
279279
//
280-
// %bb.2: derived from LLVM BB %bb.nph
281-
// Predecessors according to CFG: %bb.0 %bb.1
282-
// %reg16386 = PHI %reg16434, %bb.0, %reg16385, %bb.1
283-
BreakPHIEdge = true;
284-
for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
285-
MachineInstr *UseInst = MO.getParent();
286-
unsigned OpNo = &MO - &UseInst->getOperand(0);
287-
MachineBasicBlock *UseBlock = UseInst->getParent();
288-
if (!(UseBlock == MBB && UseInst->isPHI() &&
289-
UseInst->getOperand(OpNo+1).getMBB() == DefMBB)) {
290-
BreakPHIEdge = false;
291-
break;
292-
}
293-
}
294-
if (BreakPHIEdge)
280+
// %bb.2:
281+
// %p = PHI %y, %bb.0, %def, %bb.1
282+
if (llvm::all_of(MRI->use_nodbg_operands(Reg), [&](MachineOperand &MO) {
283+
MachineInstr *UseInst = MO.getParent();
284+
unsigned OpNo = UseInst->getOperandNo(&MO);
285+
MachineBasicBlock *UseBlock = UseInst->getParent();
286+
return UseBlock == MBB && UseInst->isPHI() &&
287+
UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
288+
})) {
289+
BreakPHIEdge = true;
295290
return true;
291+
}
296292

297293
for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
298294
// Determine the block of the use.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=arm-none-eabi | FileCheck %s
3+
4+
%struct.anon.1.19.23.27.35.49.55.57.59.61.89.95 = type { i32, i32 }
5+
6+
@e = external constant [2 x %struct.anon.1.19.23.27.35.49.55.57.59.61.89.95], align 4
7+
@f = external global i32, align 4
8+
9+
define arm_aapcscc void @g() {
10+
; CHECK-LABEL: g:
11+
; CHECK: @ %bb.0: @ %entry
12+
; CHECK-NEXT: .save {r11, lr}
13+
; CHECK-NEXT: push {r11, lr}
14+
; CHECK-NEXT: ldr r0, .LCPI0_0
15+
; CHECK-NEXT: mov r2, #0
16+
; CHECK-NEXT: ldr r1, .LCPI0_1
17+
; CHECK-NEXT: cmp r2, #0
18+
; CHECK-NEXT: ldr r0, [r0]
19+
; CHECK-NEXT: ldr r0, [r1, r0, lsl #3]!
20+
; CHECK-NEXT: moveq r0, #0
21+
; CHECK-NEXT: cmp r2, #0
22+
; CHECK-NEXT: popne {r11, lr}
23+
; CHECK-NEXT: movne pc, lr
24+
; CHECK-NEXT: ldr r1, [r1, #4]
25+
; CHECK-NEXT: bl k
26+
; CHECK-NEXT: .p2align 2
27+
; CHECK-NEXT: @ %bb.1:
28+
; CHECK-NEXT: .LCPI0_0:
29+
; CHECK-NEXT: .long f
30+
; CHECK-NEXT: .LCPI0_1:
31+
; CHECK-NEXT: .long e
32+
entry:
33+
%0 = load i32, i32* @f, align 4
34+
%c = getelementptr inbounds [2 x %struct.anon.1.19.23.27.35.49.55.57.59.61.89.95], [2 x %struct.anon.1.19.23.27.35.49.55.57.59.61.89.95]* @e, i32 0, i32 %0, i32 0
35+
%1 = load i32, i32* %c, align 4
36+
%d = getelementptr inbounds [2 x %struct.anon.1.19.23.27.35.49.55.57.59.61.89.95], [2 x %struct.anon.1.19.23.27.35.49.55.57.59.61.89.95]* @e, i32 0, i32 %0, i32 1
37+
%2 = load i32, i32* %d, align 4
38+
br i1 undef, label %land.lhs.true, label %if.end
39+
40+
land.lhs.true: ; preds = %entry
41+
br label %if.end
42+
43+
if.end: ; preds = %land.lhs.true, %entry
44+
%h.0 = phi i32 [ %1, %entry ], [ 0, %land.lhs.true ]
45+
br i1 undef, label %if.end7, label %if.then5
46+
47+
if.then5: ; preds = %if.end
48+
%call6 = call arm_aapcscc i32 bitcast (i32 (...)* @k to i32 (i32, i32)*)(i32 %h.0, i32 %2)
49+
unreachable
50+
51+
if.end7: ; preds = %if.end
52+
ret void
53+
}
54+
55+
declare arm_aapcscc i32 @k(...)
56+

0 commit comments

Comments
 (0)