From 851a7caf1a1a145a815aa11bf29aeaceca94e8c1 Mon Sep 17 00:00:00 2001 From: Jakub Kądziołka Date: Sun, 7 Jun 2020 23:25:40 +0200 Subject: gnu: llvm-9: Backport patches to fix miscompilations. * gnu/packages/llvm.scm (llvm-9)[source]: Add new patches. * gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch, gnu/packages/patches/llvm-9-fix-scev-miscompilation.patch: New files. * gnu/local.mk (dist_patch_DATA): Register new patches. --- gnu/local.mk | 2 + gnu/packages/llvm.scm | 7 +- .../patches/llvm-9-fix-lpad-miscompilation.patch | 97 ++++++++++++++++++ .../patches/llvm-9-fix-scev-miscompilation.patch | 113 +++++++++++++++++++++ 4 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/llvm-9-fix-lpad-miscompilation.patch create mode 100644 gnu/packages/patches/llvm-9-fix-scev-miscompilation.patch diff --git a/gnu/local.mk b/gnu/local.mk index 040882192f..47180eea9d 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1242,6 +1242,8 @@ dist_patch_DATA = \ %D%/packages/patches/lirc-localstatedir.patch \ %D%/packages/patches/lirc-reproducible-build.patch \ %D%/packages/patches/llvm-3.5-fix-clang-build-with-gcc5.patch \ + %D%/packages/patches/llvm-9-fix-lpad-miscompilation.patch \ + %D%/packages/patches/llvm-9-fix-scev-miscompilation.patch \ %D%/packages/patches/lm-sensors-hwmon-attrs.patch \ %D%/packages/patches/lrcalc-includes.patch \ %D%/packages/patches/lrzip-CVE-2017-8842.patch \ diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm index 11e4cfbe4c..7723ff5bc1 100644 --- a/gnu/packages/llvm.scm +++ b/gnu/packages/llvm.scm @@ -15,6 +15,7 @@ ;;; Copyright © 2019 Mathieu Othacehe ;;; Copyright © 2019 Brett Gilio ;;; Copyright © 2020 Giacomo Leidi +;;; Copyright © 2020 Jakub Kądziołka ;;; ;;; This file is part of GNU Guix. ;;; @@ -510,7 +511,11 @@ output), and Binutils.") (uri (llvm-download-uri "llvm" version)) (sha256 (base32 - "16hwp3qa54c3a3v7h8nlw0fh5criqh0hlr1skybyk0cz70gyx880")))))) + "16hwp3qa54c3a3v7h8nlw0fh5criqh0hlr1skybyk0cz70gyx880")) + (patch-flags '("-p2")) + (patches (search-patches + "llvm-9-fix-scev-miscompilation.patch" + "llvm-9-fix-lpad-miscompilation.patch")))))) (define-public clang-runtime-9 (clang-runtime-from-llvm 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 +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 + diff --git a/gnu/packages/patches/llvm-9-fix-scev-miscompilation.patch b/gnu/packages/patches/llvm-9-fix-scev-miscompilation.patch new file mode 100644 index 0000000000..3f16de5a2b --- /dev/null +++ b/gnu/packages/patches/llvm-9-fix-scev-miscompilation.patch @@ -0,0 +1,113 @@ +Guix note: this got detected with the test suite of rustc 1.41.1, but +the issue potentially affects all consumers of LLVM. + +From 58e8c793d0e43150a6452e971a32d7407a8a7401 Mon Sep 17 00:00:00 2001 +From: Tim Northover +Date: Mon, 30 Sep 2019 07:46:52 +0000 +Subject: [PATCH] Revert "[SCEV] add no wrap flag for SCEVAddExpr." + +This reverts r366419 because the analysis performed is within the context of +the loop and it's only valid to add wrapping flags to "global" expressions if +they're always correct. + +llvm-svn: 373184 +--- + llvm/lib/Analysis/ScalarEvolution.cpp | 2 +- + llvm/test/Analysis/ScalarEvolution/limit-depth.ll | 2 +- + llvm/test/Analysis/ScalarEvolution/nsw.ll | 2 +- + llvm/test/Analysis/ScalarEvolution/trip-count12.ll | 2 +- + llvm/test/Analysis/ScalarEvolution/trip-count9.ll | 8 ++++---- + 5 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp +index 354ae05bb841..c29fc5dbccfb 100644 +--- a/llvm/lib/Analysis/ScalarEvolution.cpp ++++ b/llvm/lib/Analysis/ScalarEvolution.cpp +@@ -4992,7 +4992,7 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN, + // overflow. + if (auto *BEInst = dyn_cast(BEValueV)) + if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L)) +- (void)getAddRecExpr(getAddExpr(StartVal, Accum, Flags), Accum, L, Flags); ++ (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags); + + return PHISCEV; + } +diff --git a/llvm/test/Analysis/ScalarEvolution/limit-depth.ll b/llvm/test/Analysis/ScalarEvolution/limit-depth.ll +index db68a4f84c91..6fdf8c5df974 100644 +--- a/llvm/test/Analysis/ScalarEvolution/limit-depth.ll ++++ b/llvm/test/Analysis/ScalarEvolution/limit-depth.ll +@@ -46,7 +46,7 @@ define void @test_mul(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) { + define void @test_sext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) { + ; CHECK-LABEL: @test_sext + ; CHECK: %se2 = sext i64 %iv2.inc to i128 +-; CHECK-NEXT: --> {(1 + (sext i64 {(sext i32 (1 + %a) to i64),+,1}<%loop> to i128)),+,1}<%loop2> ++; CHECK-NEXT: --> {(1 + (sext i64 {(sext i32 (1 + %a) to i64),+,1}<%loop> to i128)),+,1}<%loop2> + entry: + br label %loop + +diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll +index 69427368625d..ca24f9d4a04b 100644 +--- a/llvm/test/Analysis/ScalarEvolution/nsw.ll ++++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll +@@ -163,7 +163,7 @@ bb5: ; preds = %bb2 + declare void @f(i32) + + ; CHECK-LABEL: nswnowrap +-; CHECK: --> {(1 + %v),+,1}<%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (2 + %v) ++; CHECK: --> {(1 + %v),+,1}<%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (1 + ((1 + %v) smax %v)) + define void @nswnowrap(i32 %v, i32* %buf) { + entry: + %add = add nsw i32 %v, 1 +diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count12.ll b/llvm/test/Analysis/ScalarEvolution/trip-count12.ll +index 5e7d72d5e4f3..d0086ee2e6ac 100644 +--- a/llvm/test/Analysis/ScalarEvolution/trip-count12.ll ++++ b/llvm/test/Analysis/ScalarEvolution/trip-count12.ll +@@ -1,7 +1,7 @@ + ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s + + ; CHECK: Determining loop execution counts for: @test +-; CHECK: Loop %for.body: backedge-taken count is ((-2 + %len) /u 2) ++; CHECK: Loop %for.body: backedge-taken count is ((-2 + %len) /u 2) + ; CHECK: Loop %for.body: max backedge-taken count is 1073741823 + + define zeroext i16 @test(i16* nocapture %p, i32 %len) nounwind readonly { +diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count9.ll b/llvm/test/Analysis/ScalarEvolution/trip-count9.ll +index c0a1d12fa00e..9a080b34743f 100644 +--- a/llvm/test/Analysis/ScalarEvolution/trip-count9.ll ++++ b/llvm/test/Analysis/ScalarEvolution/trip-count9.ll +@@ -179,7 +179,7 @@ exit: + } + + ; CHECK: Determining loop execution counts for: @nsw_startx +-; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n)) ++; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax %n)) + ; CHECK: Loop %loop: max backedge-taken count is -1 + define void @nsw_startx(i4 %n, i4 %x) { + entry: +@@ -195,7 +195,7 @@ exit: + } + + ; CHECK: Determining loop execution counts for: @nsw_startx_step2 +-; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax %n)) /u 2) ++; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax %n)) /u 2) + ; CHECK: Loop %loop: max backedge-taken count is 7 + define void @nsw_startx_step2(i4 %n, i4 %x) { + entry: +@@ -381,7 +381,7 @@ exit: + } + + ; CHECK: Determining loop execution counts for: @even_nsw_startx +-; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n))) ++; CHECK: Loop %loop: backedge-taken count is (-1 + (-1 * %x) + ((1 + %x) smax (2 * %n))) + ; CHECK: Loop %loop: max backedge-taken count is -2 + define void @even_nsw_startx(i4 %n, i4 %x) { + entry: +@@ -398,7 +398,7 @@ exit: + } + + ; CHECK: Determining loop execution counts for: @even_nsw_startx_step2 +-; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax (2 * %n))) /u 2) ++; CHECK: Loop %loop: backedge-taken count is ((-1 + (-1 * %x) + ((2 + %x) smax (2 * %n))) /u 2) + ; CHECK: Loop %loop: max backedge-taken count is 7 + define void @even_nsw_startx_step2(i4 %n, i4 %x) { + entry: -- cgit 1.4.1