View | Details | Raw Unified | Return to bug 247388 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile (-7 / +3 lines)
Lines 2-11 Link Here
2
# $FreeBSD$
2
# $FreeBSD$
3
3
4
PORTNAME=	rust
4
PORTNAME=	rust
5
PORTVERSION?=	1.44.0
5
PORTVERSION?=	1.44.1
6
PORTREVISION?=	0
6
PORTREVISION?=	0
7
CATEGORIES=	lang
7
CATEGORIES=	lang
8
MASTER_SITES=	https://static.rust-lang.org/dist/:src \
8
MASTER_SITES=	https://dev-static.rust-lang.org/dist/:src \
9
		LOCAL/tobik/rust:bootstrap \
9
		LOCAL/tobik/rust:bootstrap \
10
		https://static.rust-lang.org/dist/:bootstrap
10
		https://static.rust-lang.org/dist/:bootstrap
11
DISTNAME?=	${PORTNAME}c-${PORTVERSION}-src
11
DISTNAME?=	${PORTNAME}c-${PORTVERSION}-src
Lines 87-93 Link Here
87
EXTRA_PATCHES+=	${PATCHDIR}/${ARCH}${BOOTSTRAPS_SUFFIX}
87
EXTRA_PATCHES+=	${PATCHDIR}/${ARCH}${BOOTSTRAPS_SUFFIX}
88
.endif
88
.endif
89
89
90
.if ${ARCH} == powerpc64
90
.if defined(PPC_ABI) && ${PPC_ABI} == ELFv1
91
# The bootstrap is hardcoded to use gcc9
91
# The bootstrap is hardcoded to use gcc9
92
# but we can build with a newer or older compiler as provided by USE_GCC=yes
92
# but we can build with a newer or older compiler as provided by USE_GCC=yes
93
BUILD_DEPENDS+=	gcc9:lang/gcc9
93
BUILD_DEPENDS+=	gcc9:lang/gcc9
Lines 150-159 Link Here
150
	@${ECHO_CMD} 'default-linker="${CC}"' >> ${WRKSRC}/config.toml
150
	@${ECHO_CMD} 'default-linker="${CC}"' >> ${WRKSRC}/config.toml
151
	@${ECHO_CMD} 'verbose-tests=true' >> ${WRKSRC}/config.toml
151
	@${ECHO_CMD} 'verbose-tests=true' >> ${WRKSRC}/config.toml
152
	@${ECHO_CMD} 'lld=${_RUST_BUILD_WASM}' >> ${WRKSRC}/config.toml
152
	@${ECHO_CMD} 'lld=${_RUST_BUILD_WASM}' >> ${WRKSRC}/config.toml
153
.if ${ARCH} == powerpc64
154
# XXX: crashes without this?
155
	@${ECHO_CMD} 'debuginfo-level-std=1' >> ${WRKSRC}/config.toml
156
.endif
157
	@${ECHO_CMD} '[llvm]' >> ${WRKSRC}/config.toml
153
	@${ECHO_CMD} '[llvm]' >> ${WRKSRC}/config.toml
158
.if defined(WITH_CCACHE_BUILD) && !defined(NO_CCACHE)
154
.if defined(WITH_CCACHE_BUILD) && !defined(NO_CCACHE)
159
	@${ECHO_CMD} 'ccache="${CCACHE_BIN}"' >> ${WRKSRC}/config.toml
155
	@${ECHO_CMD} 'ccache="${CCACHE_BIN}"' >> ${WRKSRC}/config.toml
