1 #![allow(non_camel_case_types)]
3 use rustc_errors::struct_span_err;
5 use rustc_hir::def_id::DefId;
6 use rustc_hir::LangItem;
7 use rustc_middle::ty::{Ty, TyCtxt};
8 use rustc_session::Session;
12 use crate::traits::BuilderMethods;
15 pub enum IntPredicate {
28 pub enum RealPredicate {
47 pub enum AtomicRmwBinOp {
61 pub enum AtomicOrdering {
65 // Consume, // Not specified yet.
69 SequentiallyConsistent,
72 pub enum SynchronizationScope {
77 #[derive(Copy, Clone, PartialEq, Debug)]
100 // FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
101 // the HashStable trait. Normally DepGraph::with_task() calls are
102 // hidden behind queries, but CGU creation is a special case in two
103 // ways: (1) it's not a query and (2) CGU are output nodes, so their
104 // Fingerprints are not actually needed. It remains to be clarified
105 // how exactly this case will be handled in the red/green system but
106 // for now we content ourselves with providing a no-op HashStable
107 // implementation for CGUs.
108 mod temp_stable_hash_impls {
109 use crate::ModuleCodegen;
110 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
112 impl<HCX, M> HashStable<HCX> for ModuleCodegen<M> {
113 fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
119 pub fn langcall(tcx: TyCtxt<'_>, span: Option<Span>, msg: &str, li: LangItem) -> DefId {
120 tcx.lang_items().require(li).unwrap_or_else(|s| {
121 let msg = format!("{} {}", msg, s);
123 Some(span) => tcx.sess.span_fatal(span, &msg[..]),
124 None => tcx.sess.fatal(&msg[..]),
129 // To avoid UB from LLVM, these two functions mask RHS with an
130 // appropriate mask unconditionally (i.e., the fallback behavior for
131 // all shifts). For 32- and 64-bit types, this matches the semantics
132 // of Java. (See related discussion on #1877 and #10183.)
134 pub fn build_unchecked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
139 let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shl, lhs, rhs);
140 // #1877, #10183: Ensure that input is always valid
141 let rhs = shift_mask_rhs(bx, rhs);
145 pub fn build_unchecked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
151 let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
152 // #1877, #10183: Ensure that input is always valid
153 let rhs = shift_mask_rhs(bx, rhs);
154 let is_signed = lhs_t.is_signed();
155 if is_signed { bx.ashr(lhs, rhs) } else { bx.lshr(lhs, rhs) }
158 fn shift_mask_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
162 let rhs_llty = bx.val_ty(rhs);
163 let shift_val = shift_mask_val(bx, rhs_llty, rhs_llty, false);
164 bx.and(rhs, shift_val)
167 pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
173 let kind = bx.type_kind(llty);
175 TypeKind::Integer => {
176 // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
177 let val = bx.int_width(llty) - 1;
179 bx.const_int(mask_llty, !val as i64)
181 bx.const_uint(mask_llty, val)
184 TypeKind::Vector => {
186 shift_mask_val(bx, bx.element_type(llty), bx.element_type(mask_llty), invert);
187 bx.vector_splat(bx.vector_length(mask_llty), mask)
189 _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
193 pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
194 struct_span_err!(a, b, E0511, "{}", c).emit();