FreeBSD Bugzilla – Attachment 215614 Details for
Bug 247307
lang/rust: properly fix build
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch
rust.patch (text/plain), 24.95 KB, created by
Piotr Kubaj
on 2020-06-16 14:28:42 UTC
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Piotr Kubaj
Created:
2020-06-16 14:28:42 UTC
Size:
24.95 KB
patch
obsolete
>Index: files/powerpc64-elfv1/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex >=================================================================== >--- files/powerpc64-elfv1/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex (nonexistent) >+++ files/powerpc64-elfv1/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex (working copy) >@@ -0,0 +1,158 @@ >+From f8e146f3430de3a6cd904f3f3f7aa1bfaefee14c Mon Sep 17 00:00:00 2001 >+From: Bjorn Pettersson <bjorn.a.pettersson@ericsson.com> >+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(-) >+ >+diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp >+index 2c9ba203fbf3..0af3de300e77 100644 >+--- src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp >++++ 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 <numeric> >+ using namespace llvm; >+ using namespace PatternMatch; >+ >+@@ -1820,12 +1821,24 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) { >+ } >+ >+ /// 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, VectorType *DestTy, >+ 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<uint32_t, 16> ShuffleMask; >++ SmallVector<uint32_t, 16> ShuffleMaskStorage; >++ ArrayRef<uint32_t> 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, >+@@ -2359,8 +2394,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) { >+ CastInst *SrcCast = cast<CastInst>(Src); >+ if (BitCastInst *BCIn = dyn_cast<BitCastInst>(SrcCast->getOperand(0))) >+ if (isa<VectorType>(BCIn->getOperand(0)->getType())) >+- if (Instruction *I = optimizeVectorResize(BCIn->getOperand(0), >+- cast<VectorType>(DestTy), *this)) >++ if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts( >++ BCIn->getOperand(0), cast<VectorType>(DestTy), *this)) >+ return I; >+ } >+ > >Property changes on: files/powerpc64-elfv1/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs >=================================================================== >--- files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs (revision 538658) >+++ files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs (nonexistent) >@@ -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 > >Property changes on: files/powerpc64-elfv1/patch-src_librustc__mir_dataflow_framework_engine.rs >___________________________________________________________________ >Deleted: fbsd:nokeywords >## -1 +0,0 ## >-yes >\ No newline at end of property >Deleted: svn:eol-style >## -1 +0,0 ## >-native >\ No newline at end of property >Deleted: svn:mime-type >## -1 +0,0 ## >-text/plain >\ No newline at end of property >Index: files/powerpc64-elfv2/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex >=================================================================== >--- files/powerpc64-elfv2/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex (nonexistent) >+++ files/powerpc64-elfv2/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex (working copy) >@@ -0,0 +1,158 @@ >+From f8e146f3430de3a6cd904f3f3f7aa1bfaefee14c Mon Sep 17 00:00:00 2001 >+From: Bjorn Pettersson <bjorn.a.pettersson@ericsson.com> >+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(-) >+ >+diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp >+index 2c9ba203fbf3..0af3de300e77 100644 >+--- src/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp >++++ 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 <numeric> >+ using namespace llvm; >+ using namespace PatternMatch; >+ >+@@ -1820,12 +1821,24 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) { >+ } >+ >+ /// 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, VectorType *DestTy, >+ 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<uint32_t, 16> ShuffleMask; >++ SmallVector<uint32_t, 16> ShuffleMaskStorage; >++ ArrayRef<uint32_t> 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, >+@@ -2359,8 +2394,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) { >+ CastInst *SrcCast = cast<CastInst>(Src); >+ if (BitCastInst *BCIn = dyn_cast<BitCastInst>(SrcCast->getOperand(0))) >+ if (isa<VectorType>(BCIn->getOperand(0)->getType())) >+- if (Instruction *I = optimizeVectorResize(BCIn->getOperand(0), >+- cast<VectorType>(DestTy), *this)) >++ if (Instruction *I = optimizeVectorResizeWithIntegerBitCasts( >++ BCIn->getOperand(0), cast<VectorType>(DestTy), *this)) >+ return I; >+ } >+ > >Property changes on: files/powerpc64-elfv2/patch-InstCombine-Fix-big-endian-miscompile-of-bitcast-zex >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property >Index: files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs >=================================================================== >--- files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs (revision 538658) >+++ files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs (nonexistent) >@@ -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 > >Property changes on: files/powerpc64-elfv2/patch-src_librustc__mir_dataflow_framework_engine.rs >___________________________________________________________________ >Deleted: fbsd:nokeywords >## -1 +0,0 ## >-yes >\ No newline at end of property >Deleted: svn:eol-style >## -1 +0,0 ## >-native >\ No newline at end of property >Deleted: svn:mime-type >## -1 +0,0 ## >-text/plain >\ No newline at end of property
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 247307
: 215614