(-)distinfo (-3 / +3 lines)
Lines 1-6 Link Here
1
TIMESTAMP = 1591048305
1
TIMESTAMP = 1592319443
2
SHA256 (rust/rustc-1.44.0-src.tar.xz) = b32fa7d6bd6ff9286aab2aa7ca696d1da921614cefc10f617aef68d9bce9118a
2
SHA256 (rust/rustc-1.44.1-src.tar.xz) = 2142c25a546d755ce751403a4ebfdeffdceca5030084bee828bf955b2986d053
3
SIZE (rust/rustc-1.44.0-src.tar.xz) = 94754392
3
SIZE (rust/rustc-1.44.1-src.tar.xz) = 94754860
4
SHA256 (rust/2020-05-07/rustc-1.43.1-aarch64-unknown-freebsd.tar.xz) = bf65d73547f9a1445ea8177fc452dddab8bbcfff8ad17d8292903ba4fc65d1a6
4
SHA256 (rust/2020-05-07/rustc-1.43.1-aarch64-unknown-freebsd.tar.xz) = bf65d73547f9a1445ea8177fc452dddab8bbcfff8ad17d8292903ba4fc65d1a6
5
SIZE (rust/2020-05-07/rustc-1.43.1-aarch64-unknown-freebsd.tar.xz) = 27175484
5
SIZE (rust/2020-05-07/rustc-1.43.1-aarch64-unknown-freebsd.tar.xz) = 27175484
6
SHA256 (rust/2020-05-07/rust-std-1.43.1-aarch64-unknown-freebsd.tar.xz) = d0f8413767123d9630bb2648fe15e8a2a05382cb7dcbe3c332223eb1e4a788a4
6
SHA256 (rust/2020-05-07/rust-std-1.43.1-aarch64-unknown-freebsd.tar.xz) = d0f8413767123d9630bb2648fe15e8a2a05382cb7dcbe3c332223eb1e4a788a4
(-)files/patch-src_llvm-project_llvm_lib_Transforms_InstCombine_InstCombineCasts.cpp (+156 lines)
Line 0 Link Here
1
From f8e146f3430de3a6cd904f3f3f7aa1bfaefee14c Mon Sep 17 00:00:00 2001
2
From: Bjorn Pettersson <bjorn.a.pettersson@ericsson.com>
3
Date: Thu, 28 Nov 2019 23:18:28 +0100
4
Subject: [PATCH] [InstCombine] Fix big-endian miscompile of (bitcast
5
 (zext/trunc (bitcast)))
6
7
Summary:
8
optimizeVectorResize is rewriting patterns like:
9
  %1 = bitcast vector %src to integer
10
  %2 = trunc/zext %1
11
  %dst = bitcast %2 to vector
12
13
Since bitcasting between integer an vector types gives
14
different integer values depending on endianness, we need
15
to take endianness into account. As it happens the old
16
implementation only produced the correct result for little
17
endian targets.
18
19
Fixes: https://bugs.llvm.org/show_bug.cgi?id=44178
20
21
Reviewers: spatel, lattner, lebedev.ri
22
23
Reviewed By: spatel, lebedev.ri
24
25
Subscribers: lebedev.ri, hiraditya, uabelho, llvm-commits
26
27
Tags: #llvm
28
29
Differential Revision: https://reviews.llvm.org/D70844
30
31
(cherry picked from commit a9d6b0e5444741d08ff1df7cf71d1559e7fefc1f)
32
---
33
 .../InstCombine/InstCombineCasts.cpp          | 79 +++++++++++++------
34
 llvm/test/Transforms/InstCombine/cast.ll      |  6 +-
35
 2 files changed, 60 insertions(+), 25 deletions(-)
36
37
--- src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp.orig	2020-04-07 15:52:51 UTC
38
+++ src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
39
@@ -18,6 +18,7 @@
40
 #include "llvm/IR/DIBuilder.h"
41
 #include "llvm/IR/PatternMatch.h"
42
 #include "llvm/Support/KnownBits.h"
43
+#include <numeric>
44
 using namespace llvm;
45
 using namespace PatternMatch;
46
 
47
@@ -1820,12 +1821,24 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst 
48
 }
49
 
50
 /// This input value (which is known to have vector type) is being zero extended
51
-/// or truncated to the specified vector type.
52
+/// or truncated to the specified vector type. Since the zext/trunc is done
53
+/// using an integer type, we have a (bitcast(cast(bitcast))) pattern,
54
+/// endianness will impact which end of the vector that is extended or
55
+/// truncated.
56
+///
57
+/// A vector is always stored with index 0 at the lowest address, which
58
+/// corresponds to the most significant bits for a big endian stored integer and
59
+/// the least significant bits for little endian. A trunc/zext of an integer
60
+/// impacts the big end of the integer. Thus, we need to add/remove elements at
61
+/// the front of the vector for big endian targets, and the back of the vector
62
+/// for little endian targets.
63
+///
64
 /// Try to replace it with a shuffle (and vector/vector bitcast) if possible.
65
 ///
66
 /// The source and destination vector types may have different element types.
