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
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
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(-)
16 diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
17 index 5ac3606dc662..2638b1e8a05c 100644
18 --- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
19 +++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
20 @@ -225,6 +225,21 @@ static bool isRegUsedByPhiNodes(unsigned DefReg,
24 +static bool isTerminatingEHLabel(MachineBasicBlock *MBB, MachineInstr &MI) {
25 + // Ignore non-EH labels.
26 + if (!MI.isEHLabel())
29 + // Any EH label outside a landing pad must be for an invoke. Consider it a
31 + if (!MBB->isEHPad())
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();
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(
44 for (MachineInstr &I : *MBB) {
45 if (!FirstTerminator &&
46 - (I.isTerminator() || (I.isEHLabel() && &I != &MBB->front()))) {
47 + (I.isTerminator() || isTerminatingEHLabel(MBB, I))) {
49 FirstTerminatorOrder = Order;
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
53 --- llvm/test/CodeGen/X86/sink-local-value.ll
54 +++ llvm/test/CodeGen/X86/sink-local-value.ll
55 @@ -145,6 +145,42 @@ try.cont: ; preds = %entry, %lpad
59 +define i32 @lpad_phi() personality i32 (...)* @__gxx_personality_v0 {
61 + store i32 42, i32* @sink_across
62 + invoke void @may_throw()
63 + to label %try.cont unwind label %lpad
65 +lpad: ; preds = %entry
66 + %p = phi i32 [ 11, %entry ] ; Trivial, but -O0 keeps it
67 + %0 = landingpad { i8*, i32 }
69 + store i32 %p, i32* @sink_across
72 +try.cont: ; preds = %entry, %lpad
73 + %r.0 = phi i32 [ 13, %entry ], [ 55, %lpad ]
77 +; The constant materialization should be *after* the stores to sink_across, but
78 +; before any EH_LABEL.
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
95 ; Function Attrs: nounwind readnone speculatable
96 declare void @llvm.dbg.value(metadata, metadata, metadata) #0