diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2024-06-22 13:45:14 -0700 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2024-06-22 20:27:08 -0700 |
| commit | dd1e19e7c22c1a670501cb7e8b9a036d8aa3af5d (patch) | |
| tree | 7c66bcc074f24d1e95a0f6d25dfdfa00143a8cc9 /compiler/rustc_mir_transform/src | |
| parent | a76e1d9b09ece967c01aafd3f8419f579a7ac5ca (diff) | |
| download | rust-dd1e19e7c22c1a670501cb7e8b9a036d8aa3af5d.tar.gz rust-dd1e19e7c22c1a670501cb7e8b9a036d8aa3af5d.zip | |
GVN away PtrToPtr before comparisons
Notably this happens in `NonNull::eq` :/
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/gvn.rs | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 23124523f17..cf1fff97f2a 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -823,18 +823,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return self.simplify_cast(kind, value, to, location); } Rvalue::BinaryOp(op, box (ref mut lhs, ref mut rhs)) => { - let ty = lhs.ty(self.local_decls, self.tcx); - let lhs = self.simplify_operand(lhs, location); - let rhs = self.simplify_operand(rhs, location); - // Only short-circuit options after we called `simplify_operand` - // on both operands for side effect. - let lhs = lhs?; - let rhs = rhs?; - - if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) { - return Some(value); - } - Value::BinaryOp(op, lhs, rhs) + return self.simplify_binary(op, lhs, rhs, location); } Rvalue::UnaryOp(op, ref mut arg_op) => { return self.simplify_unary(op, arg_op, location); @@ -1061,6 +1050,52 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { fn simplify_binary( &mut self, op: BinOp, + lhs_operand: &mut Operand<'tcx>, + rhs_operand: &mut Operand<'tcx>, + location: Location, + ) -> Option<VnIndex> { + + let lhs = self.simplify_operand(lhs_operand, location); + let rhs = self.simplify_operand(rhs_operand, location); + // Only short-circuit options after we called `simplify_operand` + // on both operands for side effect. + let mut lhs = lhs?; + let mut rhs = rhs?; + + let lhs_ty = lhs_operand.ty(self.local_decls, self.tcx); + + // If we're comparing pointers, remove `PtrToPtr` casts if the from + // types of both casts and the metadata all match. + if let BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge = op + && lhs_ty.is_any_ptr() + && let Value::Cast { kind: CastKind::PtrToPtr, value: lhs_value, from: lhs_from, .. } = + self.get(lhs) + && let Value::Cast { kind: CastKind::PtrToPtr, value: rhs_value, from: rhs_from, .. } = + self.get(rhs) + && lhs_from == rhs_from + && lhs_from.pointee_metadata_ty_or_projection(self.tcx) + == lhs_ty.pointee_metadata_ty_or_projection(self.tcx) + { + lhs = *lhs_value; + rhs = *rhs_value; + if let Some(op) = self.try_as_operand(lhs, location) { + *lhs_operand = op; + } + if let Some(op) = self.try_as_operand(rhs, location) { + *rhs_operand = op; + } + } + + if let Some(value) = self.simplify_binary_inner(op, lhs_ty, lhs, rhs) { + return Some(value); + } + let value = Value::BinaryOp(op, lhs, rhs); + Some(self.insert(value)) + } + + fn simplify_binary_inner( + &mut self, + op: BinOp, lhs_ty: Ty<'tcx>, lhs: VnIndex, rhs: VnIndex, |