67
-static Instruction *optimizeVectorResize(Value *InVal, VectorType *DestTy,
68
-                                         InstCombiner &IC) {
69
+static Instruction *optimizeVectorResizeWithIntegerBitCasts(Value *InVal,
70
+                                                            VectorType *DestTy,
71
+                                                            InstCombiner &IC) {
72
   // We can only do this optimization if the output is a multiple of the input
73
   // element size, or the input is a multiple of the output element size.
74
   // Convert the input type to have the same element type as the output.
75
@@ -1844,31 +1857,53 @@ static Instruction *optimizeVectorResize(Value *InVal,
76
     InVal = IC.Builder.CreateBitCast(InVal, SrcTy);
77
   }
78
 
79
+  bool IsBigEndian = IC.getDataLayout().isBigEndian();
80
+  unsigned SrcElts = SrcTy->getNumElements();
81
+  unsigned DestElts = DestTy->getNumElements();
82
+
83
+  assert(SrcElts != DestElts && "Element counts should be different.");
84
+
85
   // Now that the element types match, get the shuffle mask and RHS of the
86
   // shuffle to use, which depends on whether we're increasing or decreasing the
87
   // size of the input.
88
-  SmallVector<uint32_t, 16> ShuffleMask;
89
+  SmallVector<uint32_t, 16> ShuffleMaskStorage;
90
+  ArrayRef<uint32_t> ShuffleMask;
91
   Value *V2;
92
 
93
-  if (SrcTy->getNumElements() > DestTy->getNumElements()) {
94
-    // If we're shrinking the number of elements, just shuffle in the low
95
-    // elements from the input and use undef as the second shuffle input.
96
-    V2 = UndefValue::get(SrcTy);
97
-    for (unsigned i = 0, e = DestTy->getNumElements(); i != e; ++i)
98
-      ShuffleMask.push_back(i);
99
+  // Produce an identify shuffle mask for the src vector.
100
+  ShuffleMaskStorage.resize(SrcElts);
101
+  std::iota(ShuffleMaskStorage.begin(), ShuffleMaskStorage.end(), 0);
102
 
103
+  if (SrcElts > DestElts) {
104
+    // If we're shrinking the number of elements (rewriting an integer
105
+    // truncate), just shuffle in the elements corresponding to the least
106
+    // significant bits from the input and use undef as the second shuffle
107
+    // input.
108
+    V2 = UndefValue::get(SrcTy);
109
+    // Make sure the shuffle mask selects the "least significant bits" by
110
+    // keeping elements from back of the src vector for big endian, and from the
111
+    // front for little endian.
112
+    ShuffleMask = ShuffleMaskStorage;
113
+    if (IsBigEndian)
114
+      ShuffleMask = ShuffleMask.take_back(DestElts);
115
+    else
116
+      ShuffleMask = ShuffleMask.take_front(DestElts);
117
   } else {
118
-    // If we're increasing the number of elements, shuffle in all of the
119
-    // elements from InVal and fill the rest of the result elements with zeros
120
-    // from a constant zero.
121
+    // If we're increasing the number of elements (rewriting an integer zext),
122
+    // shuffle in all of the elements from InVal. Fill the rest of the result
123
+    // elements with zeros from a constant zero.
124
     V2 = Constant::getNullValue(SrcTy);
125
-    unsigned SrcElts = SrcTy->getNumElements();
126
-    for (unsigned i = 0, e = SrcElts; i != e; ++i)
127
-      ShuffleMask.push_back(i);
128
-
129
-    // The excess elements reference the first element of the zero input.
130
-    for (unsigned i = 0, e = DestTy->getNumElements()-SrcElts; i != e; ++i)
131
-      ShuffleMask.push_back(SrcElts);
132
+    // Use first elt from V2 when indicating zero in the shuffle mask.
133
+    uint32_t NullElt = SrcElts;
134
+    // Extend with null values in the "most significant bits" by adding elements
135
+    // in front of the src vector for big endian, and at the back for little
136
+    // endian.
137
+    unsigned DeltaElts = DestElts - SrcElts;
138
+    if (IsBigEndian)
139
+      ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt);
140
+    else
141
+      ShuffleMaskStorage.append(DeltaElts, NullElt);
142
+    ShuffleMask = ShuffleMaskStorage;
143
   }
144
 
145
   return new ShuffleVectorInst(InVal, V2,
146
@@ -2396,8 +2431,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &C
147
         CastInst *SrcCast = cast<CastInst>(Src);
148
         if (BitCastInst *BCIn = dyn_cast<BitCastInst>(SrcCast->getOperand(0)))
149
           if (isa<VectorType>(BCIn->getOperand(0)->getType()))
150
-            if (Instruction *I = optimizeVectorResize(BCIn->getOperand(0),
151
-                                               cast<VectorType>(DestTy), *this))
152
+            if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts(
153
+                    BCIn->getOperand(0), cast<VectorType>(DestTy), *this))
154
               return I;
155
       }
156
 
(-)files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs (-78 lines)
Lines 1-78 Link Here
1
--- src/librustc_mir/dataflow/framework/engine.rs.orig	2020-06-07 10:10:36 UTC
2
+++ src/librustc_mir/dataflow/framework/engine.rs
3
@@ -243,27 +243,24 @@ where
4
             }
