Auto merge of #122282 - DianQK:simplify_ub_check, r= · rust-lang/rust@acc30d0 (original) (raw)

1

1

`//! Performs various peephole optimizations.

`

2

2

``

3

3

`use crate::simplify::simplify_duplicate_switch_targets;

`

``

4

`+

use rustc_ast::attr;

`

4

5

`use rustc_middle::mir::*;

`

5

6

`use rustc_middle::ty::layout;

`

6

7

`use rustc_middle::ty::layout::ValidityRequirement;

`

7

8

`use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt};

`

``

9

`+

use rustc_span::sym;

`

8

10

`use rustc_span::symbol::Symbol;

`

9

11

`use rustc_target::abi::FieldIdx;

`

10

12

`use rustc_target::spec::abi::Abi;

`

`@@ -22,10 +24,17 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {

`

22

24

`local_decls: &body.local_decls,

`

23

25

`param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),

`

24

26

`};

`

``

27

`` +

// FIXME(#116171) Coverage related, also see unreachable_prop.rs.

``

``

28

`+

let rustc_ub_check = attr::contains_name(tcx.hir().krate_attrs(), sym::rustc_ub_check)

`

``

29

`+

|| tcx.sess.instrument_coverage();

`

``

30

`+

let debug_assertions = tcx.sess.opts.debug_assertions;

`

25

31

`for block in body.basic_blocks.as_mut() {

`

26

32

`for statement in block.statements.iter_mut() {

`

27

33

`match statement.kind {

`

28

34

`StatementKind::Assign(box (_place, ref mut rvalue)) => {

`

``

35

`+

if !rustc_ub_check {

`

``

36

`+

ctx.simplify_ub_check(&statement.source_info, rvalue, debug_assertions);

`

``

37

`+

}

`

29

38

` ctx.simplify_bool_cmp(&statement.source_info, rvalue);

`

30

39

` ctx.simplify_ref_deref(&statement.source_info, rvalue);

`

31

40

` ctx.simplify_len(&statement.source_info, rvalue);

`

`@@ -140,6 +149,24 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {

`

140

149

`}

`

141

150

`}

`

142

151

``

``

152

`+

fn simplify_ub_check(

`

``

153

`+

&self,

`

``

154

`+

source_info: &SourceInfo,

`

``

155

`+

rvalue: &mut Rvalue<'tcx>,

`

``

156

`+

debug_assertions: bool,

`

``

157

`+

) {

`

``

158

`+

if let Rvalue::NullaryOp(ref null_op, _) = *rvalue {

`

``

159

`+

match null_op {

`

``

160

`+

NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) => {}

`

``

161

`+

NullOp::UbCheck(_) => {

`

``

162

`+

let const_ = Const::from_bool(self.tcx, debug_assertions);

`

``

163

`+

let constant = ConstOperand { span: source_info.span, const_, user_ty: None };

`

``

164

`+

*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));

`

``

165

`+

}

`

``

166

`+

}

`

``

167

`+

}

`

``

168

`+

}

`

``

169

+

143

170

`fn simplify_cast(&self, rvalue: &mut Rvalue<'tcx>) {

`

144

171

`if let Rvalue::Cast(kind, operand, cast_ty) = rvalue {

`

145

172

`let operand_ty = operand.ty(self.local_decls, self.tcx);

`