Skip to content

Commit c7b5154

Browse files
recovering from nightly crash
1 parent 6907005 commit c7b5154

28 files changed

+1084
-122
lines changed

src/librustc_codegen_llvm/abi.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_target::abi::call::ArgType;
1111

1212
use rustc_codegen_ssa::traits::*;
1313

14-
use rustc_target::abi::{HasDataLayout, LayoutOf};
14+
use rustc_target::abi::LayoutOf;
1515
use rustc::ty::{Ty};
1616
use rustc::ty::layout::{self};
1717

@@ -302,7 +302,7 @@ impl ArgTypeMethods<'tcx> for Builder<'a, 'll, 'tcx> {
302302

303303
pub trait FnTypeLlvmExt<'tcx> {
304304
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
305-
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
305+
// fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
306306
fn llvm_cconv(&self) -> llvm::CallConv;
307307
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value);
308308
fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
@@ -323,11 +323,11 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
323323
PassMode::Ignore(IgnoreMode::CVarArgs) =>
324324
bug!("`va_list` should never be a return type"),
325325
PassMode::Direct(_) | PassMode::Pair(..) => {
326-
self.ret.layout.immediate_llvm_type(cx)
326+
self.ret.layout.immediate_llvm_type(cx).copy_addr_space(cx.flat_addr_space())
327327
}
328328
PassMode::Cast(cast) => cast.llvm_type(cx),
329329
PassMode::Indirect(..) => {
330-
llargument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
330+
llargument_tys.push(cx.type_ptr_to_alloca(self.ret.memory_ty(cx)));
331331
cx.type_void()
332332
}
333333
};
@@ -340,7 +340,8 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
340340

341341
let llarg_ty = match arg.mode {
342342
PassMode::Ignore(_) => continue,
343-
PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx),
343+
PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx)
344+
.copy_addr_space(cx.flat_addr_space()),
344345
PassMode::Pair(..) => {
345346
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 0, true));
346347
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1, true));
@@ -354,7 +355,7 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
354355
continue;
355356
}
356357
PassMode::Cast(cast) => cast.llvm_type(cx),
357-
PassMode::Indirect(_, None) => cx.type_ptr_to(arg.memory_ty(cx)),
358+
PassMode::Indirect(_, None) => cx.type_ptr_to_alloca(arg.memory_ty(cx)),
358359
};
359360
llargument_tys.push(llarg_ty);
360361
}
@@ -366,13 +367,6 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
366367
}
367368
}
368369

369-
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
370-
unsafe {
371-
llvm::LLVMPointerType(self.llvm_type(cx),
372-
cx.data_layout().instruction_address_space as c_uint)
373-
}
374-
}
375-
376370
fn llvm_cconv(&self) -> llvm::CallConv {
377371
match self.conv {
378372
Conv::C => llvm::CCallConv,

src/librustc_codegen_llvm/builder.rs

+78-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope};
22
use crate::llvm::{self, False, BasicBlock};
3-
use crate::common::Funclet;
3+
use crate::common::{Funclet, val_addr_space, val_addr_space_opt};
44
use crate::context::CodegenCx;
55
use crate::type_::Type;
66
use crate::type_of::LayoutLlvmExt;
@@ -18,7 +18,7 @@ use rustc_codegen_ssa::traits::*;
1818
use rustc_codegen_ssa::base::to_immediate;
1919
use rustc_codegen_ssa::mir::operand::{OperandValue, OperandRef};
2020
use rustc_codegen_ssa::mir::place::PlaceRef;
21-
use rustc_target::spec::{HasTargetSpec, Target};
21+
use rustc_target::spec::{HasTargetSpec, Target, AddrSpaceIdx};
2222
use std::borrow::Cow;
2323
use std::ffi::CStr;
2424
use std::ops::{Deref, Range};
@@ -215,7 +215,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
215215
funclet: Option<&Funclet<'ll>>,
216216
) -> &'ll Value {
217217

