Index: head/lang/rust-bootstrap/Makefile =================================================================== --- head/lang/rust-bootstrap/Makefile +++ head/lang/rust-bootstrap/Makefile @@ -1,8 +1,7 @@ # $FreeBSD$ PORTNAME= rust -PORTVERSION= 1.44.0 -PORTREVISION= 1 +PORTVERSION= 1.44.1 CATEGORIES= lang MASTER_SITES= https://static.rust-lang.org/dist/:rust \ LOCAL/tobik:armbase \ Index: head/lang/rust-bootstrap/distinfo =================================================================== --- head/lang/rust-bootstrap/distinfo +++ head/lang/rust-bootstrap/distinfo @@ -1,6 +1,6 @@ -TIMESTAMP = 1591049034 -SHA256 (rust/rustc-1.44.0-src.tar.xz) = b32fa7d6bd6ff9286aab2aa7ca696d1da921614cefc10f617aef68d9bce9118a -SIZE (rust/rustc-1.44.0-src.tar.xz) = 94754392 +TIMESTAMP = 1592489407 +SHA256 (rust/rustc-1.44.1-src.tar.xz) = e0386295dd5f2c7842835a509e4c57989eec6c29f989a1c85478b0e06f9d38ea +SIZE (rust/rustc-1.44.1-src.tar.xz) = 94756856 SHA256 (FreeBSD-11.3-RELEASE-arm64.tar.xz) = 0c1ee2bdbec3b6b404edef6858f38f5cdacd727abc53b1dee23910cab939d0c1 SIZE (FreeBSD-11.3-RELEASE-arm64.tar.xz) = 97990888 SHA256 (FreeBSD-11.3-RELEASE-amd64.tar.xz) = 4599023ac136325b86f2fddeec64c1624daa83657e40b00b2ef944c81463a4ff Index: head/lang/rust/Makefile =================================================================== --- head/lang/rust/Makefile +++ head/lang/rust/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PORTNAME= rust -PORTVERSION?= 1.44.0 +PORTVERSION?= 1.44.1 PORTREVISION?= 0 CATEGORIES= lang MASTER_SITES= https://static.rust-lang.org/dist/:src \ @@ -150,10 +150,6 @@ @${ECHO_CMD} 'default-linker="${CC}"' >> ${WRKSRC}/config.toml @${ECHO_CMD} 'verbose-tests=true' >> ${WRKSRC}/config.toml @${ECHO_CMD} 'lld=${_RUST_BUILD_WASM}' >> ${WRKSRC}/config.toml -.if ${ARCH} == powerpc64 -# XXX: crashes without this? - @${ECHO_CMD} 'debuginfo-level-std=1' >> ${WRKSRC}/config.toml -.endif @${ECHO_CMD} '[llvm]' >> ${WRKSRC}/config.toml .if defined(WITH_CCACHE_BUILD) && !defined(NO_CCACHE) @${ECHO_CMD} 'ccache="${CCACHE_BIN}"' >> ${WRKSRC}/config.toml Index: head/lang/rust/distinfo =================================================================== --- head/lang/rust/distinfo +++ head/lang/rust/distinfo @@ -1,6 +1,6 @@ -TIMESTAMP = 1591048305 -SHA256 (rust/rustc-1.44.0-src.tar.xz) = b32fa7d6bd6ff9286aab2aa7ca696d1da921614cefc10f617aef68d9bce9118a -SIZE (rust/rustc-1.44.0-src.tar.xz) = 94754392 +TIMESTAMP = 1592451352 +SHA256 (rust/rustc-1.44.1-src.tar.xz) = e0386295dd5f2c7842835a509e4c57989eec6c29f989a1c85478b0e06f9d38ea +SIZE (rust/rustc-1.44.1-src.tar.xz) = 94756856 SHA256 (rust/2020-05-07/rustc-1.43.1-aarch64-unknown-freebsd.tar.xz) = bf65d73547f9a1445ea8177fc452dddab8bbcfff8ad17d8292903ba4fc65d1a6 SIZE (rust/2020-05-07/rustc-1.43.1-aarch64-unknown-freebsd.tar.xz) = 27175484 SHA256 (rust/2020-05-07/rust-std-1.43.1-aarch64-unknown-freebsd.tar.xz) = d0f8413767123d9630bb2648fe15e8a2a05382cb7dcbe3c332223eb1e4a788a4 Index: head/lang/rust/files/patch-src_llvm-project_llvm_lib_Transforms_InstCombine_InstCombineCasts.cpp =================================================================== --- head/lang/rust/files/patch-src_llvm-project_llvm_lib_Transforms_InstCombine_InstCombineCasts.cpp +++ head/lang/rust/files/patch-src_llvm-project_llvm_lib_Transforms_InstCombine_InstCombineCasts.cpp @@ -0,0 +1,156 @@ +From f8e146f3430de3a6cd904f3f3f7aa1bfaefee14c Mon Sep 17 00:00:00 2001 +From: Bjorn Pettersson +Date: Thu, 28 Nov 2019 23:18:28 +0100 +Subject: [PATCH] [InstCombine] Fix big-endian miscompile of (bitcast + (zext/trunc (bitcast))) + +Summary: +optimizeVectorResize is rewriting patterns like: + %1 = bitcast vector %src to integer + %2 = trunc/zext %1 + %dst = bitcast %2 to vector + +Since bitcasting between integer an vector types gives +different integer values depending on endianness, we need +to take endianness into account. As it happens the old +implementation only produced the correct result for little +endian targets. + +Fixes: https://bugs.llvm.org/show_bug.cgi?id=44178 + +Reviewers: spatel, lattner, lebedev.ri + +Reviewed By: spatel, lebedev.ri + +Subscribers: lebedev.ri, hiraditya, uabelho, llvm-commits + +Tags: #llvm + +Differential Revision: https://reviews.llvm.org/D70844 + +(cherry picked from commit a9d6b0e5444741d08ff1df7cf71d1559e7fefc1f) +--- + .../InstCombine/InstCombineCasts.cpp | 79 +++++++++++++------ + llvm/test/Transforms/InstCombine/cast.ll | 6 +- + 2 files changed, 60 insertions(+), 25 deletions(-) + +--- src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp.orig 2020-04-07 15:52:51 UTC ++++ src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +@@ -18,6 +18,7 @@ + #include "llvm/IR/DIBuilder.h" + #include "llvm/IR/PatternMatch.h" + #include "llvm/Support/KnownBits.h" ++#include + using namespace llvm; + using namespace PatternMatch; + +@@ -1820,12 +1821,24 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst + } + + /// This input value (which is known to have vector type) is being zero extended +-/// or truncated to the specified vector type. ++/// or truncated to the specified vector type. Since the zext/trunc is done ++/// using an integer type, we have a (bitcast(cast(bitcast))) pattern, ++/// endianness will impact which end of the vector that is extended or ++/// truncated. ++/// ++/// A vector is always stored with index 0 at the lowest address, which ++/// corresponds to the most significant bits for a big endian stored integer and ++/// the least significant bits for little endian. A trunc/zext of an integer ++/// impacts the big end of the integer. Thus, we need to add/remove elements at ++/// the front of the vector for big endian targets, and the back of the vector ++/// for little endian targets. ++/// + /// Try to replace it with a shuffle (and vector/vector bitcast) if possible. + /// + /// The source and destination vector types may have different element types. +-static Instruction *optimizeVectorResize(Value *InVal, VectorType *DestTy, +- InstCombiner &IC) { ++static Instruction *optimizeVectorResizeWithIntegerBitCasts(Value *InVal, ++ VectorType *DestTy, ++ InstCombiner &IC) { + // We can only do this optimization if the output is a multiple of the input + // element size, or the input is a multiple of the output element size. + // Convert the input type to have the same element type as the output. +@@ -1844,31 +1857,53 @@ static Instruction *optimizeVectorResize(Value *InVal, + InVal = IC.Builder.CreateBitCast(InVal, SrcTy); + } + ++ bool IsBigEndian = IC.getDataLayout().isBigEndian(); ++ unsigned SrcElts = SrcTy->getNumElements(); ++ unsigned DestElts = DestTy->getNumElements(); ++ ++ assert(SrcElts != DestElts && "Element counts should be different."); ++ + // Now that the element types match, get the shuffle mask and RHS of the + // shuffle to use, which depends on whether we're increasing or decreasing the + // size of the input. +- SmallVector ShuffleMask; ++ SmallVector ShuffleMaskStorage; ++ ArrayRef ShuffleMask; + Value *V2; + +- if (SrcTy->getNumElements() > DestTy->getNumElements()) { +- // If we're shrinking the number of elements, just shuffle in the low +- // elements from the input and use undef as the second shuffle input. +- V2 = UndefValue::get(SrcTy); +- for (unsigned i = 0, e = DestTy->getNumElements(); i != e; ++i) +- ShuffleMask.push_back(i); ++ // Produce an identify shuffle mask for the src vector. ++ ShuffleMaskStorage.resize(SrcElts); ++ std::iota(ShuffleMaskStorage.begin(), ShuffleMaskStorage.end(), 0); + ++ if (SrcElts > DestElts) { ++ // If we're shrinking the number of elements (rewriting an integer ++ // truncate), just shuffle in the elements corresponding to the least ++ // significant bits from the input and use undef as the second shuffle ++ // input. ++ V2 = UndefValue::get(SrcTy); ++ // Make sure the shuffle mask selects the "least significant bits" by ++ // keeping elements from back of the src vector for big endian, and from the ++ // front for little endian. ++ ShuffleMask = ShuffleMaskStorage; ++ if (IsBigEndian) ++ ShuffleMask = ShuffleMask.take_back(DestElts); ++ else ++ ShuffleMask = ShuffleMask.take_front(DestElts); + } else { +- // If we're increasing the number of elements, shuffle in all of the +- // elements from InVal and fill the rest of the result elements with zeros +- // from a constant zero. ++ // If we're increasing the number of elements (rewriting an integer zext), ++ // shuffle in all of the elements from InVal. Fill the rest of the result ++ // elements with zeros from a constant zero. + V2 = Constant::getNullValue(SrcTy); +- unsigned SrcElts = SrcTy->getNumElements(); +- for (unsigned i = 0, e = SrcElts; i != e; ++i) +- ShuffleMask.push_back(i); +- +- // The excess elements reference the first element of the zero input. +- for (unsigned i = 0, e = DestTy->getNumElements()-SrcElts; i != e; ++i) +- ShuffleMask.push_back(SrcElts); ++ // Use first elt from V2 when indicating zero in the shuffle mask. ++ uint32_t NullElt = SrcElts; ++ // Extend with null values in the "most significant bits" by adding elements ++ // in front of the src vector for big endian, and at the back for little ++ // endian. ++ unsigned DeltaElts = DestElts - SrcElts; ++ if (IsBigEndian) ++ ShuffleMaskStorage.insert(ShuffleMaskStorage.begin(), DeltaElts, NullElt); ++ else ++ ShuffleMaskStorage.append(DeltaElts, NullElt); ++ ShuffleMask = ShuffleMaskStorage; + } + + return new ShuffleVectorInst(InVal, V2, +@@ -2396,8 +2431,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &C + CastInst *SrcCast = cast(Src); + if (BitCastInst *BCIn = dyn_cast(SrcCast->getOperand(0))) + if (isa(BCIn->getOperand(0)->getType())) +- if (Instruction *I = optimizeVectorResize(BCIn->getOperand(0), +- cast(DestTy), *this)) ++ if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts( ++ BCIn->getOperand(0), cast(DestTy), *this)) + return I; + } + Index: head/lang/rust/files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs =================================================================== --- head/lang/rust/files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs +++ head/lang/rust/files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs @@ -1,78 +0,0 @@ ---- src/librustc_mir/dataflow/framework/engine.rs.orig 2020-06-07 10:10:36 UTC -+++ src/librustc_mir/dataflow/framework/engine.rs -@@ -243,27 +243,24 @@ where - } - - SwitchInt { ref targets, ref values, ref discr, .. } => { -- let Engine { tcx, body, .. } = *self; -- let enum_ = discr -- .place() -- .and_then(|discr| switch_on_enum_discriminant(tcx, body, bb_data, discr)); -- match enum_ { -- // If this is a switch on an enum discriminant, a custom effect may be applied -- // along each outgoing edge. -- Some((enum_place, enum_def)) => { -+ // If this is a switch on an enum discriminant, a custom effect may be applied -+ // along each outgoing edge. -+ if let Some(place) = discr.place() { -+ let enum_def = switch_on_enum_discriminant(self.tcx, self.body, bb_data, place); -+ if let Some(enum_def) = enum_def { - self.propagate_bits_into_enum_discriminant_switch_successors( -- in_out, bb, enum_def, enum_place, dirty_list, &*values, &*targets, -+ in_out, bb, enum_def, place, dirty_list, &*values, &*targets, - ); -- } - -- // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same -- // exit state. -- None => { -- for target in targets.iter().copied() { -- self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list); -- } -+ return; - } - } -+ -+ // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same -+ // exit state. -+ for target in targets.iter().copied() { -+ self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list); -+ } - } - - Call { cleanup, ref destination, ref func, ref args, .. } => { -@@ -349,27 +346,22 @@ where - } - } - --/// Inspect a `SwitchInt`-terminated basic block to see if the condition of that `SwitchInt` is --/// an enum discriminant. --/// --/// We expect such blocks to have a call to `discriminant` as their last statement like so: --/// _42 = discriminant(_1) -+/// Look at the last statement of a block that ends with to see if it is an assignment of an enum -+/// discriminant to the local that determines the target of a `SwitchInt` like so: -+/// _42 = discriminant(..) - /// SwitchInt(_42, ..) --/// --/// If the basic block matches this pattern, this function returns the place corresponding to the --/// enum (`_1` in the example above) as well as the `AdtDef` of that enum. - fn switch_on_enum_discriminant( - tcx: TyCtxt<'tcx>, -- body: &'mir mir::Body<'tcx>, -- block: &'mir mir::BasicBlockData<'tcx>, -+ body: &mir::Body<'tcx>, -+ block: &mir::BasicBlockData<'tcx>, - switch_on: mir::Place<'tcx>, --) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> { -+) -> Option<&'tcx ty::AdtDef> { - match block.statements.last().map(|stmt| &stmt.kind) { - Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))) - if *lhs == switch_on => - { - match &discriminated.ty(body, tcx).ty.kind { -- ty::Adt(def, _) => Some((*discriminated, def)), -+ ty::Adt(def, _) => Some(def), - - // `Rvalue::Discriminant` is also used to get the active yield point for a - // generator, but we do not need edge-specific effects in that case. This may Index: head/lang/rust/files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs =================================================================== --- head/lang/rust/files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs +++ head/lang/rust/files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs @@ -1,78 +0,0 @@ ---- src/librustc_mir/dataflow/framework/engine.rs.orig 2020-06-07 10:10:36 UTC -+++ src/librustc_mir/dataflow/framework/engine.rs -@@ -243,27 +243,24 @@ where - } - - SwitchInt { ref targets, ref values, ref discr, .. } => { -- let Engine { tcx, body, .. } = *self; -- let enum_ = discr -- .place() -- .and_then(|discr| switch_on_enum_discriminant(tcx, body, bb_data, discr)); -- match enum_ { -- // If this is a switch on an enum discriminant, a custom effect may be applied -- // along each outgoing edge. -- Some((enum_place, enum_def)) => { -+ // If this is a switch on an enum discriminant, a custom effect may be applied -+ // along each outgoing edge. -+ if let Some(place) = discr.place() { -+ let enum_def = switch_on_enum_discriminant(self.tcx, self.body, bb_data, place); -+ if let Some(enum_def) = enum_def { - self.propagate_bits_into_enum_discriminant_switch_successors( -- in_out, bb, enum_def, enum_place, dirty_list, &*values, &*targets, -+ in_out, bb, enum_def, place, dirty_list, &*values, &*targets, - ); -- } - -- // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same -- // exit state. -- None => { -- for target in targets.iter().copied() { -- self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list); -- } -+ return; - } - } -+ -+ // Otherwise, it's just a normal `SwitchInt`, and every successor sees the same -+ // exit state. -+ for target in targets.iter().copied() { -+ self.propagate_bits_into_entry_set_for(&in_out, target, dirty_list); -+ } - } - - Call { cleanup, ref destination, ref func, ref args, .. } => { -@@ -349,27 +346,22 @@ where - } - } - --/// Inspect a `SwitchInt`-terminated basic block to see if the condition of that `SwitchInt` is --/// an enum discriminant. --/// --/// We expect such blocks to have a call to `discriminant` as their last statement like so: --/// _42 = discriminant(_1) -+/// Look at the last statement of a block that ends with to see if it is an assignment of an enum -+/// discriminant to the local that determines the target of a `SwitchInt` like so: -+/// _42 = discriminant(..) - /// SwitchInt(_42, ..) --/// --/// If the basic block matches this pattern, this function returns the place corresponding to the --/// enum (`_1` in the example above) as well as the `AdtDef` of that enum. - fn switch_on_enum_discriminant( - tcx: TyCtxt<'tcx>, -- body: &'mir mir::Body<'tcx>, -- block: &'mir mir::BasicBlockData<'tcx>, -+ body: &mir::Body<'tcx>, -+ block: &mir::BasicBlockData<'tcx>, - switch_on: mir::Place<'tcx>, --) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> { -+) -> Option<&'tcx ty::AdtDef> { - match block.statements.last().map(|stmt| &stmt.kind) { - Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))) - if *lhs == switch_on => - { - match &discriminated.ty(body, tcx).ty.kind { -- ty::Adt(def, _) => Some((*discriminated, def)), -+ ty::Adt(def, _) => Some(def), - - // `Rvalue::Discriminant` is also used to get the active yield point for a - // generator, but we do not need edge-specific effects in that case. This may