Skip to content

Commit d32ce37

Browse files
committed
Mark scalar layout unions so that backends that do not support partially initialized scalars can special case them.
1 parent 2ed6786 commit d32ce37

File tree

37 files changed

+357
-289
lines changed

37 files changed

+357
-289
lines changed

compiler/rustc_codegen_cranelift/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type {
2121
}
2222

2323
pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
24-
match scalar.value {
24+
match scalar.primitive() {
2525
Primitive::Int(int, _sign) => match int {
2626
Integer::I8 => types::I8,
2727
Integer::I16 => types::I16,

compiler/rustc_codegen_cranelift/src/discriminant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
105105
// Decode the discriminant (specifically if it's niche-encoded).
106106
match *tag_encoding {
107107
TagEncoding::Direct => {
108-
let signed = match tag_scalar.value {
108+
let signed = match tag_scalar.primitive() {
109109
Int(_, signed) => signed,
110110
_ => false,
111111
};

compiler/rustc_codegen_cranelift/src/value_and_place.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fn codegen_field<'tcx>(
5050
}
5151

5252
fn scalar_pair_calculate_b_offset(tcx: TyCtxt<'_>, a_scalar: Scalar, b_scalar: Scalar) -> Offset32 {
53-
let b_offset = a_scalar.value.size(&tcx).align_to(b_scalar.value.align(&tcx).abi);
53+
let b_offset = a_scalar.size(&tcx).align_to(b_scalar.align(&tcx).abi);
5454
Offset32::new(b_offset.bytes().try_into().unwrap())
5555
}
5656

compiler/rustc_codegen_gcc/src/builder.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -694,11 +694,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
694694
}
695695

696696
fn scalar_load_metadata<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, load: RValue<'gcc>, scalar: &abi::Scalar) {
697-
let vr = scalar.valid_range.clone();
698-
match scalar.value {
697+
let vr = scalar.valid_range(bx);
698+
match scalar.primitive() {
699699
abi::Int(..) => {
700700
if !scalar.is_always_valid(bx) {
701-
bx.range_metadata(load, scalar.valid_range);
701+
bx.range_metadata(load, vr);
702702
}
703703
}
704704
abi::Pointer if vr.start < vr.end && !vr.contains(0) => {
@@ -720,7 +720,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
720720
OperandValue::Immediate(self.to_immediate(load, place.layout))
721721
}
722722
else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
723-
let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
723+
let b_offset = a.size(self).align_to(b.align(self).abi);
724724
let pair_type = place.layout.gcc_type(self, false);
725725

726726
let mut load = |i, scalar: &abi::Scalar, align| {

compiler/rustc_codegen_gcc/src/common.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,14 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
158158
}
159159

160160
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, ty: Type<'gcc>) -> RValue<'gcc> {
161-
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(self).bits() };
161+
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
162162
match cv {
163163
Scalar::Int(ScalarInt::ZST) => {
164-
assert_eq!(0, layout.value.size(self).bytes());
164+
assert_eq!(0, layout.size(self).bytes());
165165
self.const_undef(self.type_ix(0))
166166
}
167167
Scalar::Int(int) => {
168-
let data = int.assert_bits(layout.value.size(self));
168+
let data = int.assert_bits(layout.size(self));
169169

170170
// FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code
171171
// the paths for floating-point values.
@@ -209,7 +209,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
209209
let base_addr = self.const_bitcast(base_addr, self.usize_type);
210210
let offset = self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
211211
let ptr = self.const_bitcast(base_addr + offset, ptr_type);
212-
if layout.value != Pointer {
212+
if layout.primitive() != Pointer {
213213
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
214214
}
215215
else {

compiler/rustc_codegen_gcc/src/consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
328328
interpret::Pointer::new(alloc_id, Size::from_bytes(ptr_offset)),
329329
&cx.tcx,
330330
),
331-
abi::Scalar { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } },
331+
abi::Scalar::Initialized { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } },
332332
cx.type_i8p(),
333333
));
334334
next_offset = offset + pointer_size;

compiler/rustc_codegen_gcc/src/type_of.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
224224
}
225225

226226
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc> {
227-
match scalar.value {
227+
match scalar.primitive() {
228228
Int(i, true) => cx.type_from_integer(i),
229229
Int(i, false) => cx.type_from_unsigned_integer(i),
230230
F32 => cx.type_f32(),
@@ -282,7 +282,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
282282
Size::ZERO
283283
}
284284
else {
285-
a.value.size(cx).align_to(b.value.align(cx).abi)
285+
a.size(cx).align_to(b.align(cx).abi)
286286
};
287287
self.scalar_gcc_type_at(cx, scalar, offset)
288288
}

compiler/rustc_codegen_llvm/src/abi.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -510,9 +510,9 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
510510
// If the value is a boolean, the range is 0..2 and that ultimately
511511
// become 0..0 when the type becomes i1, which would be rejected
512512
// by the LLVM verifier.
513-
if let Int(..) = scalar.value {
513+
if let Int(..) = scalar.primitive() {
514514
if !scalar.is_bool() && !scalar.is_always_valid(bx) {
515-
bx.range_metadata(callsite, scalar.valid_range);
515+
bx.range_metadata(callsite, scalar.valid_range(bx));
516516
}
517517
}
518518
}

compiler/rustc_codegen_llvm/src/asm.rs

+43-37
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
753753
/// Helper function to get the LLVM type for a Scalar. Pointers are returned as
754754
/// the equivalent integer type.
755755
fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Type {
756-
match scalar.value {
756+
match scalar.primitive() {
757757
Primitive::Int(Integer::I8, _) => cx.type_i8(),
758758
Primitive::Int(Integer::I16, _) => cx.type_i16(),
759759
Primitive::Int(Integer::I32, _) => cx.type_i32(),
@@ -774,7 +774,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
774774
) -> &'ll Value {
775775
match (reg, layout.abi) {
776776
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
777-
if let Primitive::Int(Integer::I8, _) = s.value {
777+
if let Primitive::Int(Integer::I8, _) = s.primitive() {
778778
let vec_ty = bx.cx.type_vector(bx.cx.type_i8(), 8);
779779
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
780780
} else {
@@ -785,7 +785,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
785785
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
786786
let count = 16 / layout.size.bytes();
787787
let vec_ty = bx.cx.type_vector(elem_ty, count);
788-
if let Primitive::Pointer = s.value {
788+
if let Primitive::Pointer = s.primitive() {
789789
value = bx.ptrtoint(value, bx.cx.type_isize());
790790
}
791791
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
@@ -800,7 +800,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
800800
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
801801
}
802802
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
803-
if s.value == Primitive::F64 =>
803+
if s.primitive() == Primitive::F64 =>
804804
{
805805
bx.bitcast(value, bx.cx.type_i64())
806806
}
@@ -812,7 +812,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
812812
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
813813
Abi::Scalar(s),
814814
) => {
815-
if let Primitive::Int(Integer::I32, _) = s.value {
815+
if let Primitive::Int(Integer::I32, _) = s.primitive() {
816816
bx.bitcast(value, bx.cx.type_f32())
817817
} else {
818818
value
@@ -826,19 +826,21 @@ fn llvm_fixup_input<'ll, 'tcx>(
826826
),
827827
Abi::Scalar(s),
828828
) => {
829-
if let Primitive::Int(Integer::I64, _) = s.value {
829+
if let Primitive::Int(Integer::I64, _) = s.primitive() {
830830
bx.bitcast(value, bx.cx.type_f64())
831831
} else {
832832
value
833833
}
834834
}
835-
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => match s.value {
836-
// MIPS only supports register-length arithmetics.
837-
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
838-
Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()),
839-
Primitive::F64 => bx.bitcast(value, bx.cx.type_i64()),
840-
_ => value,
841-
},
835+
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
836+
match s.primitive() {
837+
// MIPS only supports register-length arithmetics.
838+
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
839+
Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()),
840+
Primitive::F64 => bx.bitcast(value, bx.cx.type_i64()),
841+
_ => value,
842+
}
843+
}
842844
_ => value,
843845
}
844846
}
@@ -852,15 +854,15 @@ fn llvm_fixup_output<'ll, 'tcx>(
852854
) -> &'ll Value {
853855
match (reg, layout.abi) {
854856
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
855-
if let Primitive::Int(Integer::I8, _) = s.value {
857+
if let Primitive::Int(Integer::I8, _) = s.primitive() {
856858
bx.extract_element(value, bx.const_i32(0))
857859
} else {
858860
value
859861
}
860862
}
861863
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
862864
value = bx.extract_element(value, bx.const_i32(0));
863-
if let Primitive::Pointer = s.value {
865+
if let Primitive::Pointer = s.primitive() {
864866
value = bx.inttoptr(value, layout.llvm_type(bx.cx));
865867
}
866868
value
@@ -875,7 +877,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
875877
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
876878
}
877879
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
878-
if s.value == Primitive::F64 =>
880+
if s.primitive() == Primitive::F64 =>
879881
{
880882
bx.bitcast(value, bx.cx.type_f64())
881883
}
@@ -887,7 +889,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
887889
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
888890
Abi::Scalar(s),
889891
) => {
890-
if let Primitive::Int(Integer::I32, _) = s.value {
892+
if let Primitive::Int(Integer::I32, _) = s.primitive() {
891893
bx.bitcast(value, bx.cx.type_i32())
892894
} else {
893895
value
@@ -901,20 +903,22 @@ fn llvm_fixup_output<'ll, 'tcx>(
901903
),
902904
Abi::Scalar(s),
903905
) => {
904-
if let Primitive::Int(Integer::I64, _) = s.value {
906+
if let Primitive::Int(Integer::I64, _) = s.primitive() {
905907
bx.bitcast(value, bx.cx.type_i64())
906908
} else {
907909
value
908910
}
909911
}
910-
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => match s.value {
911-
// MIPS only supports register-length arithmetics.
912-
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
913-
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
914-
Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()),
915-
Primitive::F64 => bx.bitcast(value, bx.cx.type_f64()),
916-
_ => value,
917-
},
912+
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
913+
match s.primitive() {
914+
// MIPS only supports register-length arithmetics.
915+
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
916+
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
917+
Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()),
918+
Primitive::F64 => bx.bitcast(value, bx.cx.type_f64()),
919+
_ => value,
920+
}
921+
}
918922
_ => value,
919923
}
920924
}
@@ -927,7 +931,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
927931
) -> &'ll Type {
928932
match (reg, layout.abi) {
929933
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
930-
if let Primitive::Int(Integer::I8, _) = s.value {
934+
if let Primitive::Int(Integer::I8, _) = s.primitive() {
931935
cx.type_vector(cx.type_i8(), 8)
932936
} else {
933937
layout.llvm_type(cx)
@@ -946,7 +950,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
946950
cx.type_vector(elem_ty, count * 2)
947951
}
948952
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
949-
if s.value == Primitive::F64 =>
953+
if s.primitive() == Primitive::F64 =>
950954
{
951955
cx.type_i64()
952956
}
@@ -958,7 +962,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
958962
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
959963
Abi::Scalar(s),
960964
) => {
961-
if let Primitive::Int(Integer::I32, _) = s.value {
965+
if let Primitive::Int(Integer::I32, _) = s.primitive() {
962966
cx.type_f32()
963967
} else {
964968
layout.llvm_type(cx)
@@ -972,19 +976,21 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
972976
),
973977
Abi::Scalar(s),
974978
) => {
975-
if let Primitive::Int(Integer::I64, _) = s.value {
979+
if let Primitive::Int(Integer::I64, _) = s.primitive() {
976980
cx.type_f64()
977981
} else {
978982
layout.llvm_type(cx)
979983
}
980984
}
981-
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => match s.value {
982-
// MIPS only supports register-length arithmetics.
983-
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
984-
Primitive::F32 => cx.type_i32(),
985-
Primitive::F64 => cx.type_i64(),
986-
_ => layout.llvm_type(cx),
987-
},
985+
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
986+
match s.primitive() {
987+
// MIPS only supports register-length arithmetics.
988+
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
989+
Primitive::F32 => cx.type_i32(),
990+
Primitive::F64 => cx.type_i64(),
991+
_ => layout.llvm_type(cx),
992+
}
993+
}
988994
_ => layout.llvm_type(cx),
989995
}
990996
}

compiler/rustc_codegen_llvm/src/builder.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -484,14 +484,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
484484
bx.noundef_metadata(load);
485485
}
486486

487-
match scalar.value {
487+
match scalar.primitive() {
488488
abi::Int(..) => {
489489
if !scalar.is_always_valid(bx) {
490-
bx.range_metadata(load, scalar.valid_range);
490+
bx.range_metadata(load, scalar.valid_range(bx));
491491
}
492492
}
493493
abi::Pointer => {
494-
if !scalar.valid_range.contains(0) {
494+
if !scalar.valid_range(bx).contains(0) {
495495
bx.nonnull_metadata(load);
496496
}
497497

@@ -525,7 +525,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
525525
});
526526
OperandValue::Immediate(self.to_immediate(llval, place.layout))
527527
} else if let abi::Abi::ScalarPair(a, b) = place.layout.abi {
528-
let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
528+
let b_offset = a.size(self).align_to(b.align(self).abi);
529529
let pair_ty = place.layout.llvm_type(self);
530530

531531
let mut load = |i, scalar: abi::Scalar, layout, align, offset| {

compiler/rustc_codegen_llvm/src/common.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,16 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
221221
}
222222

223223
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: &'ll Type) -> &'ll Value {
224-
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(self).bits() };
224+
let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() };
225225
match cv {
226226
Scalar::Int(ScalarInt::ZST) => {
227-
assert_eq!(0, layout.value.size(self).bytes());
227+
assert_eq!(0, layout.size(self).bytes());
228228
self.const_undef(self.type_ix(0))
229229
}
230230
Scalar::Int(int) => {
231-
let data = int.assert_bits(layout.value.size(self));
231+
let data = int.assert_bits(layout.size(self));
232232
let llval = self.const_uint_big(self.type_ix(bitsize), data);
233-
if layout.value == Pointer {
233+
if layout.primitive() == Pointer {
234234
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
235235
} else {
236236
self.const_bitcast(llval, llty)
@@ -269,7 +269,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
269269
1,
270270
)
271271
};
272-
if layout.value != Pointer {
272+
if layout.primitive() != Pointer {
273273
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
274274
} else {
275275
self.const_bitcast(llval, llty)

compiler/rustc_codegen_llvm/src/consts.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
109109
Pointer::new(alloc_id, Size::from_bytes(ptr_offset)),
110110
&cx.tcx,
111111
),
112-
Scalar { value: Primitive::Pointer, valid_range: WrappingRange { start: 0, end: !0 } },
112+
Scalar::Initialized {
113+
value: Primitive::Pointer,
114+
valid_range: WrappingRange { start: 0, end: !0 },
115+
},
113116
cx.type_i8p_ext(address_space),
114117
));
115118
next_offset = offset + pointer_size;

0 commit comments

Comments
 (0)