aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch')
-rw-r--r--gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch97
1 files changed, 97 insertions, 0 deletions
diff --git a/gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch b/gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch
new file mode 100644
index 0000000000..6cfe07e50a
--- /dev/null
+++ b/gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch
@@ -0,0 +1,97 @@
+From 011fb5bf8b31316472fccb1a19c91912246df9b2 Mon Sep 17 00:00:00 2001
+From: Reid Kleckner <rnk@google.com>
+Date: Sat, 28 Mar 2020 11:03:14 -0700
+Subject: [PATCH] [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
+---
+ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 17 +++++++++-
+ llvm/test/CodeGen/X86/sink-local-value.ll | 36 ++++++++++++++++++++++
+ 2 files changed, 52 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+index 5ac3606dc662..2638b1e8a05c 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
+