218-
debug!("invoke {:?} with args ({:?})",
218+
debug!("Invoke {:?} with args ({:?})",
219219
llfn,
220220
args);
221221

@@ -548,6 +548,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
548548
let count = self.const_usize(count);
549549
let start = dest.project_index(&mut self, zero).llval;
550550
let end = dest.project_index(&mut self, count).llval;
551+
let start = self.flat_addr_cast(start);
552+
let end = self.flat_addr_cast(end);
551553

552554
let mut header_bx = self.build_sibling_block("repeat_loop_header");
553555
let mut body_bx = self.build_sibling_block("repeat_loop_body");
@@ -724,23 +726,56 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
724726
}
725727

726728
fn ptrtoint(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
729+
let val = self.flat_addr_cast(val);
727730
unsafe {
728731
llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, UNNAMED)
729732
}
730733
}
731734

732735
fn inttoptr(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
736+
let dest_ty = dest_ty.copy_addr_space(self.cx().flat_addr_space());
733737
unsafe {
734738
llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, UNNAMED)
735739
}
736740
}
737741

738742
fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
743+
let dest_ty = dest_ty.copy_addr_space(val_addr_space(val));
739744
unsafe {
740745
llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED)
741746
}
742747
}
743748

749+
fn as_ptr_cast(
750+
&mut self, val: &'ll Value,
751+
addr_space: AddrSpaceIdx, dest_ty: &'ll Type
752+
) -> &'ll Value {
753+
let val = self.addrspace_cast(val, addr_space);
754+
self.pointercast(val, dest_ty.copy_addr_space(addr_space))
755+
}
756+
757+
fn flat_as_ptr_cast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
758+
self.as_ptr_cast(val, self.cx().flat_addr_space(), dest_ty)
759+
}
760+
761+
fn addrspace_cast(&mut self, val: &'ll Value, dest: AddrSpaceIdx) -> &'ll Value {
762+
let src_ty = self.cx().val_ty(val);
763+
764+
if src_ty.is_ptr() && src_ty.address_space() != dest {
765+
let dest_ty = src_ty.copy_addr_space(dest);
766+
self.cx().check_addr_space_cast(val, dest_ty);
767+
unsafe {
768+
llvm::LLVMBuildAddrSpaceCast(self.llbuilder, val,
769+
dest_ty, UNNAMED)
770+
}
771+
} else {
772+
val
773+
}
774+
}
775+
776+
fn flat_addr_cast(&mut self, val: &'ll Value) -> &'ll Value {
777+
self.addrspace_cast(val, self.cx().flat_addr_space())
778+
}
744779

745780
fn intcast(&mut self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
746781
unsafe {
@@ -749,6 +784,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
749784
}
750785

751786
fn pointercast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
787+
let dest_ty = dest_ty.copy_addr_space(val_addr_space(val));
752788
unsafe {
753789
llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, UNNAMED)
754790
}
@@ -757,6 +793,16 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
757793
/* Comparisons */
758794
fn icmp(&mut self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
759795
let op = llvm::IntPredicate::from_generic(op);
796+
797+
match (val_addr_space_opt(lhs), val_addr_space_opt(rhs)) {
798+
(Some(l), Some(r)) if l == r => {},
799+
(Some(l), Some(r)) if l != r => {
800+
bug!("Tried to compare pointers of different address spaces: lhs {:?} rhs {:?}",
801+
lhs, rhs);
802+
},
803+
_ => {},
804+
}
805+
760806
unsafe {
761807
llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED)
762808
}
@@ -818,7 +864,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
818864
flags: MemFlags,
819865
) {
820866
let ptr_width = &self.sess().target.target.target_pointer_width;
821-
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
867+
let addr_space = self.val_ty(ptr).address_space();
868+
let intrinsic_key = format!("llvm.memset.p{}i8.i{}", addr_space, ptr_width);
822869
let llintrinsicfn = self.get_intrinsic(&intrinsic_key);
823870
let ptr = self.pointercast(ptr, self.type_i8p());
824871
let align = self.const_u32(align.bytes() as u32);
@@ -1035,7 +1082,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
10351082
funclet: Option<&Funclet<'ll>>,
10361083
) -> &'ll Value {
10371084

1038-
debug!("call {:?} with args ({:?})",
1085+
debug!("Call {:?} with args ({:?})",
10391086
llfn,
10401087
args);
10411088

@@ -1231,14 +1278,15 @@ impl Builder<'a, 'll, 'tcx> {
12311278
fn check_store(&mut self, val: &'ll Value, ptr: &'ll Value) -> &'ll Value {
12321279
let dest_ptr_ty = self.cx.val_ty(ptr);
12331280
let stored_ty = self.cx.val_ty(val);
1234-
let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
1281+
let stored_ptr_ty = self.cx.type_as_ptr_to(stored_ty,
1282+
dest_ptr_ty.address_space());
12351283

12361284
assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer);
12371285

12381286
if dest_ptr_ty == stored_ptr_ty {
12391287
ptr
12401288
} else {
1241-
debug!("type mismatch in store. \
1289+
debug!("Type mismatch in store. \
12421290
Expected {:?}, got {:?}; inserting bitcast",
12431291
dest_ptr_ty, stored_ptr_ty);
12441292
self.bitcast(ptr, stored_ptr_ty)
@@ -1274,10 +1322,21 @@ impl Builder<'a, 'll, 'tcx> {
12741322
.map(|(i, (expected_ty, &actual_val))| {
12751323
let actual_ty = self.val_ty(actual_val);
12761324
if expected_ty != actual_ty {
1277-
debug!("type mismatch in function call of {:?}. \
1325+
debug!("Type mismatch in function call of {:?}. \
12781326
Expected {:?} for param {}, got {:?}; injecting bitcast",
12791327
llfn, expected_ty, i, actual_ty);
1280-
self.bitcast(actual_val, expected_ty)
1328+
if expected_ty.is_ptr() && actual_ty.is_ptr() {
1329+
let actual_val = self.addrspace_cast(actual_val,
1330+
expected_ty.address_space());
1331+
self.pointercast(actual_val, expected_ty)
1332+
} else {
1333+
let actual_val = if actual_ty.is_ptr() {
1334+
self.flat_addr_cast(actual_val)
1335+
} else {
1336+
actual_val
1337+
};
1338+
self.bitcast(actual_val, expected_ty)
1339+
}
12811340
} else {
12821341
actual_val
12831342
}
@@ -1303,7 +1362,16 @@ impl Builder<'a, 'll, 'tcx> {
13031362
return;
13041363
}
13051364

1306-
let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1365+
let addr_space = self.cx.val_ty(ptr).address_space();
1366+
// Old LLVMs don't have the address space specific intrinsics.
1367+
// So as a semi-crude workaround, don't specialize if in the
1368+
// default address space.
1369+
let lifetime_intrinsic = if let AddrSpaceIdx(0) = addr_space {
1370+
self.cx.get_intrinsic(intrinsic)
1371+
} else {
1372+
let intrinsic = format!("{}.p{}i8", intrinsic, addr_space);
1373+
self.cx.get_intrinsic(&intrinsic)
1374+
};
13071375

13081376
let ptr = self.pointercast(ptr, self.cx.type_i8p());
13091377
self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);

src/librustc_codegen_llvm/common.rs

+35-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use rustc_codegen_ssa::traits::*;
1313
use crate::consts::const_alloc_to_llvm;
1414
use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size, Align};
1515
use rustc::mir::interpret::{Scalar, GlobalAlloc, Allocation};
16+
use rustc_codegen_ssa::common::TypeKind;
1617
use rustc_codegen_ssa::mir::place::PlaceRef;
18+
use rustc_target::spec::AddrSpaceIdx;
1719

1820
use libc::{c_uint, c_char};
1921

@@ -135,9 +137,9 @@ impl CodegenCx<'ll, 'tcx> {
135137
s.len() as c_uint,
136138
!null_terminated as Bool);
137139
let sym = self.generate_local_symbol_name("str");
138-
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
139-
bug!("symbol `{}` is already defined", sym);
140-
});
140+
let addr_space = self.const_addr_space();
141+
let g = self.define_global(&sym[..], self.val_ty(sc), addr_space)
142+
.unwrap_or_else(||bug!("symbol `{}` is already defined", sym) );
141143
llvm::LLVMSetInitializer(g, sc);
142144
llvm::LLVMSetGlobalConstant(g, True);
143145
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
@@ -290,6 +292,10 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
290292
}
291293
}
292294

