@@ -18,6 +18,36 @@ use super::{FunctionCx, LocalRef};
1818use super :: operand:: { OperandRef , OperandValue } ;
1919use super :: place:: PlaceRef ;
2020
21+ fn codegen_binop_fixup < ' a , ' tcx : ' a , Bx > ( bx : & mut Bx ,
22+ lhs : Bx :: Value ,
23+ rhs : Bx :: Value )
24+ -> ( Bx :: Value , Bx :: Value )
25+ where Bx : BuilderMethods < ' a , ' tcx > ,
26+ {
27+ // In case we're in separate addr spaces.
28+ // Can happen when cmp against null_mut, eg.
29+ // `infer-addr-spaces` should propagate.
30+ // But, empirically, `infer-addr-spaces` doesn't.
31+ let fix_null_ty = |val, this_ty, other_ty| {
32+ if bx. cx ( ) . const_null ( this_ty) == val {
33+ bx. cx ( ) . const_null ( other_ty)
34+ } else {
35+ val
36+ }
37+ } ;
38+ let lhs_ty = bx. cx ( ) . val_ty ( lhs) ;
39+ let rhs_ty = bx. cx ( ) . val_ty ( rhs) ;
40+ let lhs = fix_null_ty ( lhs, lhs_ty, rhs_ty) ;
41+ let rhs = fix_null_ty ( rhs, rhs_ty, lhs_ty) ;
42+ if bx. cx ( ) . type_addr_space ( lhs_ty) . is_some ( ) {
43+ assert ! ( bx. cx( ) . type_addr_space( rhs_ty) . is_some( ) ) ;
44+ ( bx. flat_addr_cast ( lhs) ,
45+ bx. flat_addr_cast ( rhs) )
46+ } else {
47+ ( lhs, rhs)
48+ }
49+ }
50+
2151impl < ' a , ' tcx : ' a , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
2252 pub fn codegen_rvalue (
2353 & mut self ,
@@ -63,7 +93,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6393 // index into the struct, and this case isn't
6494 // important enough for it.
6595 debug ! ( "codegen_rvalue: creating ugly alloca" ) ;
66- let scratch = PlaceRef :: alloca ( & mut bx, operand. layout , "__unsize_temp" ) ;
96+ let scratch = PlaceRef :: alloca_addr_space ( & mut bx, operand. layout ,
97+ "__unsize_temp" ) ;
6798 scratch. storage_live ( & mut bx) ;
6899 operand. val . store ( & mut bx, scratch) ;
69100 base:: coerce_unsized_into ( & mut bx, scratch, dest) ;
@@ -89,7 +120,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
89120 }
90121 let zero = bx. cx ( ) . const_usize ( 0 ) ;
91122 let start = dest. project_index ( & mut bx, zero) . llval ;
92- let start = bx. flat_addr_cast ( start) ;
93123
94124 if let OperandValue :: Immediate ( v) = cg_elem. val {
95125 let size = bx. cx ( ) . const_usize ( dest. layout . size . bytes ( ) ) ;
@@ -111,6 +141,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
111141
112142 let count = bx. cx ( ) . const_usize ( count) ;
113143 let end = dest. project_index ( & mut bx, count) . llval ;
144+ let start = bx. flat_addr_cast ( start) ;
114145 let end = bx. flat_addr_cast ( end) ;
115146
116147 let mut header_bx = bx. build_sibling_block ( "repeat_loop_header" ) ;
@@ -245,7 +276,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
245276 // until LLVM removes pointee types.
246277 let lldata = bx. pointercast ( lldata,
247278 bx. cx ( ) . scalar_pair_element_backend_type ( cast, 0 , true ) ) ;
248- let lldata = bx. flat_addr_cast ( lldata) ;
249279 OperandValue :: Pair ( lldata, llextra)
250280 }
251281 OperandValue :: Immediate ( lldata) => {
@@ -618,17 +648,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
618648 lhs, rhs
619649 )
620650 } else {
621- // In case we're in separate addr spaces.
622- // Can happen when cmp against null_mut, eg.
623- // `infer-addr-spaces` should propagate.
624- let lhs_ty = bx. cx ( ) . val_ty ( rhs) ;
625- let ( lhs, rhs) = if bx. cx ( ) . type_addr_space ( lhs_ty) . is_some ( ) {
626- assert ! ( bx. cx( ) . type_addr_space( bx. cx( ) . val_ty( rhs) ) . is_some( ) ) ;
627- ( bx. flat_addr_cast ( lhs) ,
628- bx. flat_addr_cast ( rhs) )
629- } else {
630- ( lhs, rhs)
631- } ;
651+ let ( lhs, rhs) = codegen_binop_fixup ( bx, lhs, rhs) ;
632652 bx. icmp (
633653 base:: bin_op_to_icmp_predicate ( op. to_hir_binop ( ) , is_signed) ,
634654 lhs, rhs
@@ -647,12 +667,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
647667 rhs_extra : Bx :: Value ,
648668 _input_ty : Ty < ' tcx > ,
649669 ) -> Bx :: Value {
650- // In case we're in separate addr spaces.
651- // Can happen when cmp against null_mut, eg.
652- // `infer-addr-spaces` should propagate.
653- let lhs_addr = bx. flat_addr_cast ( lhs_addr) ;
654- let rhs_addr = bx. flat_addr_cast ( rhs_addr) ;
655-
670+ let ( lhs_addr, rhs_addr) = codegen_binop_fixup ( bx, lhs_addr, rhs_addr) ;
656671 match op {
657672 mir:: BinOp :: Eq => {
658673 let lhs = bx. icmp ( IntPredicate :: IntEQ , lhs_addr, rhs_addr) ;
0 commit comments