]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/builder.rs
Auto merge of #68679 - matthewjasper:needs-type-op, r=varkor
[rust.git] / src / librustc_codegen_llvm / builder.rs
1 use crate::common::Funclet;
2 use crate::context::CodegenCx;
3 use crate::llvm::{self, BasicBlock, False};
4 use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope};
5 use crate::type_::Type;
6 use crate::type_of::LayoutLlvmExt;
7 use crate::value::Value;
8 use libc::{c_char, c_uint};
9 use log::debug;
10 use rustc::session::config::{self, Sanitizer};
11 use rustc::ty::layout::{self, Align, Size, TyLayout};
12 use rustc::ty::{self, Ty, TyCtxt};
13 use rustc_codegen_ssa::base::to_immediate;
14 use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind};
15 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
16 use rustc_codegen_ssa::mir::place::PlaceRef;
17 use rustc_codegen_ssa::traits::*;
18 use rustc_codegen_ssa::MemFlags;
19 use rustc_data_structures::const_cstr;
20 use rustc_data_structures::small_c_str::SmallCStr;
21 use rustc_hir::def_id::DefId;
22 use rustc_target::spec::{HasTargetSpec, Target};
23 use std::borrow::Cow;
24 use std::ffi::CStr;
25 use std::iter::TrustedLen;
26 use std::ops::{Deref, Range};
27 use std::ptr;
28
29 // All Builders must have an llfn associated with them
30 #[must_use]
31 pub struct Builder<'a, 'll, 'tcx> {
32     pub llbuilder: &'ll mut llvm::Builder<'ll>,
33     pub cx: &'a CodegenCx<'ll, 'tcx>,
34 }
35
36 impl Drop for Builder<'a, 'll, 'tcx> {
37     fn drop(&mut self) {
38         unsafe {
39             llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
40         }
41     }
42 }
43
44 // FIXME(eddyb) use a checked constructor when they become `const fn`.
45 const EMPTY_C_STR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"\0") };
46
47 /// Empty string, to be used where LLVM expects an instruction name, indicating
48 /// that the instruction is to be left unnamed (i.e. numbered, in textual IR).
49 // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer.
50 const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr();
51
52 impl BackendTypes for Builder<'_, 'll, 'tcx> {
53     type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
54     type Function = <CodegenCx<'ll, 'tcx> as BackendTypes>::Function;
55     type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
56     type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
57     type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
58
59     type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
60     type DIVariable = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIVariable;
61 }
62
63 impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {
64     fn data_layout(&self) -> &ty::layout::TargetDataLayout {
65         self.cx.data_layout()
66     }
67 }
68
69 impl ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
70     fn tcx(&self) -> TyCtxt<'tcx> {
71         self.cx.tcx
72     }
73 }
74
75 impl ty::layout::HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> {
76     fn param_env(&self) -> ty::ParamEnv<'tcx> {
77         self.cx.param_env()
78     }
79 }
80
81 impl HasTargetSpec for Builder<'_, '_, 'tcx> {
82     fn target_spec(&self) -> &Target {
83         &self.cx.target_spec()
84     }
85 }
86
87 impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
88     type Ty = Ty<'tcx>;
89     type TyLayout = TyLayout<'tcx>;
90
91     fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
92         self.cx.layout_of(ty)
93     }
94 }
95
96 impl Deref for Builder<'_, 'll, 'tcx> {
97     type Target = CodegenCx<'ll, 'tcx>;
98
99     fn deref(&self) -> &Self::Target {
100         self.cx
101     }
102 }
103
104 impl HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
105     type CodegenCx = CodegenCx<'ll, 'tcx>;
106 }
107
108 macro_rules! builder_methods_for_value_instructions {
109     ($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => {
110         $(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
111             unsafe {
112                 llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED)
113             }
114         })+
115     }
116 }
117
118 impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
119     fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
120         let mut bx = Builder::with_cx(cx);
121         let llbb = unsafe {
122             let name = SmallCStr::new(name);
123             llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr())
124         };
125         bx.position_at_end(llbb);
126         bx
127     }
128
129     fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
130         // Create a fresh builder from the crate context.
131         let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
132         Builder { llbuilder, cx }
133     }
134
135     fn build_sibling_block(&self, name: &str) -> Self {
136         Builder::new_block(self.cx, self.llfn(), name)
137     }
138
139     fn llbb(&self) -> &'ll BasicBlock {
140         unsafe { llvm::LLVMGetInsertBlock(self.llbuilder) }
141     }
142
143     fn position_at_end(&mut self, llbb: &'ll BasicBlock) {
144         unsafe {
145             llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
146         }
147     }
148
149     fn ret_void(&mut self) {
150         unsafe {
151             llvm::LLVMBuildRetVoid(self.llbuilder);
152         }
153     }
154
155     fn ret(&mut self, v: &'ll Value) {
156         unsafe {
157             llvm::LLVMBuildRet(self.llbuilder, v);
158         }
159     }
160
161     fn br(&mut self, dest: &'ll BasicBlock) {
162         unsafe {
163             llvm::LLVMBuildBr(self.llbuilder, dest);
164         }
165     }
166
167     fn cond_br(
168         &mut self,
169         cond: &'ll Value,
170         then_llbb: &'ll BasicBlock,
171         else_llbb: &'ll BasicBlock,
172     ) {
173         unsafe {
174             llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb);
175         }
176     }
177
178     fn switch(
179         &mut self,
180         v: &'ll Value,
181         else_llbb: &'ll BasicBlock,
182         cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)> + TrustedLen,
183     ) {
184         let switch =
185             unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) };
186         for (on_val, dest) in cases {
187             let on_val = self.const_uint_big(self.val_ty(v), on_val);
188             unsafe { llvm::LLVMAddCase(switch, on_val, dest) }
189         }
190     }
191
192     fn invoke(
193         &mut self,
194         llfn: &'ll Value,
195         args: &[&'ll Value],
196         then: &'ll BasicBlock,
197         catch: &'ll BasicBlock,
198         funclet: Option<&Funclet<'ll>>,
199     ) -> &'ll Value {
200         debug!("invoke {:?} with args ({:?})", llfn, args);
201
202         let args = self.check_call("invoke", llfn, args);
203         let bundle = funclet.map(|funclet| funclet.bundle());
204         let bundle = bundle.as_ref().map(|b| &*b.raw);
205
206         unsafe {
207             llvm::LLVMRustBuildInvoke(
208                 self.llbuilder,
209                 llfn,
210                 args.as_ptr(),
211                 args.len() as c_uint,
212                 then,
213                 catch,
214                 bundle,
215                 UNNAMED,
216             )
217         }
218     }
219
220     fn unreachable(&mut self) {
221         unsafe {
222             llvm::LLVMBuildUnreachable(self.llbuilder);
223         }
224     }
225
226     builder_methods_for_value_instructions! {
227         add(a, b) => LLVMBuildAdd,
228         fadd(a, b) => LLVMBuildFAdd,
229         sub(a, b) => LLVMBuildSub,
230         fsub(a, b) => LLVMBuildFSub,
231         mul(a, b) => LLVMBuildMul,
232         fmul(a, b) => LLVMBuildFMul,
233         udiv(a, b) => LLVMBuildUDiv,
234         exactudiv(a, b) => LLVMBuildExactUDiv,
235         sdiv(a, b) => LLVMBuildSDiv,
236         exactsdiv(a, b) => LLVMBuildExactSDiv,
237         fdiv(a, b) => LLVMBuildFDiv,
238         urem(a, b) => LLVMBuildURem,
239         srem(a, b) => LLVMBuildSRem,
240         frem(a, b) => LLVMBuildFRem,
241         shl(a, b) => LLVMBuildShl,
242         lshr(a, b) => LLVMBuildLShr,
243         ashr(a, b) => LLVMBuildAShr,
244         and(a, b) => LLVMBuildAnd,
245         or(a, b) => LLVMBuildOr,
246         xor(a, b) => LLVMBuildXor,
247         neg(x) => LLVMBuildNeg,
248         fneg(x) => LLVMBuildFNeg,
249         not(x) => LLVMBuildNot,
250         unchecked_sadd(x, y) => LLVMBuildNSWAdd,
251         unchecked_uadd(x, y) => LLVMBuildNUWAdd,
252         unchecked_ssub(x, y) => LLVMBuildNSWSub,
253         unchecked_usub(x, y) => LLVMBuildNUWSub,
254         unchecked_smul(x, y) => LLVMBuildNSWMul,
255         unchecked_umul(x, y) => LLVMBuildNUWMul,
256     }
257
258     fn fadd_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
259         unsafe {
260             let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
261             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
262             instr
263         }
264     }
265
266     fn fsub_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
267         unsafe {
268             let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
269             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
270             instr
271         }
272     }
273
274     fn fmul_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
275         unsafe {
276             let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
277             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
278             instr
279         }
280     }
281
282     fn fdiv_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
283         unsafe {
284             let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
285             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
286             instr
287         }
288     }
289
290     fn frem_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
291         unsafe {
292             let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
293             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
294             instr
295         }
296     }
297
298     fn checked_binop(
299         &mut self,
300         oop: OverflowOp,
301         ty: Ty<'_>,
302         lhs: Self::Value,
303         rhs: Self::Value,
304     ) -> (Self::Value, Self::Value) {
305         use rustc::ty::{Int, Uint};
306         use syntax::ast::IntTy::*;
307         use syntax::ast::UintTy::*;
308
309         let new_kind = match ty.kind {
310             Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.ptr_width)),
311             Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.ptr_width)),
312             ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
313             _ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
314         };
315
316         let name = match oop {
317             OverflowOp::Add => match new_kind {
318                 Int(I8) => "llvm.sadd.with.overflow.i8",
319                 Int(I16) => "llvm.sadd.with.overflow.i16",
320                 Int(I32) => "llvm.sadd.with.overflow.i32",
321                 Int(I64) => "llvm.sadd.with.overflow.i64",
322                 Int(I128) => "llvm.sadd.with.overflow.i128",
323
324                 Uint(U8) => "llvm.uadd.with.overflow.i8",
325                 Uint(U16) => "llvm.uadd.with.overflow.i16",
326                 Uint(U32) => "llvm.uadd.with.overflow.i32",
327                 Uint(U64) => "llvm.uadd.with.overflow.i64",
328                 Uint(U128) => "llvm.uadd.with.overflow.i128",
329
330                 _ => unreachable!(),
331             },
332             OverflowOp::Sub => match new_kind {
333                 Int(I8) => "llvm.ssub.with.overflow.i8",
334                 Int(I16) => "llvm.ssub.with.overflow.i16",
335                 Int(I32) => "llvm.ssub.with.overflow.i32",
336                 Int(I64) => "llvm.ssub.with.overflow.i64",
337                 Int(I128) => "llvm.ssub.with.overflow.i128",
338
339                 Uint(U8) => "llvm.usub.with.overflow.i8",
340                 Uint(U16) => "llvm.usub.with.overflow.i16",
341                 Uint(U32) => "llvm.usub.with.overflow.i32",
342                 Uint(U64) => "llvm.usub.with.overflow.i64",
343                 Uint(U128) => "llvm.usub.with.overflow.i128",
344
345                 _ => unreachable!(),
346             },
347             OverflowOp::Mul => match new_kind {
348                 Int(I8) => "llvm.smul.with.overflow.i8",
349                 Int(I16) => "llvm.smul.with.overflow.i16",
350                 Int(I32) => "llvm.smul.with.overflow.i32",
351                 Int(I64) => "llvm.smul.with.overflow.i64",
352                 Int(I128) => "llvm.smul.with.overflow.i128",
353
354                 Uint(U8) => "llvm.umul.with.overflow.i8",
355                 Uint(U16) => "llvm.umul.with.overflow.i16",
356                 Uint(U32) => "llvm.umul.with.overflow.i32",
357                 Uint(U64) => "llvm.umul.with.overflow.i64",
358                 Uint(U128) => "llvm.umul.with.overflow.i128",
359
360                 _ => unreachable!(),
361             },
362         };
363
364         let intrinsic = self.get_intrinsic(&name);
365         let res = self.call(intrinsic, &[lhs, rhs], None);
366         (self.extract_value(res, 0), self.extract_value(res, 1))
367     }
368
369     fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
370         let mut bx = Builder::with_cx(self.cx);
371         bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) });
372         bx.dynamic_alloca(ty, align)
373     }
374
375     fn dynamic_alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
376         unsafe {
377             let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED);
378             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
379             alloca
380         }
381     }
382
383     fn array_alloca(&mut self, ty: &'ll Type, len: &'ll Value, align: Align) -> &'ll Value {
384         unsafe {
385             let alloca = llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED);
386             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
387             alloca
388         }
389     }
390
391     fn load(&mut self, ptr: &'ll Value, align: Align) -> &'ll Value {
392         unsafe {
393             let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
394             llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
395             load
396         }
397     }
398
399     fn volatile_load(&mut self, ptr: &'ll Value) -> &'ll Value {
400         unsafe {
401             let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
402             llvm::LLVMSetVolatile(load, llvm::True);
403             load
404         }
405     }
406
407     fn atomic_load(
408         &mut self,
409         ptr: &'ll Value,
410         order: rustc_codegen_ssa::common::AtomicOrdering,
411         size: Size,
412     ) -> &'ll Value {
413         unsafe {
414             let load = llvm::LLVMRustBuildAtomicLoad(
415                 self.llbuilder,
416                 ptr,
417                 UNNAMED,
418                 AtomicOrdering::from_generic(order),
419             );
420             // LLVM requires the alignment of atomic loads to be at least the size of the type.
421             llvm::LLVMSetAlignment(load, size.bytes() as c_uint);
422             load
423         }
424     }
425
426     fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> {
427         debug!("PlaceRef::load: {:?}", place);
428
429         assert_eq!(place.llextra.is_some(), place.layout.is_unsized());
430
431         if place.layout.is_zst() {
432             return OperandRef::new_zst(self, place.layout);
433         }
434
435         fn scalar_load_metadata<'a, 'll, 'tcx>(
436             bx: &mut Builder<'a, 'll, 'tcx>,
437             load: &'ll Value,
438             scalar: &layout::Scalar,
439         ) {
440             let vr = scalar.valid_range.clone();
441             match scalar.value {
442                 layout::Int(..) => {
443                     let range = scalar.valid_range_exclusive(bx);
444                     if range.start != range.end {
445                         bx.range_metadata(load, range);
446                     }
447                 }
448                 layout::Pointer if vr.start() < vr.end() && !vr.contains(&0) => {
449                     bx.nonnull_metadata(load);
450                 }
451                 _ => {}
452             }
453         }
454
455         let val = if let Some(llextra) = place.llextra {
456             OperandValue::Ref(place.llval, Some(llextra), place.align)
457         } else if place.layout.is_llvm_immediate() {
458             let mut const_llval = None;
459             unsafe {
460                 if let Some(global) = llvm::LLVMIsAGlobalVariable(place.llval) {
461                     if llvm::LLVMIsGlobalConstant(global) == llvm::True {
462                         const_llval = llvm::LLVMGetInitializer(global);
463                     }
464                 }
465             }
466             let llval = const_llval.unwrap_or_else(|| {
467                 let load = self.load(place.llval, place.align);
468                 if let layout::Abi::Scalar(ref scalar) = place.layout.abi {
469                     scalar_load_metadata(self, load, scalar);
470                 }
471                 load
472             });
473             OperandValue::Immediate(to_immediate(self, llval, place.layout))
474         } else if let layout::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
475             let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
476
477             let mut load = |i, scalar: &layout::Scalar, align| {
478                 let llptr = self.struct_gep(place.llval, i as u64);
479                 let load = self.load(llptr, align);
480                 scalar_load_metadata(self, load, scalar);
481                 if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load }
482             };
483
484             OperandValue::Pair(
485                 load(0, a, place.align),
486                 load(1, b, place.align.restrict_for_offset(b_offset)),
487             )
488         } else {
489             OperandValue::Ref(place.llval, None, place.align)
490         };
491
492         OperandRef { val, layout: place.layout }
493     }
494
495     fn write_operand_repeatedly(
496         mut self,
497         cg_elem: OperandRef<'tcx, &'ll Value>,
498         count: u64,
499         dest: PlaceRef<'tcx, &'ll Value>,
500     ) -> Self {
501         let zero = self.const_usize(0);
502         let count = self.const_usize(count);
503         let start = dest.project_index(&mut self, zero).llval;
504         let end = dest.project_index(&mut self, count).llval;
505
506         let mut header_bx = self.build_sibling_block("repeat_loop_header");
507         let mut body_bx = self.build_sibling_block("repeat_loop_body");
508         let next_bx = self.build_sibling_block("repeat_loop_next");
509
510         self.br(header_bx.llbb());
511         let current = header_bx.phi(self.val_ty(start), &[start], &[self.llbb()]);
512
513         let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
514         header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
515
516         let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
517         cg_elem
518             .val
519             .store(&mut body_bx, PlaceRef::new_sized_aligned(current, cg_elem.layout, align));
520
521         let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
522         body_bx.br(header_bx.llbb());
523         header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
524
525         next_bx
526     }
527
528     fn range_metadata(&mut self, load: &'ll Value, range: Range<u128>) {
529         if self.sess().target.target.arch == "amdgpu" {
530             // amdgpu/LLVM does something weird and thinks a i64 value is
531             // split into a v2i32, halving the bitwidth LLVM expects,
532             // tripping an assertion. So, for now, just disable this
533             // optimization.
534             return;
535         }
536
537         unsafe {
538             let llty = self.cx.val_ty(load);
539             let v = [
540                 self.cx.const_uint_big(llty, range.start),
541                 self.cx.const_uint_big(llty, range.end),
542             ];
543
544             llvm::LLVMSetMetadata(
545                 load,
546                 llvm::MD_range as c_uint,
547                 llvm::LLVMMDNodeInContext(self.cx.llcx, v.as_ptr(), v.len() as c_uint),
548             );
549         }
550     }
551
552     fn nonnull_metadata(&mut self, load: &'ll Value) {
553         unsafe {
554             llvm::LLVMSetMetadata(
555                 load,
556                 llvm::MD_nonnull as c_uint,
557                 llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0),
558             );
559         }
560     }
561
562     fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
563         self.store_with_flags(val, ptr, align, MemFlags::empty())
564     }
565
566     fn store_with_flags(
567         &mut self,
568         val: &'ll Value,
569         ptr: &'ll Value,
570         align: Align,
571         flags: MemFlags,
572     ) -> &'ll Value {
573         debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags);
574         let ptr = self.check_store(val, ptr);
575         unsafe {
576             let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
577             let align =
578                 if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() as c_uint };
579             llvm::LLVMSetAlignment(store, align);
580             if flags.contains(MemFlags::VOLATILE) {
581                 llvm::LLVMSetVolatile(store, llvm::True);
582             }
583             if flags.contains(MemFlags::NONTEMPORAL) {
584                 // According to LLVM [1] building a nontemporal store must
585                 // *always* point to a metadata value of the integer 1.
586                 //
587                 // [1]: http://llvm.org/docs/LangRef.html#store-instruction
588                 let one = self.cx.const_i32(1);
589                 let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
590                 llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
591             }
592             store
593         }
594     }
595
596     fn atomic_store(
597         &mut self,
598         val: &'ll Value,
599         ptr: &'ll Value,
600         order: rustc_codegen_ssa::common::AtomicOrdering,
601         size: Size,
602     ) {
603         debug!("Store {:?} -> {:?}", val, ptr);
604         let ptr = self.check_store(val, ptr);
605         unsafe {
606             let store = llvm::LLVMRustBuildAtomicStore(
607                 self.llbuilder,
608                 val,
609                 ptr,
610                 AtomicOrdering::from_generic(order),
611             );
612             // LLVM requires the alignment of atomic stores to be at least the size of the type.
613             llvm::LLVMSetAlignment(store, size.bytes() as c_uint);
614         }
615     }
616
617     fn gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
618         unsafe {
619             llvm::LLVMBuildGEP(
620                 self.llbuilder,
621                 ptr,
622                 indices.as_ptr(),
623                 indices.len() as c_uint,
624                 UNNAMED,
625             )
626         }
627     }
628
629     fn inbounds_gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
630         unsafe {
631             llvm::LLVMBuildInBoundsGEP(
632                 self.llbuilder,
633                 ptr,
634                 indices.as_ptr(),
635                 indices.len() as c_uint,
636                 UNNAMED,
637             )
638         }
639     }
640
641     fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value {
642         assert_eq!(idx as c_uint as u64, idx);
643         unsafe { llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED) }
644     }
645
646     /* Casts */
647     fn trunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
648         unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) }
649     }
650
651     fn sext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
652         unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) }
653     }
654
655     fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
656         unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) }
657     }
658
659     fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
660         unsafe { llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty, UNNAMED) }
661     }
662
663     fn uitofp(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
664         unsafe { llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, UNNAMED) }
665     }
666
667     fn sitofp(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
668         unsafe { llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, UNNAMED) }
669     }
670
671     fn fptrunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
672         unsafe { llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, UNNAMED) }
673     }
674
675     fn fpext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
676         unsafe { llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, UNNAMED) }
677     }
678
679     fn ptrtoint(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
680         unsafe { llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, UNNAMED) }
681     }
682
683     fn inttoptr(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
684         unsafe { llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, UNNAMED) }
685     }
686
687     fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
688         unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) }
689     }
690
691     fn intcast(&mut self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
692         unsafe { llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed) }
693     }
694
695     fn pointercast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
696         unsafe { llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, UNNAMED) }
697     }
698
699     /* Comparisons */
700     fn icmp(&mut self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
701         let op = llvm::IntPredicate::from_generic(op);
702         unsafe { llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) }
703     }
704
705     fn fcmp(&mut self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
706         unsafe { llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) }
707     }
708
709     /* Miscellaneous instructions */
710     fn memcpy(
711         &mut self,
712         dst: &'ll Value,
713         dst_align: Align,
714         src: &'ll Value,
715         src_align: Align,
716         size: &'ll Value,
717         flags: MemFlags,
718     ) {
719         if flags.contains(MemFlags::NONTEMPORAL) {
720             // HACK(nox): This is inefficient but there is no nontemporal memcpy.
721             let val = self.load(src, src_align);
722             let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val)));
723             self.store_with_flags(val, ptr, dst_align, flags);
724             return;
725         }
726         let size = self.intcast(size, self.type_isize(), false);
727         let is_volatile = flags.contains(MemFlags::VOLATILE);
728         let dst = self.pointercast(dst, self.type_i8p());
729         let src = self.pointercast(src, self.type_i8p());
730         unsafe {
731             llvm::LLVMRustBuildMemCpy(
732                 self.llbuilder,
733                 dst,
734                 dst_align.bytes() as c_uint,
735                 src,
736                 src_align.bytes() as c_uint,
737                 size,
738                 is_volatile,
739             );
740         }
741     }
742
743     fn memmove(
744         &mut self,
745         dst: &'ll Value,
746         dst_align: Align,
747         src: &'ll Value,
748         src_align: Align,
749         size: &'ll Value,
750         flags: MemFlags,
751     ) {
752         if flags.contains(MemFlags::NONTEMPORAL) {
753             // HACK(nox): This is inefficient but there is no nontemporal memmove.
754             let val = self.load(src, src_align);
755             let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val)));
756             self.store_with_flags(val, ptr, dst_align, flags);
757             return;
758         }
759         let size = self.intcast(size, self.type_isize(), false);
760         let is_volatile = flags.contains(MemFlags::VOLATILE);
761         let dst = self.pointercast(dst, self.type_i8p());
762         let src = self.pointercast(src, self.type_i8p());
763         unsafe {
764             llvm::LLVMRustBuildMemMove(
765                 self.llbuilder,
766                 dst,
767                 dst_align.bytes() as c_uint,
768                 src,
769                 src_align.bytes() as c_uint,
770                 size,
771                 is_volatile,
772             );
773         }
774     }
775
776     fn memset(
777         &mut self,
778         ptr: &'ll Value,
779         fill_byte: &'ll Value,
780         size: &'ll Value,
781         align: Align,
782         flags: MemFlags,
783     ) {
784         let ptr_width = &self.sess().target.target.target_pointer_width;
785         let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
786         let llintrinsicfn = self.get_intrinsic(&intrinsic_key);
787         let ptr = self.pointercast(ptr, self.type_i8p());
788         let align = self.const_u32(align.bytes() as u32);
789         let volatile = self.const_bool(flags.contains(MemFlags::VOLATILE));
790         self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None);
791     }
792
793     fn select(
794         &mut self,
795         cond: &'ll Value,
796         then_val: &'ll Value,
797         else_val: &'ll Value,
798     ) -> &'ll Value {
799         unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) }
800     }
801
802     #[allow(dead_code)]
803     fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
804         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
805     }
806
807     fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
808         unsafe { llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, UNNAMED) }
809     }
810
811     fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
812         unsafe {
813             let elt_ty = self.cx.val_ty(elt);
814             let undef = llvm::LLVMGetUndef(self.type_vector(elt_ty, num_elts as u64));
815             let vec = self.insert_element(undef, elt, self.cx.const_i32(0));
816             let vec_i32_ty = self.type_vector(self.type_i32(), num_elts as u64);
817             self.shuffle_vector(vec, undef, self.const_null(vec_i32_ty))
818         }
819     }
820
821     fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
822         assert_eq!(idx as c_uint as u64, idx);
823         unsafe { llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED) }
824     }
825
826     fn insert_value(&mut self, agg_val: &'ll Value, elt: &'ll Value, idx: u64) -> &'ll Value {
827         assert_eq!(idx as c_uint as u64, idx);
828         unsafe { llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint, UNNAMED) }
829     }
830
831     fn landing_pad(
832         &mut self,
833         ty: &'ll Type,
834         pers_fn: &'ll Value,
835         num_clauses: usize,
836     ) -> &'ll Value {
837         unsafe {
838             llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, num_clauses as c_uint, UNNAMED)
839         }
840     }
841
842     fn set_cleanup(&mut self, landing_pad: &'ll Value) {
843         unsafe {
844             llvm::LLVMSetCleanup(landing_pad, llvm::True);
845         }
846     }
847
848     fn resume(&mut self, exn: &'ll Value) -> &'ll Value {
849         unsafe { llvm::LLVMBuildResume(self.llbuilder, exn) }
850     }
851
852     fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
853         let name = const_cstr!("cleanuppad");
854         let ret = unsafe {
855             llvm::LLVMRustBuildCleanupPad(
856                 self.llbuilder,
857                 parent,
858                 args.len() as c_uint,
859                 args.as_ptr(),
860                 name.as_ptr(),
861             )
862         };
863         Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
864     }
865
866     fn cleanup_ret(
867         &mut self,
868         funclet: &Funclet<'ll>,
869         unwind: Option<&'ll BasicBlock>,
870     ) -> &'ll Value {
871         let ret =
872             unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) };
873         ret.expect("LLVM does not have support for cleanupret")
874     }
875
876     fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
877         let name = const_cstr!("catchpad");
878         let ret = unsafe {
879             llvm::LLVMRustBuildCatchPad(
880                 self.llbuilder,
881                 parent,
882                 args.len() as c_uint,
883                 args.as_ptr(),
884                 name.as_ptr(),
885             )
886         };
887         Funclet::new(ret.expect("LLVM does not have support for catchpad"))
888     }
889
890     fn catch_switch(
891         &mut self,
892         parent: Option<&'ll Value>,
893         unwind: Option<&'ll BasicBlock>,
894         num_handlers: usize,
895     ) -> &'ll Value {
896         let name = const_cstr!("catchswitch");
897         let ret = unsafe {
898             llvm::LLVMRustBuildCatchSwitch(
899                 self.llbuilder,
900                 parent,
901                 unwind,
902                 num_handlers as c_uint,
903                 name.as_ptr(),
904             )
905         };
906         ret.expect("LLVM does not have support for catchswitch")
907     }
908
909     fn add_handler(&mut self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
910         unsafe {
911             llvm::LLVMRustAddHandler(catch_switch, handler);
912         }
913     }
914
915     fn set_personality_fn(&mut self, personality: &'ll Value) {
916         unsafe {
917             llvm::LLVMSetPersonalityFn(self.llfn(), personality);
918         }
919     }
920
921     // Atomic Operations
922     fn atomic_cmpxchg(
923         &mut self,
924         dst: &'ll Value,
925         cmp: &'ll Value,
926         src: &'ll Value,
927         order: rustc_codegen_ssa::common::AtomicOrdering,
928         failure_order: rustc_codegen_ssa::common::AtomicOrdering,
929         weak: bool,
930     ) -> &'ll Value {
931         let weak = if weak { llvm::True } else { llvm::False };
932         unsafe {
933             llvm::LLVMRustBuildAtomicCmpXchg(
934                 self.llbuilder,
935                 dst,
936                 cmp,
937                 src,
938                 AtomicOrdering::from_generic(order),
939                 AtomicOrdering::from_generic(failure_order),
940                 weak,
941             )
942         }
943     }
944     fn atomic_rmw(
945         &mut self,
946         op: rustc_codegen_ssa::common::AtomicRmwBinOp,
947         dst: &'ll Value,
948         src: &'ll Value,
949         order: rustc_codegen_ssa::common::AtomicOrdering,
950     ) -> &'ll Value {
951         unsafe {
952             llvm::LLVMBuildAtomicRMW(
953                 self.llbuilder,
954                 AtomicRmwBinOp::from_generic(op),
955                 dst,
956                 src,
957                 AtomicOrdering::from_generic(order),
958                 False,
959             )
960         }
961     }
962
963     fn atomic_fence(
964         &mut self,
965         order: rustc_codegen_ssa::common::AtomicOrdering,
966         scope: rustc_codegen_ssa::common::SynchronizationScope,
967     ) {
968         unsafe {
969             llvm::LLVMRustBuildAtomicFence(
970                 self.llbuilder,
971                 AtomicOrdering::from_generic(order),
972                 SynchronizationScope::from_generic(scope),
973             );
974         }
975     }
976
977     fn set_invariant_load(&mut self, load: &'ll Value) {
978         unsafe {
979             llvm::LLVMSetMetadata(
980                 load,
981                 llvm::MD_invariant_load as c_uint,
982                 llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0),
983             );
984         }
985     }
986
987     fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) {
988         self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
989     }
990
991     fn lifetime_end(&mut self, ptr: &'ll Value, size: Size) {
992         self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
993     }
994
995     fn call(
996         &mut self,
997         llfn: &'ll Value,
998         args: &[&'ll Value],
999         funclet: Option<&Funclet<'ll>>,
1000     ) -> &'ll Value {
1001         debug!("call {:?} with args ({:?})", llfn, args);
1002
1003         let args = self.check_call("call", llfn, args);
1004         let bundle = funclet.map(|funclet| funclet.bundle());
1005         let bundle = bundle.as_ref().map(|b| &*b.raw);
1006
1007         unsafe {
1008             llvm::LLVMRustBuildCall(
1009                 self.llbuilder,
1010                 llfn,
1011                 args.as_ptr() as *const &llvm::Value,
1012                 args.len() as c_uint,
1013                 bundle,
1014                 UNNAMED,
1015             )
1016         }
1017     }
1018
1019     fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
1020         unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
1021     }
1022
1023     fn cx(&self) -> &CodegenCx<'ll, 'tcx> {
1024         self.cx
1025     }
1026
1027     unsafe fn delete_basic_block(&mut self, bb: &'ll BasicBlock) {
1028         llvm::LLVMDeleteBasicBlock(bb);
1029     }
1030
1031     fn do_not_inline(&mut self, llret: &'ll Value) {
1032         llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
1033     }
1034 }
1035
1036 impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
1037     fn get_static(&mut self, def_id: DefId) -> &'ll Value {
1038         // Forward to the `get_static` method of `CodegenCx`
1039         self.cx().get_static(def_id)
1040     }
1041 }
1042
1043 impl Builder<'a, 'll, 'tcx> {
1044     pub fn llfn(&self) -> &'ll Value {
1045         unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
1046     }
1047
1048     fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
1049         unsafe {
1050             llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
1051         }
1052     }
1053
1054     pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
1055         unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
1056     }
1057
1058     pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
1059         unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
1060     }
1061
1062     pub fn insert_element(
1063         &mut self,
1064         vec: &'ll Value,
1065         elt: &'ll Value,
1066         idx: &'ll Value,
1067     ) -> &'ll Value {
1068         unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) }
1069     }
1070
1071     pub fn shuffle_vector(
1072         &mut self,
1073         v1: &'ll Value,
1074         v2: &'ll Value,
1075         mask: &'ll Value,
1076     ) -> &'ll Value {
1077         unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) }
1078     }
1079
1080     pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1081         unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
1082     }
1083     pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1084         unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
1085     }
1086     pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1087         unsafe {
1088             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
1089             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1090             instr
1091         }
1092     }
1093     pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1094         unsafe {
1095             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
1096             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1097             instr
1098         }
1099     }
1100     pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
1101         unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
1102     }
1103     pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
1104         unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
1105     }
1106     pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
1107         unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
1108     }
1109     pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
1110         unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
1111     }
1112     pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
1113         unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
1114     }
1115     pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
1116         unsafe {
1117             llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false)
1118         }
1119     }
1120     pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
1121         unsafe {
1122             llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false)
1123         }
1124     }
1125     pub fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value {
1126         unsafe {
1127             let instr =
1128                 llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
1129             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1130             instr
1131         }
1132     }
1133     pub fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value {
1134         unsafe {
1135             let instr =
1136                 llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
1137             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1138             instr
1139         }
1140     }
1141     pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
1142         unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
1143     }
1144     pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
1145         unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
1146     }
1147
1148     pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
1149         unsafe {
1150             llvm::LLVMAddClause(landing_pad, clause);
1151         }
1152     }
1153
1154     pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
1155         let ret =
1156             unsafe { llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
1157         ret.expect("LLVM does not have support for catchret")
1158     }
1159
1160     fn check_store(&mut self, val: &'ll Value, ptr: &'ll Value) -> &'ll Value {
1161         let dest_ptr_ty = self.cx.val_ty(ptr);
1162         let stored_ty = self.cx.val_ty(val);
1163         let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
1164
1165         assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer);
1166
1167         if dest_ptr_ty == stored_ptr_ty {
1168             ptr
1169         } else {
1170             debug!(
1171                 "type mismatch in store. \
1172                     Expected {:?}, got {:?}; inserting bitcast",
1173                 dest_ptr_ty, stored_ptr_ty
1174             );
1175             self.bitcast(ptr, stored_ptr_ty)
1176         }
1177     }
1178
1179     fn check_call<'b>(
1180         &mut self,
1181         typ: &str,
1182         llfn: &'ll Value,
1183         args: &'b [&'ll Value],
1184     ) -> Cow<'b, [&'ll Value]> {
1185         let mut fn_ty = self.cx.val_ty(llfn);
1186         // Strip off pointers
1187         while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
1188             fn_ty = self.cx.element_type(fn_ty);
1189         }
1190
1191         assert!(
1192             self.cx.type_kind(fn_ty) == TypeKind::Function,
1193             "builder::{} not passed a function, but {:?}",
1194             typ,
1195             fn_ty
1196         );
1197
1198         let param_tys = self.cx.func_params_types(fn_ty);
1199
1200         let all_args_match = param_tys
1201             .iter()
1202             .zip(args.iter().map(|&v| self.val_ty(v)))
1203             .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
1204
1205         if all_args_match {
1206             return Cow::Borrowed(args);
1207         }
1208
1209         let casted_args: Vec<_> = param_tys
1210             .into_iter()
1211             .zip(args.iter())
1212             .enumerate()
1213             .map(|(i, (expected_ty, &actual_val))| {
1214                 let actual_ty = self.val_ty(actual_val);
1215                 if expected_ty != actual_ty {
1216                     debug!(
1217                         "type mismatch in function call of {:?}. \
1218                             Expected {:?} for param {}, got {:?}; injecting bitcast",
1219                         llfn, expected_ty, i, actual_ty
1220                     );
1221                     self.bitcast(actual_val, expected_ty)
1222                 } else {
1223                     actual_val
1224                 }
1225             })
1226             .collect();
1227
1228         Cow::Owned(casted_args)
1229     }
1230
1231     pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
1232         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
1233     }
1234
1235     fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
1236         let size = size.bytes();
1237         if size == 0 {
1238             return;
1239         }
1240
1241         let opts = &self.cx.sess().opts;
1242         let emit = match opts.debugging_opts.sanitizer {
1243             // Some sanitizer use lifetime intrinsics. When they are in use,
1244             // emit lifetime intrinsics regardless of optimization level.
1245             Some(Sanitizer::Address) | Some(Sanitizer::Memory) => true,
1246             _ => opts.optimize != config::OptLevel::No,
1247         };
1248         if !emit {
1249             return;
1250         }
1251
1252         let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1253
1254         let ptr = self.pointercast(ptr, self.cx.type_i8p());
1255         self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
1256     }
1257
1258     fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
1259         assert_eq!(vals.len(), bbs.len());
1260         let phi = unsafe { llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED) };
1261         unsafe {
1262             llvm::LLVMAddIncoming(phi, vals.as_ptr(), bbs.as_ptr(), vals.len() as c_uint);
1263             phi
1264         }
1265     }
1266
1267     fn add_incoming_to_phi(&mut self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
1268         unsafe {
1269             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
1270         }
1271     }
1272 }