295+
fn const_as_cast(&self, val: &'ll Value, addr_space: AddrSpaceIdx) -> &'ll Value {
296+
self.const_addrcast(val, addr_space)
297+
}
298+
293299
fn scalar_to_backend(
294300
&self,
295301
cv: Scalar,
@@ -305,10 +311,16 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
305311
Scalar::Raw { data, size } => {
306312
assert_eq!(size as u64, layout.value.size(self).bytes());
307313
let llval = self.const_uint_big(self.type_ix(bitsize), data);
308-
if layout.value == layout::Pointer {
309-
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
314+
let flat_llty = llty.copy_addr_space(self.flat_addr_space());
315+
let llval = if layout.value == layout::Pointer {
316+
unsafe { llvm::LLVMConstIntToPtr(llval, flat_llty) }
310317
} else {
311-
self.const_bitcast(llval, llty)
318+
self.const_bitcast(llval, flat_llty)
319+
};
320+
if llty.is_ptr() {
321+
self.const_as_cast(llval, llty.address_space())
322+
} else {
323+
llval
312324
}
313325
},
314326
Scalar::Ptr(ptr) => {
@@ -317,7 +329,8 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
317329
Some(GlobalAlloc::Memory(alloc)) => {
318330
let init = const_alloc_to_llvm(self, alloc);
319331
if alloc.mutability == Mutability::Mutable {
320-
self.static_addr_of_mut(init, alloc.align, None)
332+
self.static_addr_of_mut(init, alloc.align, None,
333+
self.mutable_addr_space())
321334
} else {
322335
self.static_addr_of(init, alloc.align, None)
323336
}
@@ -331,11 +344,12 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
331344
}
332345
None => bug!("missing allocation {:?}", ptr.alloc_id),
333346
};
334-
let llval = unsafe { llvm::LLVMConstInBoundsGEP(
347+
let llval_ref = unsafe { llvm::LLVMConstInBoundsGEP(
335348
self.const_bitcast(base_addr, self.type_i8p()),
336349
&self.const_usize(ptr.offset.bytes()),
337350
1,
338351
) };
352+
let llval = self.const_flat_as_cast(llval_ref);
339353
if layout.value != layout::Pointer {
340354
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
341355
} else {
@@ -375,6 +389,19 @@ pub fn val_ty(v: &'ll Value) -> &'ll Type {
375389
}
376390
}
377391

392+
pub fn val_addr_space_opt(v: &'ll Value) -> Option<AddrSpaceIdx> {
393+
let ty = val_ty(v);
394+
if ty.kind() == TypeKind::Pointer {
395+
Some(ty.address_space())
396+
} else {
397+
None
398+
}
399+
}
400+
401+
pub fn val_addr_space(v: &'ll Value) -> AddrSpaceIdx {
402+
val_addr_space_opt(v).unwrap_or_default()
403+
}
404+
378405
pub fn bytes_in_context(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value {
379406
unsafe {
380407
let ptr = bytes.as_ptr() as *const c_char;

0 commit comments

Comments
 (0)