about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_abi/src/lib.rs24
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs3
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs16
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs13
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs17
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs3
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs222
-rw-r--r--compiler/rustc_target/src/abi/call/loongarch.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/riscv.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs2
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs4
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs8
25 files changed, 193 insertions, 173 deletions
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index b9ec7d2ee74..fe65ad9c6cb 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -267,6 +267,9 @@ impl TargetDataLayout {
                 ["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
                 ["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
                 ["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
+                // FIXME(erikdesjardins): we should be parsing nonzero address spaces
+                // this will require replacing TargetDataLayout::{pointer_size,pointer_align}
+                // with e.g. `fn pointer_size_in(AddressSpace)`
                 [p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
                     dl.pointer_size = size(s, p)?;
                     dl.pointer_align = align(a, p)?;
@@ -861,7 +864,7 @@ pub enum Primitive {
     Int(Integer, bool),
     F32,
     F64,
-    Pointer,
+    Pointer(AddressSpace),
 }
 
 impl Primitive {
@@ -872,7 +875,10 @@ impl Primitive {
             Int(i, _) => i.size(),
             F32 => Size::from_bits(32),
             F64 => Size::from_bits(64),
-            Pointer => dl.pointer_size,
+            // FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
+            // different address spaces can have different sizes
+            // (but TargetDataLayout doesn't currently parse that part of the DL string)
+            Pointer(_) => dl.pointer_size,
         }
     }
 
@@ -883,14 +889,12 @@ impl Primitive {
             Int(i, _) => i.align(dl),
             F32 => dl.f32_align,
             F64 => dl.f64_align,
-            Pointer => dl.pointer_align,
+            // FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
+            // different address spaces can have different alignments
+            // (but TargetDataLayout doesn't currently parse that part of the DL string)
+            Pointer(_) => dl.pointer_align,
         }
     }
-
-    #[inline]
-    pub fn is_ptr(self) -> bool {
-        matches!(self, Pointer)
-    }
 }
 
 /// Inclusive wrap-around range of valid values, that is, if
@@ -1176,7 +1180,8 @@ impl FieldsShape {
 /// An identifier that specifies the address space that some operation
 /// should operate on. Special address spaces have an effect on code generation,
 /// depending on the target and the address spaces it implements.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
 pub struct AddressSpace(pub u32);
 
 impl AddressSpace {
@@ -1456,7 +1461,6 @@ pub struct PointeeInfo {
     pub size: Size,
     pub align: Align,
     pub safe: Option<PointerKind>,
-    pub address_space: AddressSpace,
 }
 
 /// Used in `might_permit_raw_init` to indicate the kind of initialisation
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 2dcd42fbd8f..63ed10cdfcc 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -35,7 +35,8 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
         },
         Primitive::F32 => types::F32,
         Primitive::F64 => types::F64,
-        Primitive::Pointer => pointer_ty(tcx),
+        // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+        Primitive::Pointer(_) => pointer_ty(tcx),
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index a92242b2615..e88c12716ec 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -709,7 +709,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
                         bx.range_metadata(load, vr);
                     }
                 }
-                abi::Pointer if vr.start < vr.end && !vr.contains(0) => {
+                abi::Pointer(_) if vr.start < vr.end && !vr.contains(0) => {
                     bx.nonnull_metadata(load);
                 }
                 _ => {}
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index 0afc56b4494..c939da9cec3 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -211,7 +211,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
                 let base_addr = self.const_bitcast(base_addr, self.usize_type);
                 let offset = self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
                 let ptr = self.const_bitcast(base_addr + offset, ptr_type);
-                if layout.primitive() != Pointer {
+                if !matches!(layout.primitive(), Pointer(_)) {
                     self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
                 }
                 else {
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index ea8ab761146..ba64b1f6389 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -7,9 +7,9 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}
 use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint};
+use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar as InterpScalar, read_target_uint};
 use rustc_span::def_id::DefId;
-use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange};
+use rustc_target::abi::{self, AddressSpace, Align, HasDataLayout, Primitive, Size, WrappingRange};
 
 use crate::base;
 use crate::context::CodegenCx;
@@ -322,13 +322,21 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
             )
             .expect("const_alloc_to_llvm: could not read relocation pointer")
             as u64;
