@@ -18,6 +18,36 @@ use super::{FunctionCx, LocalRef};
18
18
use super :: operand:: { OperandRef , OperandValue } ;
19
19
use super :: place:: PlaceRef ;
20
20
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
+
21
51
impl < ' a , ' tcx : ' a , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
22
52
pub fn codegen_rvalue (
23
53
& mut self ,
@@ -63,7 +93,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
63
93
// index into the struct, and this case isn't
64
94
// important enough for it.
65
95
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" ) ;
67
98
scratch. storage_live ( & mut bx) ;
68
99
operand. val . store ( & mut bx, scratch) ;
69
100
base:: coerce_unsized_into ( & mut bx, scratch, dest) ;
@@ -89,7 +120,6 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
89
120
}
90
121
let zero = bx. cx ( ) . const_usize ( 0 ) ;
91
122
let start = dest. project_index ( & mut bx, zero) . llval ;
92
- let start = bx. flat_addr_cast ( start) ;
93
123
94
124
if let OperandValue :: Immediate ( v) = cg_elem. val {
95
125
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> {
111
141
112
142
let count = bx. cx ( ) . const_usize ( count) ;
113
143
let end = dest. project_index ( & mut bx, count) . llval ;
144
+ let start = bx. flat_addr_cast ( start) ;
114
145
let end = bx. flat_addr_cast ( end) ;
115
146
116
147
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> {
245
276
// until LLVM removes pointee types.
246
277
let lldata = bx. pointercast ( lldata,
247
278
bx. cx ( ) . scalar_pair_element_backend_type ( cast, 0 , true ) ) ;
248
- let lldata = bx. flat_addr_cast ( lldata) ;
249
279
OperandValue :: Pair ( lldata, llextra)
250
280
}
251
281
OperandValue :: Immediate ( lldata) => {
@@ -618,17 +648,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
618
648
lhs, rhs
619
649
)
620
650
} 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) ;
632
652
bx. icmp (
633
653
base:: bin_op_to_icmp_predicate ( op. to_hir_binop ( ) , is_signed) ,
634
654
lhs, rhs
@@ -647,12 +667,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
647
667
rhs_extra : Bx :: Value ,
648
668
_input_ty : Ty < ' tcx > ,
649
669
) -> 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) ;
656
671
match op {
657
672
mir:: BinOp :: Eq => {
658
673
let lhs = bx. icmp ( IntPredicate :: IntEQ , lhs_addr, rhs_addr) ;
0 commit comments