@@ -205,13 +205,22 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
205
205
assert ! ( alloc_align >= layout. align. abi) ;
206
206
207
207
let read_scalar = |start, size, s : abi:: Scalar , ty| {
208
+ let range = alloc_range ( start, size) ;
208
209
match alloc. 0 . read_scalar (
209
210
bx,
210
- alloc_range ( start , size ) ,
211
+ range ,
211
212
/*read_provenance*/ matches ! ( s. primitive( ) , abi:: Primitive :: Pointer ( _) ) ,
212
213
) {
213
- Ok ( val) => bx. scalar_to_backend ( val, s, ty) ,
214
- Err ( _) => bx. const_poison ( ty) ,
214
+ Ok ( val) => Some ( bx. scalar_to_backend ( val, s, ty) ) ,
215
+ Err ( _) => {
216
+ if alloc. 0 . provenance ( ) . range_empty ( range, & bx. tcx ( ) )
217
+ && alloc. 0 . init_mask ( ) . is_range_initialized ( range) . unwrap_err ( ) == range
218
+ {
219
+ Some ( bx. const_undef ( ty) )
220
+ } else {
221
+ None
222
+ }
223
+ }
215
224
}
216
225
} ;
217
226
@@ -222,16 +231,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
222
231
// check that walks over the type of `mplace` to make sure it is truly correct to treat this
223
232
// like a `Scalar` (or `ScalarPair`).
224
233
match layout. backend_repr {
225
- BackendRepr :: Scalar ( s @ abi :: Scalar :: Initialized { .. } ) => {
234
+ BackendRepr :: Scalar ( s) => {
226
235
let size = s. size ( bx) ;
227
236
assert_eq ! ( size, layout. size, "abi::Scalar size does not match layout size" ) ;
228
- let val = read_scalar ( offset, size, s, bx. immediate_backend_type ( layout) ) ;
229
- OperandRef { val : OperandValue :: Immediate ( val) , layout }
237
+ if let Some ( val) = read_scalar ( offset, size, s, bx. immediate_backend_type ( layout) ) {
238
+ return OperandRef { val : OperandValue :: Immediate ( val) , layout } ;
239
+ }
230
240
}
231
- BackendRepr :: ScalarPair (
232
- a @ abi:: Scalar :: Initialized { .. } ,
233
- b @ abi:: Scalar :: Initialized { .. } ,
234
- ) => {
241
+ BackendRepr :: ScalarPair ( a, b) => {
235
242
let ( a_size, b_size) = ( a. size ( bx) , b. size ( bx) ) ;
236
243
let b_offset = ( offset + a_size) . align_to ( b. align ( bx) . abi ) ;
237
244
assert ! ( b_offset. bytes( ) > 0 ) ;
@@ -247,20 +254,21 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
247
254
b,
248
255
bx. scalar_pair_element_backend_type ( layout, 1 , true ) ,
249
256
) ;
250
- OperandRef { val : OperandValue :: Pair ( a_val, b_val) , layout }
251
- }
252
- _ if layout. is_zst ( ) => OperandRef :: zero_sized ( layout) ,
253
- _ => {
254
- // Neither a scalar nor scalar pair. Load from a place
255
- // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the
256
- // same `ConstAllocation`?
257
- let init = bx. const_data_from_alloc ( alloc) ;
258
- let base_addr = bx. static_addr_of ( init, alloc_align, None ) ;
259
-
260
- let llval = bx. const_ptr_byte_offset ( base_addr, offset) ;
261
- bx. load_operand ( PlaceRef :: new_sized ( llval, layout) )
257
+ if let ( Some ( a_val) , Some ( b_val) ) = ( a_val, b_val) {
258
+ return OperandRef { val : OperandValue :: Pair ( a_val, b_val) , layout } ;
259
+ }
262
260
}
261
+ _ if layout. is_zst ( ) => return OperandRef :: zero_sized ( layout) ,
262
+ _ => { }
263
263
}
264
+ // Neither a scalar nor scalar pair. Load from a place
265
+ // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the
266
+ // same `ConstAllocation`?
267
+ let init = bx. const_data_from_alloc ( alloc) ;
268
+ let base_addr = bx. static_addr_of ( init, alloc_align, None ) ;
269
+
270
+ let llval = bx. const_ptr_byte_offset ( base_addr, offset) ;
271
+ bx. load_operand ( PlaceRef :: new_sized ( llval, layout) )
264
272
}
265
273
266
274
/// Asserts that this operand refers to a scalar and returns
0 commit comments