+
+        let address_space = match cx.tcx.global_alloc(alloc_id) {
+            GlobalAlloc::Function(..) => cx.data_layout().instruction_address_space,
+            GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) | GlobalAlloc::VTable(..) => {
+                AddressSpace::DATA
+            }
+        };
+
         llvals.push(cx.scalar_to_backend(
             InterpScalar::from_pointer(
                 interpret::Pointer::new(alloc_id, Size::from_bytes(ptr_offset)),
                 &cx.tcx,
             ),
-            abi::Scalar::Initialized { value: Primitive::Pointer, valid_range: WrappingRange::full(dl.pointer_size) },
-            cx.type_i8p(),
+            abi::Scalar::Initialized { value: Primitive::Pointer(address_space), valid_range: WrappingRange::full(dl.pointer_size) },
+            cx.type_i8p_ext(address_space),
         ));
         next_offset = offset + pointer_size;
     }
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 524d10fb5e2..1326af670cd 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -253,7 +253,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
             Int(i, false) => cx.type_from_unsigned_integer(i),
             F32 => cx.type_f32(),
             F64 => cx.type_f64(),
-            Pointer => {
+            Pointer(address_space) => {
                 // If we know the alignment, pick something better than i8.
                 let pointee =
                     if let Some(pointee) = self.pointee_info_at(cx, offset) {
@@ -262,7 +262,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
                     else {
                         cx.type_i8()
                     };
-                cx.type_ptr_to(pointee)
+                cx.type_ptr_to_ext(pointee, address_space)
             }
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 52c8b51796c..d9f8170a3cf 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -849,6 +849,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
 /// Helper function to get the LLVM type for a Scalar. Pointers are returned as
 /// the equivalent integer type.
 fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Type {
+    let dl = &cx.tcx.data_layout;
     match scalar.primitive() {
         Primitive::Int(Integer::I8, _) => cx.type_i8(),
         Primitive::Int(Integer::I16, _) => cx.type_i16(),
@@ -856,7 +857,8 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty
         Primitive::Int(Integer::I64, _) => cx.type_i64(),
         Primitive::F32 => cx.type_f32(),
         Primitive::F64 => cx.type_f64(),
-        Primitive::Pointer => cx.type_isize(),
+        // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+        Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
         _ => unreachable!(),
     }
 }
@@ -868,6 +870,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
     reg: InlineAsmRegClass,
     layout: &TyAndLayout<'tcx>,
 ) -> &'ll Value {
+    let dl = &bx.tcx.data_layout;
     match (reg, layout.abi) {
         (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.primitive() {
@@ -881,8 +884,10 @@ fn llvm_fixup_input<'ll, 'tcx>(
             let elem_ty = llvm_asm_scalar_type(bx.cx, s);
             let count = 16 / layout.size.bytes();
             let vec_ty = bx.cx.type_vector(elem_ty, count);
-            if let Primitive::Pointer = s.primitive() {
-                value = bx.ptrtoint(value, bx.cx.type_isize());
+            // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+            if let Primitive::Pointer(_) = s.primitive() {
+                let t = bx.type_from_integer(dl.ptr_sized_integer());
+                value = bx.ptrtoint(value, t);
             }
             bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
         }
@@ -958,7 +963,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
         }
         (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
             value = bx.extract_element(value, bx.const_i32(0));
-            if let Primitive::Pointer = s.primitive() {
+            if let Primitive::Pointer(_) = s.primitive() {
                 value = bx.inttoptr(value, layout.llvm_type(bx.cx));
             }
             value
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 5e98deae48a..0f33b985489 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -511,7 +511,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                         bx.range_metadata(load, scalar.valid_range(bx));
                     }
                 }
-                abi::Pointer => {
+                abi::Pointer(_) => {
                     if !scalar.valid_range(bx).contains(0) {
                         bx.nonnull_metadata(load);
                     }
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index acee9134fb9..edb1c160626 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -236,7 +236,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             Scalar::Int(int) => {
                 let data = int.assert_bits(layout.size(self));
                 let llval = self.const_uint_big(self.type_ix(bitsize), data);
-                if layout.primitive() == Pointer {
+                if matches!(layout.primitive(), Pointer(_)) {
                     unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
                 } else {
                     self.const_bitcast(llval, llty)
@@ -284,7 +284,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         1,
                     )
                 };
-                if layout.primitive() != Pointer {
+                if !matches!(layout.primitive(), Pointer(_)) {
                     unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
                 } else {
                     self.const_bitcast(llval, llty)
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 16467b614fe..2f630b32ffe 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -111,7 +111,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
                 &cx.tcx,
             ),
             Scalar::Initialized {
-                value: Primitive::Pointer,
+                value: Primitive::Pointer(address_space),
                 valid_range: WrappingRange::full(dl.pointer_size),
             },
             cx.type_i8p_ext(address_space),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index 564ab351bd4..54e850f2599 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -122,7 +122,8 @@ fn tag_base_type<'ll, 'tcx>(
                 Primitive::Int(t, _) => t,
                 Primitive::F32 => Integer::I32,
                 Primitive::F64 => Integer::I64,
-                Primitive::Pointer => {
+                // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+                Primitive::Pointer(_) => {
                     // If the niche is the NULL value of a reference, then `discr_enum_ty` will be
                     // a RawPtr. CodeView doesn't know what to do with enums whose base type is a
                     // pointer so we fix this up to just be `usize`.
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index a6a75eff9a3..dd89c4c59c1 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -149,7 +149,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                                     emit_va_arg(self, args[0], ret_ty)
                                 }
                             }
-                            Primitive::F64 | Primitive::Pointer => {
+                            Primitive::F64 | Primitive::Pointer(_) => {
                                 emit_va_arg(self, args[0], ret_ty)
                             }
                             // `va_arg` should never be used with the return type f32.
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index 75cd5df9723..c73d233b767 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -7,7 +7,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Ty, TypeVisitable};
-use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
+use rustc_target::abi::{Abi, Align, FieldsShape};
 use rustc_target::abi::{Int, Pointer, F32, F64};
 use rustc_target::abi::{PointeeInfo, Scalar, Size, TyAbiInterface, Variants};
 use smallvec::{smallvec, SmallVec};
@@ -312,14 +312,13 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
             Int(i, _) => cx.type_from_integer(i),
             F32 => cx.type_f32(),
             F64 => cx.type_f64(),
-            Pointer => {
+            Pointer(address_space) => {
                 // If we know the alignment, pick something better than i8.
-                let (pointee, address_space) =
-                    if let Some(pointee) = self.pointee_info_at(cx, offset) {
-                        (cx.type_pointee_for_align(pointee.align), pointee.address_space)
-                    } else {
-                        (cx.type_i8(), AddressSpace::DATA)
-                    };
+                let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
+                    cx.type_pointee_for_align(pointee.align)
+                } else {
+                    cx.type_i8()
+                };
                 cx.type_ptr_to_ext(pointee, address_space)
             }
         }
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 978aff511bf..e2106f8b5c5 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1801,8 +1801,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         match (src.layout.abi, dst.layout.abi) {
             (abi::Abi::Scalar(src_scalar), abi::Abi::Scalar(dst_scalar)) => {
                 // HACK(eddyb) LLVM doesn't like `bitcast`s between pointers and non-pointers.
-                let src_is_ptr = src_scalar.primitive() == abi::Pointer;
-                let dst_is_ptr = dst_scalar.primitive() == abi::Pointer;
+                let src_is_ptr = matches!(src_scalar.primitive(), abi::Pointer(_));
+                let dst_is_ptr = matches!(dst_scalar.primitive(), abi::Pointer(_));
                 if src_is_ptr == dst_is_ptr {
                     assert_eq!(src.layout.size, dst.layout.size);
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index fbe30154a7c..cf02f59f67b 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, Ty};
-use rustc_target::abi::{Abi, Align, FieldsShape, Int, TagEncoding};
+use rustc_target::abi::{Abi, Align, FieldsShape, Int, Pointer, TagEncoding};
 use rustc_target::abi::{VariantIdx, Variants};
 
 #[derive(Copy, Clone, Debug)]
@@ -209,6 +209,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         cast_to: Ty<'tcx>,
     ) -> V {
+        let dl = &bx.tcx().data_layout;
         let cast_to_layout = bx.cx().layout_of(cast_to);
         let cast_to_size = cast_to_layout.layout.size();
         let cast_to = bx.cx().immediate_backend_type(cast_to_layout);
@@ -250,12 +251,14 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
             TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
                 // Cast to an integer so we don't have to treat a pointer as a
                 // special case.
-                let (tag, tag_llty) = if tag_scalar.primitive().is_ptr() {
-                    let t = bx.type_isize();
-                    let tag = bx.ptrtoint(tag_imm, t);
-                    (tag, t)
-                } else {
-                    (tag_imm, bx.cx().immediate_backend_type(tag_op.layout))
+                let (tag, tag_llty) = match tag_scalar.primitive() {
+                    // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+                    Pointer(_) => {
+                        let t = bx.type_from_integer(dl.ptr_sized_integer());
+                        let tag = bx.ptrtoint(tag_imm, t);
+                        (tag, t)
+                    }
+                    _ => (tag_imm, bx.cx().immediate_backend_type(tag_op.layout)),
                 };
 
                 let tag_size = tag_scalar.size(bx.cx());
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index befc0928f3d..a1b3985dce4 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -319,7 +319,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 assert_eq!(size, mplace.layout.size, "abi::Scalar size does not match layout size");
                 let scalar = alloc.read_scalar(
                     alloc_range(Size::ZERO, size),
-                    /*read_provenance*/ s.is_ptr(),
+                    /*read_provenance*/ matches!(s, abi::Pointer(_)),
                 )?;
                 Some(ImmTy { imm: scalar.into(), layout: mplace.layout })
             }
@@ -335,11 +335,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields
                 let a_val = alloc.read_scalar(
                     alloc_range(Size::ZERO, a_size),
-                    /*read_provenance*/ a.is_ptr(),
+                    /*read_provenance*/ matches!(a, abi::Pointer(_)),
                 )?;
                 let b_val = alloc.read_scalar(
                     alloc_range(b_offset, b_size),
-                    /*read_provenance*/ b.is_ptr(),
+                    /*read_provenance*/ matches!(b, abi::Pointer(_)),
                 )?;
                 Some(ImmTy { imm: Immediate::ScalarPair(a_val, b_val), layout: mplace.layout })
             }
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 3c873024c92..2c76582f2ec 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -38,6 +38,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) {
         let tcx = self.tcx;
+        let dl = &tcx.data_layout;
         let span = tcx.hir().span(hir_id);
         let normalize = |ty| {
             let ty = self.resolve_vars_if_possible(ty);
@@ -69,7 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Special-case transmuting from `typeof(function)` and
             // `Option<typeof(function)>` to present a clearer error.
             let from = unpack_option_like(tcx, from);
-            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&tcx) {
+            if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) {
                 struct_span_err!(tcx.sess, span, E0591, "can't transmute zero-sized type")
                     .note(&format!("source type: {from}"))
                     .note(&format!("target type: {to}"))
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index dfd016569c2..66b9d96e695 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -128,7 +128,8 @@ impl PrimitiveExt for Primitive {
             Int(i, signed) => i.to_ty(tcx, signed),
             F32 => tcx.types.f32,
             F64 => tcx.types.f64,
-            Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
+            // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+            Pointer(_) => tcx.mk_mut_ptr(tcx.mk_unit()),
         }
     }
 
@@ -138,7 +139,11 @@ impl PrimitiveExt for Primitive {
     fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             Int(i, signed) => i.to_ty(tcx, signed),
-            Pointer => tcx.types.usize,
+            // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+            Pointer(_) => {
+                let signed = false;
+                tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
+            }
             F32 | F64 => bug!("floats do not have an int type"),
         }
     }
@@ -812,132 +817,125 @@ where
         let tcx = cx.tcx();
         let param_env = cx.param_env();
 
-        let addr_space_of_ty = |ty: Ty<'tcx>| {
-            if ty.is_fn() { cx.data_layout().instruction_address_space } else { AddressSpace::DATA }
-        };
-
-        let pointee_info = match *this.ty.kind() {
-            ty::RawPtr(mt) if offset.bytes() == 0 => {
-                tcx.layout_of(param_env.and(mt.ty)).ok().map(|layout| PointeeInfo {
-                    size: layout.size,
-                    align: layout.align.abi,
-                    safe: None,
-                    address_space: addr_space_of_ty(mt.ty),
-                })
-            }
-            ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
-                tcx.layout_of(param_env.and(tcx.mk_fn_ptr(fn_sig))).ok().map(|layout| PointeeInfo {
-                    size: layout.size,
-                    align: layout.align.abi,
-                    safe: None,
-                    address_space: cx.data_layout().instruction_address_space,
-                })
-            }
-            ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
-                let address_space = addr_space_of_ty(ty);
-                let kind = if tcx.sess.opts.optimize == OptLevel::No {
-                    // Use conservative pointer kind if not optimizing. This saves us the
-                    // Freeze/Unpin queries, and can save time in the codegen backend (noalias
-                    // attributes in LLVM have compile-time cost even in unoptimized builds).
-                    PointerKind::SharedMutable
-                } else {
-                    match mt {
-                        hir::Mutability::Not => {
-                            if ty.is_freeze(tcx, cx.param_env()) {
-                                PointerKind::Frozen
-                            } else {
-                                PointerKind::SharedMutable
+        let pointee_info =
+            match *this.ty.kind() {
+                ty::RawPtr(mt) if offset.bytes() == 0 => {
+                    tcx.layout_of(param_env.and(mt.ty)).ok().map(|layout| PointeeInfo {
+                        size: layout.size,
+                        align: layout.align.abi,
+                        safe: None,
+                    })
+                }
+                ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
+                    tcx.layout_of(param_env.and(tcx.mk_fn_ptr(fn_sig))).ok().map(|layout| {
+                        PointeeInfo { size: layout.size, align: layout.align.abi, safe: None }
+                    })
+                }
+                ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
+                    let kind = if tcx.sess.opts.optimize == OptLevel::No {
+                        // Use conservative pointer kind if not optimizing. This saves us the
+                        // Freeze/Unpin queries, and can save time in the codegen backend (noalias
+                        // attributes in LLVM have compile-time cost even in unoptimized builds).
+                        PointerKind::SharedMutable
+                    } else {
+                        match mt {
+                            hir::Mutability::Not => {
+                                if ty.is_freeze(tcx, cx.param_env()) {
+                                    PointerKind::Frozen
+                                } else {
+                                    PointerKind::SharedMutable
+                                }
                             }
-                        }
-                        hir::Mutability::Mut => {
-                            // References to self-referential structures should not be considered
-                            // noalias, as another pointer to the structure can be obtained, that
-                            // is not based-on the original reference. We consider all !Unpin
-                            // types to be potentially self-referential here.
-                            if ty.is_unpin(tcx, cx.param_env()) {
-                                PointerKind::UniqueBorrowed
-                            } else {
-                                PointerKind::UniqueBorrowedPinned
+                            hir::Mutability::Mut => {
+                                // References to self-referential structures should not be considered
+                                // noalias, as another pointer to the structure can be obtained, that
+                                // is not based-on the original reference. We consider all !Unpin
+                                // types to be potentially self-referential here.
+                                if ty.is_unpin(tcx, cx.param_env()) {
+                                    PointerKind::UniqueBorrowed
+                                } else {
+                                    PointerKind::UniqueBorrowedPinned
+                                }
                             }
                         }
-                    }
-                };
+                    };
 
-                tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo {
-                    size: layout.size,
-                    align: layout.align.abi,
-                    safe: Some(kind),
-                    address_space,
-                })
-            }
+                    tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo {
+                        size: layout.size,
+                        align: layout.align.abi,
+                        safe: Some(kind),
+                    })
+                }
 
-            _ => {
-                let mut data_variant = match this.variants {
-                    // Within the discriminant field, only the niche itself is
-                    // always initialized, so we only check for a pointer at its
-                    // offset.
-                    //
-                    // If the niche is a pointer, it's either valid (according
-                    // to its type), or null (which the niche field's scalar
-                    // validity range encodes). This allows using
-                    // `dereferenceable_or_null` for e.g., `Option<&T>`, and
-                    // this will continue to work as long as we don't start
-                    // using more niches than just null (e.g., the first page of
-                    // the address space, or unaligned pointers).
-                    Variants::Multiple {
-                        tag_encoding: TagEncoding::Niche { untagged_variant, .. },
-                        tag_field,
-                        ..
-                    } if this.fields.offset(tag_field) == offset => {
-                        Some(this.for_variant(cx, untagged_variant))
-                    }
-                    _ => Some(this),
-                };
+                _ => {
+                    let mut data_variant = match this.variants {
+                        // Within the discriminant field, only the niche itself is
+                        // always initialized, so we only check for a pointer at its
+                        // offset.
+                        //
+                        // If the niche is a pointer, it's either valid (according
+                        // to its type), or null (which the niche field's scalar
+                        // validity range encodes). This allows using
+                        // `dereferenceable_or_null` for e.g., `Option<&T>`, and
+                        // this will continue to work as long as we don't start
+                        // using more niches than just null (e.g., the first page of
+                        // the address space, or unaligned pointers).
+                        Variants::Multiple {
+                            tag_encoding: TagEncoding::Niche { untagged_variant, .. },
+                            tag_field,
+                            ..
+                        } if this.fields.offset(tag_field) == offset => {
+                            Some(this.for_variant(cx, untagged_variant))
+                        }
+                        _ => Some(this),
+                    };
 
-                if let Some(variant) = data_variant {
-                    // We're not interested in any unions.
-                    if let FieldsShape::Union(_) = variant.fields {
-                        data_variant = None;
+                    if let Some(variant) = data_variant {
+                        // We're not interested in any unions.
+                        if let FieldsShape::Union(_) = variant.fields {
+                            data_variant = None;
+                        }
                     }
-                }
 
-                let mut result = None;
-
-                if let Some(variant) = data_variant {
-                    let ptr_end = offset + Pointer.size(cx);
-                    for i in 0..variant.fields.count() {
-                        let field_start = variant.fields.offset(i);
-                        if field_start <= offset {
-                            let field = variant.field(cx, i);
-                            result = field.to_result().ok().and_then(|field| {
-                                if ptr_end <= field_start + field.size {
-                                    // We found the right field, look inside it.
-                                    let field_info =
-                                        field.pointee_info_at(cx, offset - field_start);
-                                    field_info
-                                } else {
-                                    None
+                    let mut result = None;
+
+                    if let Some(variant) = data_variant {
+                        // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
+                        // (requires passing in the expected address space from the caller)
+                        let ptr_end = offset + Pointer(AddressSpace::DATA).size(cx);
+                        for i in 0..variant.fields.count() {
+                            let field_start = variant.fields.offset(i);
+                            if field_start <= offset {
+                                let field = variant.field(cx, i);
+                                result = field.to_result().ok().and_then(|field| {
+                                    if ptr_end <= field_start + field.size {
+                                        // We found the right field, look inside it.
+                                        let field_info =
+                                            field.pointee_info_at(cx, offset - field_start);
+                                        field_info
+                                    } else {
+                                        None
+                                    }
+                                });
+                                if result.is_some() {
+                                    break;
                                 }
-                            });
-                            if result.is_some() {
-                                break;
                             }
                         }
                     }
-                }
 
-                // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
-                if let Some(ref mut pointee) = result {
-                    if let ty::Adt(def, _) = this.ty.kind() {
-                        if def.is_box() && offset.bytes() == 0 {
-                            pointee.safe = Some(PointerKind::UniqueOwned);
+                    // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
+                    if let Some(ref mut pointee) = result {
+                        if let ty::Adt(def, _) = this.ty.kind() {
+                            if def.is_box() && offset.bytes() == 0 {
+                                pointee.safe = Some(PointerKind::UniqueOwned);
+                            }
                         }
                     }
-                }
 
-                result
-            }
-        };
+                    result
+                }
+            };
 
         debug!(
             "pointee_info_at (offset={:?}, type kind: {:?}) => {:?}",
diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs
index 4a2d39cc700..247256f076b 100644
--- a/compiler/rustc_target/src/abi/call/loongarch.rs
+++ b/compiler/rustc_target/src/abi/call/loongarch.rs
@@ -39,7 +39,7 @@ where
 {
     match arg_layout.abi {
         Abi::Scalar(scalar) => match scalar.primitive() {
-            abi::Int(..) | abi::Pointer => {
+            abi::Int(..) | abi::Pointer(_) => {
                 if arg_layout.size.bits() > xlen {
                     return Err(CannotUseFpConv);
                 }
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 3b8c867d35b..a0730fbb650 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -346,7 +346,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
             // The primitive for this algorithm.
             Abi::Scalar(scalar) => {
                 let kind = match scalar.primitive() {
-                    abi::Int(..) | abi::Pointer => RegKind::Integer,
+                    abi::Int(..) | abi::Pointer(_) => RegKind::Integer,
                     abi::F32 | abi::F64 => RegKind::Float,
                 };
                 Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs
index 34280d38e34..d90dce2a087 100644
--- a/compiler/rustc_target/src/abi/call/riscv.rs
+++ b/compiler/rustc_target/src/abi/call/riscv.rs
@@ -45,7 +45,7 @@ where
 {
     match arg_layout.abi {
         Abi::Scalar(scalar) => match scalar.primitive() {
-            abi::Int(..) | abi::Pointer => {
+            abi::Int(..) | abi::Pointer(_) => {
                 if arg_layout.size.bits() > xlen {
                     return Err(CannotUseFpConv);
                 }
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index 0c7a4f32461..cbed5b4afc1 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -83,7 +83,7 @@ where
         (abi::F32, _) => offset += Reg::f32().size,
         (_, abi::F64) => offset += Reg::f64().size,
         (abi::Int(i, _signed), _) => offset += i.size(),
-        (abi::Pointer, _) => offset += Reg::i64().size,
+        (abi::Pointer(_), _) => offset += Reg::i64().size,
         _ => {}
     }
 
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index c0c071a614f..9427f27d1b7 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -50,7 +50,7 @@ where
             Abi::Uninhabited => return Ok(()),
 
             Abi::Scalar(scalar) => match scalar.primitive() {
-                abi::Int(..) | abi::Pointer => Class::Int,
+                abi::Int(..) | abi::Pointer(_) => Class::Int,
                 abi::F32 | abi::F64 => Class::Sse,
             },
 
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 91a505a72fa..e47e68e0670 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -244,7 +244,7 @@ fn adjust_for_rust_scalar<'tcx>(
     }
 
     // Only pointer types handled below.
-    let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return };
+    let Scalar::Initialized { value: Pointer(_), valid_range} = scalar else { return };
 
     if !valid_range.contains(0) {
         attrs.set(ArgAttribute::NonNull);
@@ -479,7 +479,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
             }
 
             let size = arg.layout.size;
-            if arg.layout.is_unsized() || size > Pointer.size(cx) {
+            if arg.layout.is_unsized() || size > Pointer(AddressSpace::DATA).size(cx) {
                 arg.make_indirect();
             } else {
                 // We want to pass small aggregates as immediates, but using
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 6aa016133ca..0f25579c7bf 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -134,7 +134,7 @@ fn layout_of_uncached<'tcx>(
             ty::FloatTy::F64 => F64,
         }),
         ty::FnPtr(_) => {
-            let mut ptr = scalar_unit(Pointer);
+            let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
             ptr.valid_range_mut().start = 1;
             tcx.intern_layout(LayoutS::scalar(cx, ptr))
         }
@@ -144,7 +144,7 @@ fn layout_of_uncached<'tcx>(
 
         // Potentially-wide pointers.
         ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-            let mut data_ptr = scalar_unit(Pointer);
+            let mut data_ptr = scalar_unit(Pointer(AddressSpace::DATA));
             if !ty.is_unsafe_ptr() {
                 data_ptr.valid_range_mut().start = 1;
             }
@@ -178,7 +178,7 @@ fn layout_of_uncached<'tcx>(
                     }
                     ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
                     ty::Dynamic(..) => {
-                        let mut vtable = scalar_unit(Pointer);
+                        let mut vtable = scalar_unit(Pointer(AddressSpace::DATA));
                         vtable.valid_range_mut().start = 1;
                         vtable
                     }
@@ -195,7 +195,7 @@ fn layout_of_uncached<'tcx>(
         ty::Dynamic(_, _, ty::DynStar) => {
             let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false));
             data.valid_range_mut().start = 0;
-            let mut vtable = scalar_unit(Pointer);
+            let mut vtable = scalar_unit(Pointer(AddressSpace::DATA));
             vtable.valid_range_mut().start = 1;
             tcx.intern_layout(cx.scalar_pair(data, vtable))
         }