Author: Reid Kleckner Date: 2020-04-13T13:37:15-07:00 New Revision: 47e68d864420afd42d34fd25e97522e5c149de46
URL: https://github.com/llvm/llvm-project/commit/47e68d864420afd42d34fd25e97522e5c149de46 DIFF: https://github.com/llvm/llvm-project/commit/47e68d864420afd42d34fd25e97522e5c149de46.diff LOG: [CodeGen] Fix sinking local values in lpads with phis There was already a test case for landingpads to handle this case, but I had forgotten to consider PHI instructions preceding the EH_LABEL in the landingpad. PR45261 (cherry picked from commit e5bf5037d869c74bc2faf81fa1f58dfd827e8356) Added: Modified: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp llvm/test/CodeGen/X86/sink-local-value.ll Removed: ################################################################################ diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 8294591b7326..6ecde9b43c07 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -225,6 +225,21 @@ static bool isRegUsedByPhiNodes(unsigned DefReg, return false; } +static bool isTerminatingEHLabel(MachineBasicBlock *MBB, MachineInstr &MI) { + // Ignore non-EH labels. + if (!MI.isEHLabel()) + return false; + + // Any EH label outside a landing pad must be for an invoke. Consider it a + // terminator. + if (!MBB->isEHPad()) + return true; + + // If this is a landingpad, the first non-phi instruction will be an EH_LABEL. + // Don't consider that label to be a terminator. + return MI.getIterator() != MBB->getFirstNonPHI(); +} + /// Build a map of instruction orders. Return the first terminator and its /// order. Consider EH_LABEL instructions to be terminators as well, since local /// values for phis after invokes must be materialized before the call. @@ -233,7 +248,7 @@ void FastISel::InstOrderMap::initialize( unsigned Order = 0; for (MachineInstr &I : *MBB) { if (!FirstTerminator && - (I.isTerminator() || (I.isEHLabel() && &I != &MBB->front()))) { + (I.isTerminator() || isTerminatingEHLabel(MBB, I))) { FirstTerminator = &I; FirstTerminatorOrder = Order; } diff --git a/llvm/test/CodeGen/X86/sink-local-value.ll b/llvm/test/CodeGen/X86/sink-local-value.ll index b0e511ac1189..f7d861ac9b6c 100644 --- a/llvm/test/CodeGen/X86/sink-local-value.ll +++ b/llvm/test/CodeGen/X86/sink-local-value.ll @@ -145,6 +145,42 @@ try.cont: ; preds = %entry, %lpad ; CHECK: retl +define i32 @lpad_phi() personality i32 (...)* @__gxx_personality_v0 { +entry: + store i32 42, i32* @sink_across + invoke void @may_throw() + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %p = phi i32 [ 11, %entry ] ; Trivial, but -O0 keeps it + %0 = landingpad { i8*, i32 } + catch i8* null + store i32 %p, i32* @sink_across + br label %try.cont + +try.cont: ; preds = %entry, %lpad + %r.0 = phi i32 [ 13, %entry ], [ 55, %lpad ] + ret i32 %r.0 +} + +; The constant materialization should be *after* the stores to sink_across, but +; before any EH_LABEL. + +; CHECK-LABEL: lpad_phi: +; CHECK: movl $42, sink_across +; CHECK: movl $13, %{{[a-z]*}} +; CHECK: .Ltmp{{.*}}: +; CHECK: calll may_throw +; CHECK: .Ltmp{{.*}}: +; CHECK: jmp .LBB{{.*}} +; CHECK: .LBB{{.*}}: # %lpad +; CHECK-NEXT: .Ltmp{{.*}}: +; CHECK: movl {{.*}}, sink_across +; CHECK: movl $55, %{{[a-z]*}} +; CHECK: .LBB{{.*}}: # %try.cont +; CHECK: retl + + ; Function Attrs: nounwind readnone speculatable declare void @llvm.dbg.value(metadata, metadata, metadata) #0 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits