Skip to content

Commit 765f55c

Browse files
authored
Rollup merge of rust-lang#125893 - cjgillot:gvn-newops, r=oli-obk
Handle all GVN binops in a single place. <!-- If this PR is related to an unstable feature or an otherwise tracked effort, please link to the relevant tracking issue here. If you don't know of a related tracking issue or there are none, feel free to ignore this. This PR will get automatically assigned to a reviewer. In case you would like a specific user to review your work, you can assign it to them by using r​? <reviewer name> --> Addresses https://github.com/rust-lang/rust/pull/125359/files#r1608185319 r? ```@oli-obk```
2 parents 183ad51 + c3de4b3 commit 765f55c

File tree

1 file changed

+40
-30
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+40
-30
lines changed

compiler/rustc_mir_transform/src/gvn.rs

+40-30
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ enum Value<'tcx> {
223223
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
224224
UnaryOp(UnOp, VnIndex),
225225
BinaryOp(BinOp, VnIndex, VnIndex),
226-
CheckedBinaryOp(BinOp, VnIndex, VnIndex), // FIXME get rid of this, work like MIR instead
227226
Cast {
228227
kind: CastKind,
229228
value: VnIndex,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
508507
let val = self.ecx.binary_op(bin_op, &lhs, &rhs).ok()?;
509508
val.into()
510509
}
511-
CheckedBinaryOp(bin_op, lhs, rhs) => {
512-
let lhs = self.evaluated[lhs].as_ref()?;
513-
let lhs = self.ecx.read_immediate(lhs).ok()?;
514-
let rhs = self.evaluated[rhs].as_ref()?;
515-
let rhs = self.ecx.read_immediate(rhs).ok()?;
516-
let val = self
517-
.ecx
518-
.binary_op(bin_op.wrapping_to_overflowing().unwrap(), &lhs, &rhs)
519-
.ok()?;
520-
val.into()
521-
}
522510
Cast { kind, value, from: _, to } => match kind {
523511
CastKind::IntToInt | CastKind::IntToFloat => {
524512
let value = self.evaluated[value].as_ref()?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
829817
let lhs = lhs?;
830818
let rhs = rhs?;
831819

832-
if let Some(op) = op.overflowing_to_wrapping() {
833-
if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
834-
return Some(value);
835-
}
836-
Value::CheckedBinaryOp(op, lhs, rhs)
837-
} else {
838-
if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
839-
return Some(value);
840-
}
841-
Value::BinaryOp(op, lhs, rhs)
820+
if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
821+
return Some(value);
842822
}
823+
Value::BinaryOp(op, lhs, rhs)
843824
}
844825
Rvalue::UnaryOp(op, ref mut arg) => {
845826
let arg = self.simplify_operand(arg, location)?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
970951
fn simplify_binary(
971952
&mut self,
972953
op: BinOp,
973-
checked: bool,
974954
lhs_ty: Ty<'tcx>,
975955
lhs: VnIndex,
976956
rhs: VnIndex,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
999979
use Either::{Left, Right};
1000980
let a = as_bits(lhs).map_or(Right(lhs), Left);
1001981
let b = as_bits(rhs).map_or(Right(rhs), Left);
982+
1002983
let result = match (op, a, b) {
1003984
// Neutral elements.
1004-
(BinOp::Add | BinOp::BitOr | BinOp::BitXor, Left(0), Right(p))
985+
(
986+
BinOp::Add
987+
| BinOp::AddWithOverflow
988+
| BinOp::AddUnchecked
989+
| BinOp::BitOr
990+
| BinOp::BitXor,
991+
Left(0),
992+
Right(p),
993+
)
1005994
| (
1006995
BinOp::Add
996+
| BinOp::AddWithOverflow
997+
| BinOp::AddUnchecked
1007998
| BinOp::BitOr
1008999
| BinOp::BitXor
10091000
| BinOp::Sub
1001+
| BinOp::SubWithOverflow
1002+
| BinOp::SubUnchecked
10101003
| BinOp::Offset
10111004
| BinOp::Shl
10121005
| BinOp::Shr,
10131006
Right(p),
10141007
Left(0),
10151008
)
1016-
| (BinOp::Mul, Left(1), Right(p))
1017-
| (BinOp::Mul | BinOp::Div, Right(p), Left(1)) => p,
1009+
| (BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked, Left(1), Right(p))
1010+
| (
1011+
BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::Div,
1012+
Right(p),
1013+
Left(1),
1014+
) => p,
10181015
// Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
10191016
(BinOp::BitAnd, Right(p), Left(ones)) | (BinOp::BitAnd, Left(ones), Right(p))
10201017
if ones == layout.size.truncate(u128::MAX)
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10231020
p
10241021
}
10251022
// Absorbing elements.
1026-
(BinOp::Mul | BinOp::BitAnd, _, Left(0))
1023+
(
1024+
BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::BitAnd,
1025+
_,
1026+
Left(0),
1027+
)
10271028
| (BinOp::Rem, _, Left(1))
10281029
| (
1029-
BinOp::Mul | BinOp::Div | BinOp::Rem | BinOp::BitAnd | BinOp::Shl | BinOp::Shr,
1030+
BinOp::Mul
1031+
| BinOp::MulWithOverflow
1032+
| BinOp::MulUnchecked
1033+
| BinOp::Div
1034+
| BinOp::Rem
1035+
| BinOp::BitAnd
1036+
| BinOp::Shl
1037+
| BinOp::Shr,
10301038
Left(0),
10311039
_,
10321040
) => self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty),
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10381046
self.insert_scalar(Scalar::from_uint(ones, layout.size), lhs_ty)
10391047
}
10401048
// Sub/Xor with itself.
1041-
(BinOp::Sub | BinOp::BitXor, a, b) if a == b => {
1049+
(BinOp::Sub | BinOp::SubWithOverflow | BinOp::SubUnchecked | BinOp::BitXor, a, b)
1050+
if a == b =>
1051+
{
10421052
self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty)
10431053
}
10441054
// Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10521062
_ => return None,
10531063
};
10541064

1055-
if checked {
1065+
if op.is_overflowing() {
10561066
let false_val = self.insert_bool(false);
10571067
Some(self.insert_tuple(vec![result, false_val]))
10581068
} else {

0 commit comments

Comments
 (0)