Auto merge of #135335 - oli-obk:push-zxwssomxxtnq, r=saethlin · compiler-errors/rust@a7a6c64 (original) (raw)
`@@ -204,14 +204,30 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
`
204
204
`let alloc_align = alloc.inner().align;
`
205
205
`assert!(alloc_align >= layout.align.abi);
`
206
206
``
``
207
`` +
// Returns None when the value is partially undefined or any byte of it has provenance.
``
``
208
`+
// Otherwise returns the value or (if the entire value is undef) returns an undef.
`
207
209
`let read_scalar = |start, size, s: abi::Scalar, ty| {
`
``
210
`+
let range = alloc_range(start, size);
`
208
211
`match alloc.0.read_scalar(
`
209
212
` bx,
`
210
``
`-
alloc_range(start, size),
`
``
213
`+
range,
`
211
214
`/read_provenance/ matches!(s.primitive(), abi::Primitive::Pointer(_)),
`
212
215
`) {
`
213
``
`-
Ok(val) => bx.scalar_to_backend(val, s, ty),
`
214
``
`-
Err(_) => bx.const_poison(ty),
`
``
216
`+
Ok(val) => Some(bx.scalar_to_backend(val, s, ty)),
`
``
217
`+
Err(_) => {
`
``
218
`+
// We may have failed due to partial provenance or unexpected provenance,
`
``
219
`+
// continue down the normal code path if so.
`
``
220
`+
if alloc.0.provenance().range_empty(range, &bx.tcx())
`
``
221
`` +
// Since read_scalar failed, but there were no relocations involved, the
``
``
222
`+
// bytes must be partially or fully uninitialized. Thus we can now unwrap the
`
``
223
`+
// information about the range of uninit bytes and check if it's the full range.
`
``
224
`+
&& alloc.0.init_mask().is_range_initialized(range).unwrap_err() == range
`
``
225
`+
{
`
``
226
`+
Some(bx.const_undef(ty))
`
``
227
`+
} else {
`
``
228
`+
None
`
``
229
`+
}
`
``
230
`+
}
`
215
231
`}
`
216
232
`};
`
217
233
``
`@@ -222,16 +238,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
`
222
238
`` // check that walks over the type of mplace to make sure it is truly correct to treat this
``
223
239
`` // like a Scalar (or ScalarPair).
``
224
240
`match layout.backend_repr {
`
225
``
`-
BackendRepr::Scalar(s @ abi::Scalar::Initialized { .. }) => {
`
``
241
`+
BackendRepr::Scalar(s) => {
`
226
242
`let size = s.size(bx);
`
227
243
`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 }
`
``
244
`+
if let Some(val) = read_scalar(offset, size, s, bx.immediate_backend_type(layout)) {
`
``
245
`+
return OperandRef { val: OperandValue::Immediate(val), layout };
`
``
246
`+
}
`
230
247
`}
`
231
``
`-
BackendRepr::ScalarPair(
`
232
``
`-
a @ abi::Scalar::Initialized { .. },
`
233
``
`-
b @ abi::Scalar::Initialized { .. },
`
234
``
`-
) => {
`
``
248
`+
BackendRepr::ScalarPair(a, b) => {
`
235
249
`let (a_size, b_size) = (a.size(bx), b.size(bx));
`
236
250
`let b_offset = (offset + a_size).align_to(b.align(bx).abi);
`
237
251
`assert!(b_offset.bytes() > 0);
`
`@@ -247,20 +261,21 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
`
247
261
` b,
`
248
262
` bx.scalar_pair_element_backend_type(layout, 1, true),
`
249
263
`);
`
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))
`
``
264
`+
if let (Some(a_val), Some(b_val)) = (a_val, b_val) {
`
``
265
`+
return OperandRef { val: OperandValue::Pair(a_val, b_val), layout };
`
``
266
`+
}
`
262
267
`}
`
``
268
`+
_ if layout.is_zst() => return OperandRef::zero_sized(layout),
`
``
269
`+
_ => {}
`
263
270
`}
`
``
271
`+
// Neither a scalar nor scalar pair. Load from a place
`
``
272
`` +
// FIXME: should we cache const_data_from_alloc to avoid repeating this for the
``
``
273
`` +
// same ConstAllocation?
``
``
274
`+
let init = bx.const_data_from_alloc(alloc);
`
``
275
`+
let base_addr = bx.static_addr_of(init, alloc_align, None);
`
``
276
+
``
277
`+
let llval = bx.const_ptr_byte_offset(base_addr, offset);
`
``
278
`+
bx.load_operand(PlaceRef::new_sized(llval, layout))
`
264
279
`}
`
265
280
``
266
281
`/// Asserts that this operand refers to a scalar and returns
`