11use crate :: llvm:: { AtomicRmwBinOp , AtomicOrdering , SynchronizationScope } ;
22use crate :: llvm:: { self , False , BasicBlock } ;
3- use crate :: common:: Funclet ;
3+ use crate :: common:: { Funclet , val_addr_space , val_addr_space_opt } ;
44use crate :: context:: CodegenCx ;
55use crate :: type_:: Type ;
66use crate :: type_of:: LayoutLlvmExt ;
@@ -18,7 +18,7 @@ use rustc_codegen_ssa::traits::*;
1818use rustc_codegen_ssa:: base:: to_immediate;
1919use rustc_codegen_ssa:: mir:: operand:: { OperandValue , OperandRef } ;
2020use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
21- use rustc_target:: spec:: { HasTargetSpec , Target } ;
21+ use rustc_target:: spec:: { HasTargetSpec , Target , AddrSpaceIdx } ;
2222use std:: borrow:: Cow ;
2323use std:: ffi:: CStr ;
2424use 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 ) ;
0 commit comments