Commit | Line | Data |
---|---|---|
851a7caf JK |
1 | From 011fb5bf8b31316472fccb1a19c91912246df9b2 Mon Sep 17 00:00:00 2001 |
2 | From: Reid Kleckner <rnk@google.com> | |
3 | Date: Sat, 28 Mar 2020 11:03:14 -0700 | |
4 | Subject: [PATCH] [CodeGen] Fix sinking local values in lpads with phis | |
5 | ||
6 | There was already a test case for landingpads to handle this case, but I | |
7 | had forgotten to consider PHI instructions preceding the EH_LABEL in the | |
8 | landingpad. | |
9 | ||
10 | PR45261 | |
11 | --- | |
12 | llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 17 +++++++++- | |
13 | llvm/test/CodeGen/X86/sink-local-value.ll | 36 ++++++++++++++++++++++ | |
14 | 2 files changed, 52 insertions(+), 1 deletion(-) | |
15 | ||
16 | diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | |
17 | index 5ac3606dc662..2638b1e8a05c 100644 | |
9e4c24ef MC |
18 | --- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp |
19 | +++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | |
851a7caf JK |
20 | @@ -225,6 +225,21 @@ static bool isRegUsedByPhiNodes(unsigned DefReg, |
21 | return false; | |
22 | } | |
23 | ||
24 | +static bool isTerminatingEHLabel(MachineBasicBlock *MBB, MachineInstr &MI) { | |
25 | + // Ignore non-EH labels. | |
26 | + if (!MI.isEHLabel()) | |
27 | + return false; | |
28 | + | |
29 | + // Any EH label outside a landing pad must be for an invoke. Consider it a | |
30 | + // terminator. | |
31 | + if (!MBB->isEHPad()) | |
32 | + return true; | |
33 | + | |
34 | + // If this is a landingpad, the first non-phi instruction will be an EH_LABEL. | |
35 | + // Don't consider that label to be a terminator. | |
36 | + return MI.getIterator() != MBB->getFirstNonPHI(); | |
37 | +} | |
38 | + | |
39 | /// Build a map of instruction orders. Return the first terminator and its | |
40 | /// order. Consider EH_LABEL instructions to be terminators as well, since local | |
41 | /// values for phis after invokes must be materialized before the call. | |
42 | @@ -233,7 +248,7 @@ void FastISel::InstOrderMap::initialize( | |
43 | unsigned Order = 0; | |
44 | for (MachineInstr &I : *MBB) { | |
45 | if (!FirstTerminator && | |
46 | - (I.isTerminator() || (I.isEHLabel() && &I != &MBB->front()))) { | |
47 | + (I.isTerminator() || isTerminatingEHLabel(MBB, I))) { | |
48 | FirstTerminator = &I; | |
49 | FirstTerminatorOrder = Order; | |
50 | } | |
51 | diff --git a/llvm/test/CodeGen/X86/sink-local-value.ll b/llvm/test/CodeGen/X86/sink-local-value.ll | |
52 | index b0e511ac1189..f7d861ac9b6c 100644 | |
9e4c24ef MC |
53 | --- llvm/test/CodeGen/X86/sink-local-value.ll |
54 | +++ llvm/test/CodeGen/X86/sink-local-value.ll | |
851a7caf JK |
55 | @@ -145,6 +145,42 @@ try.cont: ; preds = %entry, %lpad |
56 | ; CHECK: retl | |
57 | ||
58 | ||
59 | +define i32 @lpad_phi() personality i32 (...)* @__gxx_personality_v0 { | |
60 | +entry: | |
61 | + store i32 42, i32* @sink_across | |
62 | + invoke void @may_throw() | |
63 | + to label %try.cont unwind label %lpad | |
64 | + | |
65 | +lpad: ; preds = %entry | |
66 | + %p = phi i32 [ 11, %entry ] ; Trivial, but -O0 keeps it | |
67 | + %0 = landingpad { i8*, i32 } | |
68 | + catch i8* null | |
69 | + store i32 %p, i32* @sink_across | |
70 | + br label %try.cont | |
71 | + | |
72 | +try.cont: ; preds = %entry, %lpad | |
73 | + %r.0 = phi i32 [ 13, %entry ], [ 55, %lpad ] | |
74 | + ret i32 %r.0 | |
75 | +} | |
76 | + | |
77 | +; The constant materialization should be *after* the stores to sink_across, but | |
78 | +; before any EH_LABEL. | |
79 | + | |
80 | +; CHECK-LABEL: lpad_phi: | |
81 | +; CHECK: movl $42, sink_across | |
82 | +; CHECK: movl $13, %{{[a-z]*}} | |
83 | +; CHECK: .Ltmp{{.*}}: | |
84 | +; CHECK: calll may_throw | |
85 | +; CHECK: .Ltmp{{.*}}: | |
86 | +; CHECK: jmp .LBB{{.*}} | |
87 | +; CHECK: .LBB{{.*}}: # %lpad | |
88 | +; CHECK-NEXT: .Ltmp{{.*}}: | |
89 | +; CHECK: movl {{.*}}, sink_across | |
90 | +; CHECK: movl $55, %{{[a-z]*}} | |
91 | +; CHECK: .LBB{{.*}}: # %try.cont | |
92 | +; CHECK: retl | |
93 | + | |
94 | + | |
95 | ; Function Attrs: nounwind readnone speculatable | |
96 | declare void @llvm.dbg.value(metadata, metadata, metadata) #0 | |
97 |