]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/builder.rs
Rollup merge of #69747 - spastorino:rename-rustc-guide, r=pietroalbini
[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 rustc_ast::ast::IntTy::*;
307         use rustc_ast::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 is_volatile = flags.contains(MemFlags::VOLATILE);
785         let ptr = self.pointercast(ptr, self.type_i8p());
786         unsafe {
787             llvm::LLVMRustBuildMemSet(
788                 self.llbuilder,
789                 ptr,
790                 align.bytes() as c_uint,
791                 fill_byte,
792                 size,
793                 is_volatile,
794             );
795         }
796     }
797
798     fn select(
799         &mut self,
800         cond: &'ll Value,
801         then_val: &'ll Value,
802         else_val: &'ll Value,
803     ) -> &'ll Value {
804         unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) }
805     }
806
807     #[allow(dead_code)]
808     fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
809         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
810     }
811
812     fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
813         unsafe { llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, UNNAMED) }
814     }
815
816     fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
817         unsafe {
818             let elt_ty = self.cx.val_ty(elt);
819             let undef = llvm::LLVMGetUndef(self.type_vector(elt_ty, num_elts as u64));
820             let vec = self.insert_element(undef, elt, self.cx.const_i32(0));
821             let vec_i32_ty = self.type_vector(self.type_i32(), num_elts as u64);
822             self.shuffle_vector(vec, undef, self.const_null(vec_i32_ty))
823         }
824     }
825
826     fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
827         assert_eq!(idx as c_uint as u64, idx);
828         unsafe { llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED) }
829     }
830
831     fn insert_value(&mut self, agg_val: &'ll Value, elt: &'ll Value, idx: u64) -> &'ll Value {
832         assert_eq!(idx as c_uint as u64, idx);
833         unsafe { llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint, UNNAMED) }
834     }
835
836     fn landing_pad(
837         &mut self,
838         ty: &'ll Type,
839         pers_fn: &'ll Value,
840         num_clauses: usize,
841     ) -> &'ll Value {
842         unsafe {
843             llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, num_clauses as c_uint, UNNAMED)
844         }
845     }
846
847     fn set_cleanup(&mut self, landing_pad: &'ll Value) {
848         unsafe {
849             llvm::LLVMSetCleanup(landing_pad, llvm::True);
850         }
851     }
852
853     fn resume(&mut self, exn: &'ll Value) -> &'ll Value {
854         unsafe { llvm::LLVMBuildResume(self.llbuilder, exn) }
855     }
856
857     fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> {
858         let name = const_cstr!("cleanuppad");
859         let ret = unsafe {
860             llvm::LLVMRustBuildCleanupPad(
861                 self.llbuilder,
862                 parent,
863                 args.len() as c_uint,
864                 args.as_ptr(),
865                 name.as_ptr(),
866             )
867         };
868         Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
869     }
870
871     fn cleanup_ret(
872         &mut self,
873         funclet: &Funclet<'ll>,
874         unwind: Option<&'ll BasicBlock>,
875     ) -> &'ll Value {
876         let ret =
877             unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) };
878         ret.expect("LLVM does not have support for cleanupret")
879     }
880
881     fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> {
882         let name = const_cstr!("catchpad");
883         let ret = unsafe {
884             llvm::LLVMRustBuildCatchPad(
885                 self.llbuilder,
886                 parent,
887                 args.len() as c_uint,
888                 args.as_ptr(),
889                 name.as_ptr(),
890             )
891         };
892         Funclet::new(ret.expect("LLVM does not have support for catchpad"))
893     }
894
895     fn catch_switch(
896         &mut self,
897         parent: Option<&'ll Value>,
898         unwind: Option<&'ll BasicBlock>,
899         num_handlers: usize,
900     ) -> &'ll Value {
901         let name = const_cstr!("catchswitch");
902         let ret = unsafe {
903             llvm::LLVMRustBuildCatchSwitch(
904                 self.llbuilder,
905                 parent,
906                 unwind,
907                 num_handlers as c_uint,
908                 name.as_ptr(),
909             )
910         };
911         ret.expect("LLVM does not have support for catchswitch")
912     }
913
914     fn add_handler(&mut self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
915         unsafe {
916             llvm::LLVMRustAddHandler(catch_switch, handler);
917         }
918     }
919
920     fn set_personality_fn(&mut self, personality: &'ll Value) {
921         unsafe {
922             llvm::LLVMSetPersonalityFn(self.llfn(), personality);
923         }
924     }
925
926     // Atomic Operations
927     fn atomic_cmpxchg(
928         &mut self,
929         dst: &'ll Value,
930         cmp: &'ll Value,
931         src: &'ll Value,
932         order: rustc_codegen_ssa::common::AtomicOrdering,
933         failure_order: rustc_codegen_ssa::common::AtomicOrdering,
934         weak: bool,
935     ) -> &'ll Value {
936         let weak = if weak { llvm::True } else { llvm::False };
937         unsafe {
938             llvm::LLVMRustBuildAtomicCmpXchg(
939                 self.llbuilder,
940                 dst,
941                 cmp,
942                 src,
943                 AtomicOrdering::from_generic(order),
944                 AtomicOrdering::from_generic(failure_order),
945                 weak,
946             )
947         }
948     }
949     fn atomic_rmw(
950         &mut self,
951         op: rustc_codegen_ssa::common::AtomicRmwBinOp,
952         dst: &'ll Value,
953         src: &'ll Value,
954         order: rustc_codegen_ssa::common::AtomicOrdering,
955     ) -> &'ll Value {
956         unsafe {
957             llvm::LLVMBuildAtomicRMW(
958                 self.llbuilder,
959                 AtomicRmwBinOp::from_generic(op),
960                 dst,
961                 src,
962                 AtomicOrdering::from_generic(order),
963                 False,
964             )
965         }
966     }
967
968     fn atomic_fence(
969         &mut self,
970         order: rustc_codegen_ssa::common::AtomicOrdering,
971         scope: rustc_codegen_ssa::common::SynchronizationScope,
972     ) {
973         unsafe {
974             llvm::LLVMRustBuildAtomicFence(
975                 self.llbuilder,
976                 AtomicOrdering::from_generic(order),
977                 SynchronizationScope::from_generic(scope),
978             );
979         }
980     }
981
982     fn set_invariant_load(&mut self, load: &'ll Value) {
983         unsafe {
984             llvm::LLVMSetMetadata(
985                 load,
986                 llvm::MD_invariant_load as c_uint,
987                 llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0),
988             );
989         }
990     }
991
992     fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) {
993         self.call_lifetime_intrinsic("llvm.lifetime.start.p0i8", ptr, size);
994     }
995
996     fn lifetime_end(&mut self, ptr: &'ll Value, size: Size) {
997         self.call_lifetime_intrinsic("llvm.lifetime.end.p0i8", ptr, size);
998     }
999
1000     fn call(
1001         &mut self,
1002         llfn: &'ll Value,
1003         args: &[&'ll Value],
1004         funclet: Option<&Funclet<'ll>>,
1005     ) -> &'ll Value {
1006         debug!("call {:?} with args ({:?})", llfn, args);
1007
1008         let args = self.check_call("call", llfn, args);
1009         let bundle = funclet.map(|funclet| funclet.bundle());
1010         let bundle = bundle.as_ref().map(|b| &*b.raw);
1011
1012         unsafe {
1013             llvm::LLVMRustBuildCall(
1014                 self.llbuilder,
1015                 llfn,
1016                 args.as_ptr() as *const &llvm::Value,
1017                 args.len() as c_uint,
1018                 bundle,
1019             )
1020         }
1021     }
1022
1023     fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
1024         unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
1025     }
1026
1027     fn cx(&self) -> &CodegenCx<'ll, 'tcx> {
1028         self.cx
1029     }
1030
1031     unsafe fn delete_basic_block(&mut self, bb: &'ll BasicBlock) {
1032         llvm::LLVMDeleteBasicBlock(bb);
1033     }
1034
1035     fn do_not_inline(&mut self, llret: &'ll Value) {
1036         llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
1037     }
1038 }
1039
1040 impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
1041     fn get_static(&mut self, def_id: DefId) -> &'ll Value {
1042         // Forward to the `get_static` method of `CodegenCx`
1043         self.cx().get_static(def_id)
1044     }
1045 }
1046
1047 impl Builder<'a, 'll, 'tcx> {
1048     pub fn llfn(&self) -> &'ll Value {
1049         unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
1050     }
1051
1052     fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
1053         unsafe {
1054             llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
1055         }
1056     }
1057
1058     pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
1059         unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
1060     }
1061
1062     pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
1063         unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
1064     }
1065
1066     pub fn insert_element(
1067         &mut self,
1068         vec: &'ll Value,
1069         elt: &'ll Value,
1070         idx: &'ll Value,
1071     ) -> &'ll Value {
1072         unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) }
1073     }
1074
1075     pub fn shuffle_vector(
1076         &mut self,
1077         v1: &'ll Value,
1078         v2: &'ll Value,
1079         mask: &'ll Value,
1080     ) -> &'ll Value {
1081         unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) }
1082     }
1083
1084     pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1085         unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
1086     }
1087     pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1088         unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
1089     }
1090     pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1091         unsafe {
1092             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
1093             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1094             instr
1095         }
1096     }
1097     pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1098         unsafe {
1099             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
1100             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1101             instr
1102         }
1103     }
1104     pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
1105         unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
1106     }
1107     pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
1108         unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
1109     }
1110     pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
1111         unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
1112     }
1113     pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
1114         unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
1115     }
1116     pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
1117         unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
1118     }
1119     pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
1120         unsafe {
1121             llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false)
1122         }
1123     }
1124     pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
1125         unsafe {
1126             llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false)
1127         }
1128     }
1129     pub fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value {
1130         unsafe {
1131             let instr =
1132                 llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
1133             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1134             instr
1135         }
1136     }
1137     pub fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value {
1138         unsafe {
1139             let instr =
1140                 llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
1141             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1142             instr
1143         }
1144     }
1145     pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
1146         unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
1147     }
1148     pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
1149         unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
1150     }
1151
1152     pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
1153         unsafe {
1154             llvm::LLVMAddClause(landing_pad, clause);
1155         }
1156     }
1157
1158     pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
1159         let ret =
1160             unsafe { llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) };
1161         ret.expect("LLVM does not have support for catchret")
1162     }
1163
1164     fn check_store(&mut self, val: &'ll Value, ptr: &'ll Value) -> &'ll Value {
1165         let dest_ptr_ty = self.cx.val_ty(ptr);
1166         let stored_ty = self.cx.val_ty(val);
1167         let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
1168
1169         assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer);
1170
1171         if dest_ptr_ty == stored_ptr_ty {
1172             ptr
1173         } else {
1174             debug!(
1175                 "type mismatch in store. \
1176                     Expected {:?}, got {:?}; inserting bitcast",
1177                 dest_ptr_ty, stored_ptr_ty
1178             );
1179             self.bitcast(ptr, stored_ptr_ty)
1180         }
1181     }
1182
1183     fn check_call<'b>(
1184         &mut self,
1185         typ: &str,
1186         llfn: &'ll Value,
1187         args: &'b [&'ll Value],
1188     ) -> Cow<'b, [&'ll Value]> {
1189         let mut fn_ty = self.cx.val_ty(llfn);
1190         // Strip off pointers
1191         while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
1192             fn_ty = self.cx.element_type(fn_ty);
1193         }
1194
1195         assert!(
1196             self.cx.type_kind(fn_ty) == TypeKind::Function,
1197             "builder::{} not passed a function, but {:?}",
1198             typ,
1199             fn_ty
1200         );
1201
1202         let param_tys = self.cx.func_params_types(fn_ty);
1203
1204         let all_args_match = param_tys
1205             .iter()
1206             .zip(args.iter().map(|&v| self.val_ty(v)))
1207             .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
1208
1209         if all_args_match {
1210             return Cow::Borrowed(args);
1211         }
1212
1213         let casted_args: Vec<_> = param_tys
1214             .into_iter()
1215             .zip(args.iter())
1216             .enumerate()
1217             .map(|(i, (expected_ty, &actual_val))| {
1218                 let actual_ty = self.val_ty(actual_val);
1219                 if expected_ty != actual_ty {
1220                     debug!(
1221                         "type mismatch in function call of {:?}. \
1222                             Expected {:?} for param {}, got {:?}; injecting bitcast",
1223                         llfn, expected_ty, i, actual_ty
1224                     );
1225                     self.bitcast(actual_val, expected_ty)
1226                 } else {
1227                     actual_val
1228                 }
1229             })
1230             .collect();
1231
1232         Cow::Owned(casted_args)
1233     }
1234
1235     pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
1236         unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) }
1237     }
1238
1239     fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
1240         let size = size.bytes();
1241         if size == 0 {
1242             return;
1243         }
1244
1245         let opts = &self.cx.sess().opts;
1246         let emit = match opts.debugging_opts.sanitizer {
1247             // Some sanitizer use lifetime intrinsics. When they are in use,
1248             // emit lifetime intrinsics regardless of optimization level.
1249             Some(Sanitizer::Address) | Some(Sanitizer::Memory) => true,
1250             _ => opts.optimize != config::OptLevel::No,
1251         };
1252         if !emit {
1253             return;
1254         }
1255
1256         let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1257
1258         let ptr = self.pointercast(ptr, self.cx.type_i8p());
1259         self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
1260     }
1261
1262     fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
1263         assert_eq!(vals.len(), bbs.len());
1264         let phi = unsafe { llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED) };
1265         unsafe {
1266             llvm::LLVMAddIncoming(phi, vals.as_ptr(), bbs.as_ptr(), vals.len() as c_uint);
1267             phi
1268         }
1269     }
1270
1271     fn add_incoming_to_phi(&mut self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
1272         unsafe {
1273             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
1274         }
1275     }
1276 }