5
 
6
             SwitchInt { ref targets, ref values, ref discr, .. } => {
7
-                let Engine { tcx, body, .. } = *self;
8
-                let enum_ = discr
9
-                    .place()
10
-                    .and_then(|discr| switch_on_enum_discriminant(tcx, body, bb_data, discr));
11
-                match enum_ {
12
-                    // If this is a switch on an enum discriminant, a custom effect may be applied
13
-                    // along each outgoing edge.
14
-                    Some((enum_place, enum_def)) => {
15
+                // If this is a switch on an enum discriminant, a custom effect may be applied
16
+                // along each outgoing edge.
17
+                if let Some(place) = discr.place() {
18
+                    let enum_def = switch_on_enum_discriminant(self.tcx, self.body, bb_data, place);
19
+                    if let Some(enum_def) = enum_def {
20
                         self.propagate_bits_into_enum_discriminant_switch_successors(
21
-                            in_out, bb, enum_def, enum_place, dirty_list, &*values, &*targets,
22
+                            in_out, bb, enum_def, place, dirty_list, &*values, &*targets,
23
                         );
24
-                    }
25
 
26
-                    // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same
27
-                    // exit state.
28
-                    None => {
29
-                        for target in targets.iter().copied() {
30
-                            self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list);
31
-                        }
32
+                            return;
33
                     }
34
                 }
35
+
36
+                // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same
37
+                // exit state.
38
+                for target in targets.iter().copied() {
39
+                    self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list);
40
+                }
41
             }
42
 
43
             Call { cleanup, ref destination, ref func, ref args, .. } => {
44
@@ -349,27 +346,22 @@ where
45
     }
46
 }
47
 
48
-/// Inspect a `SwitchInt`-terminated basic block to see if the condition of that `SwitchInt` is
49
-/// an enum discriminant.
50
-///
51
-/// We expect such blocks to have a call to `discriminant` as their last statement like so:
52
-///   _42 = discriminant(_1)
53
+/// Look at the last statement of a block that ends with  to see if it is an assignment of an enum
54
+/// discriminant to the local that determines the target of a `SwitchInt` like so:
55
+///   _42 = discriminant(..)
56
 ///   SwitchInt(_42, ..)
57
-///
58
-/// If the basic block matches this pattern, this function returns the place corresponding to the
59
-/// enum (`_1` in the example above) as well as the `AdtDef` of that enum.
60
 fn switch_on_enum_discriminant(
61
     tcx: TyCtxt<'tcx>,
62
-    body: &'mir mir::Body<'tcx>,
63
-    block: &'mir mir::BasicBlockData<'tcx>,
64
+    body: &mir::Body<'tcx>,
65
+    block: &mir::BasicBlockData<'tcx>,
66
     switch_on: mir::Place<'tcx>,
67
-) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
68
+) -> Option<&'tcx ty::AdtDef> {
69
     match block.statements.last().map(|stmt| &stmt.kind) {
70
         Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))))
71
             if *lhs == switch_on =>
72
         {
73
             match &discriminated.ty(body, tcx).ty.kind {
74
-                ty::Adt(def, _) => Some((*discriminated, def)),
75
+                ty::Adt(def, _) => Some(def),
76
 
77
                 // `Rvalue::Discriminant` is also used to get the active yield point for a
78
                 // generator, but we do not need edge-specific effects in that case. This may
(-)files/powerpc64-elfv2/patch-src_bootstrap_native.rs (-13 lines)
Lines 1-13 Link Here
1
--- src/bootstrap/native.rs.orig	2019-11-04 15:45:21 UTC
2
+++ src/bootstrap/native.rs
3
@@ -241,6 +241,10 @@ impl Step for Llvm {
4
             }
5
         }
6
 
7
+        if target == "powerpc64-unknown-freebsd" {
8
+            cfg.define("CMAKE_EXE_LINKER_FLAGS", "-Wl,-rpath=/usr/local/lib/%CC% -L/usr/local/lib/%CC%");
9
+        }
10
+
11
         // http://llvm.org/docs/HowToCrossCompileLLVM.html
12
         if target != builder.config.build && !emscripten {
13
             builder.ensure(Llvm {
(-)files/powerpc64-elfv2/patch-src_librustc__llvm_build.rs (-14 lines)
Lines 1-14 Link Here
1
--- src/librustc_llvm/build.rs.orig	2020-03-09 22:11:17 UTC
2
+++ src/librustc_llvm/build.rs
3
@@ -264,7 +264,10 @@ fn main() {
4
     };
5
 
6
     // C++ runtime library
7
-    if !target.contains("msvc") {
8
+    if target == "powerpc64-unknown-freebsd" && !is_crossed {
9
+        println!("cargo:rustc-link-search=native=/usr/local/lib/%CC%");
10
+        println!("cargo:rustc-link-lib=static=stdc++");
11
+    } else if !target.contains("msvc") {
12
         if let Some(s) = llvm_static_stdcpp {
13
             assert!(!cxxflags.contains("stdlib=libc++"));
14
             let path = PathBuf::from(s);
(-)files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs (-78 lines)
Lines 1-78 Link Here
1
--- src/librustc_mir/dataflow/framework/engine.rs.orig	2020-06-07 10:10:36 UTC
2
+++ src/librustc_mir/dataflow/framework/engine.rs
3
@@ -243,27 +243,24 @@ where
4
             }
5
 
6
             SwitchInt { ref targets, ref values, ref discr, .. } => {
7
-                let Engine { tcx, body, .. } = *self;
8
-                let enum_ = discr
9
-                    .place()
10
-                    .and_then(|discr| switch_on_enum_discriminant(tcx, body, bb_data, discr));
11
-                match enum_ {
12
-                    // If this is a switch on an enum discriminant, a custom effect may be applied
13
-                    // along each outgoing edge.
14
-                    Some((enum_place, enum_def)) => {
15
+                // If this is a switch on an enum discriminant, a custom effect may be applied
16
+                // along each outgoing edge.
17
+                if let Some(place) = discr.place() {
18
+                    let enum_def = switch_on_enum_discriminant(self.tcx, self.body, bb_data, place);
19
+                    if let Some(enum_def) = enum_def {
20
                         self.propagate_bits_into_enum_discriminant_switch_successors(
21
-                            in_out, bb, enum_def, enum_place, dirty_list, &*values, &*targets,
22
+                            in_out, bb, enum_def, place, dirty_list, &*values, &*targets,
23
                         );
24
-                    }
25
 
26
-                    // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same
27
-                    // exit state.
28
-                    None => {
29
-                        for target in targets.iter().copied() {
30
-                            self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list);
31
-                        }
32
+                            return;
33
                     }
34
                 }
35
+
36
+                // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same
37
+                // exit state.
38
+                for target in targets.iter().copied() {
39
+                    self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list);
40
+                }
41
             }
42
 
43
             Call { cleanup, ref destination, ref func, ref args, .. } => {
44
@@ -349,27 +346,22 @@ where
45
     }
46
 }
47
 
48
-/// Inspect a `SwitchInt`-terminated basic block to see if the condition of that `SwitchInt` is
49
-/// an enum discriminant.
50
-///
51
-/// We expect such blocks to have a call to `discriminant` as their last statement like so:
52
-///   _42 = discriminant(_1)
53
+/// Look at the last statement of a block that ends with  to see if it is an assignment of an enum
54
+/// discriminant to the local that determines the target of a `SwitchInt` like so:
55
+///   _42 = discriminant(..)
56
 ///   SwitchInt(_42, ..)
57
-///
58
-/// If the basic block matches this pattern, this function returns the place corresponding to the
59
-/// enum (`_1` in the example above) as well as the `AdtDef` of that enum.
60
 fn switch_on_enum_discriminant(
61
     tcx: TyCtxt<'tcx>,
62
-    body: &'mir mir::Body<'tcx>,
63
-    block: &'mir mir::BasicBlockData<'tcx>,
64
+    body: &mir::Body<'tcx>,
65
+    block: &mir::BasicBlockData<'tcx>,
66
     switch_on: mir::Place<'tcx>,
67
-) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
68
+) -> Option<&'tcx ty::AdtDef> {
69
     match block.statements.last().map(|stmt| &stmt.kind) {
70
         Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))))
71
             if *lhs == switch_on =>
72
         {
73
             match &discriminated.ty(body, tcx).ty.kind {
74
-                ty::Adt(def, _) => Some((*discriminated, def)),
75
+                ty::Adt(def, _) => Some(def),
76
 
77
                 // `Rvalue::Discriminant` is also used to get the active yield point for a
78
                 // generator, but we do not need edge-specific effects in that case. This may

Return to bug 247388