@@ -210,6 +210,14 @@ impl<'ll> CodegenCx<'ll, '_> {
210210 unsafe { llvm::LLVMConstBitCast(val, ty) }
211211 }
212212
213+ pub(crate) fn const_pointercast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
214+ unsafe { llvm::LLVMConstPointerCast(val, ty) }
215+ }
216+
217+ /// Create a global variable.
218+ ///
219+ /// The returned global variable is a pointer in the default address space for globals.
220+ /// Fails if a symbol with the given name already exists.
213221 pub(crate) fn static_addr_of_mut(
214222 &self,
215223 cv: &'ll Value,
@@ -233,6 +241,34 @@ impl<'ll> CodegenCx<'ll, '_> {
233241 gv
234242 }
235243
244+ /// Create a global constant.
245+ ///
246+ /// The returned global variable is a pointer in the default address space for globals.
247+ pub(crate) fn static_addr_of_impl(
248+ &self,
249+ cv: &'ll Value,
250+ align: Align,
251+ kind: Option<&str>,
252+ ) -> &'ll Value {
253+ if let Some(&gv) = self.const_globals.borrow().get(&cv) {
254+ unsafe {
255+ // Upgrade the alignment in cases where the same constant is used with different
256+ // alignment requirements
257+ let llalign = align.bytes() as u32;
258+ if llalign > llvm::LLVMGetAlignment(gv) {
259+ llvm::LLVMSetAlignment(gv, llalign);
260+ }
261+ }
262+ return gv;
263+ }
264+ let gv = self.static_addr_of_mut(cv, align, kind);
265+ unsafe {
266+ llvm::LLVMSetGlobalConstant(gv, True);
267+ }
268+ self.const_globals.borrow_mut().insert(cv, gv);
269+ gv
270+ }
271+
236272 #[instrument(level = "debug", skip(self))]
237273 pub(crate) fn get_static(&self, def_id: DefId) -> &'ll Value {
238274 let instance = Instance::mono(self.tcx, def_id);
@@ -505,24 +541,15 @@ impl<'ll> CodegenCx<'ll, '_> {
505541}
506542
507543impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
544+ /// Get a pointer to a global variable.
545+ ///
546+ /// The pointer will always be in the default address space. If global variables default to a
547+ /// different address space, an addrspacecast is inserted.
508548 fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value {
509- if let Some(&gv) = self.const_globals.borrow().get(&cv) {
510- unsafe {
511- // Upgrade the alignment in cases where the same constant is used with different
512- // alignment requirements
513- let llalign = align.bytes() as u32;
514- if llalign > llvm::LLVMGetAlignment(gv) {
515- llvm::LLVMSetAlignment(gv, llalign);
516- }
517- }
518- return gv;
519- }
520- let gv = self.static_addr_of_mut(cv, align, kind);
521- unsafe {
522- llvm::LLVMSetGlobalConstant(gv, True);
523- }
524- self.const_globals.borrow_mut().insert(cv, gv);
525- gv
549+ let gv = self.static_addr_of_impl(cv, align, kind);
550+ // static_addr_of_impl returns the bare global variable, which might not be in the default
551+ // address space. Cast to the default address space if necessary.
552+ self.const_pointercast(gv, self.type_ptr())
526553 }
527554
528555 fn codegen_static(&self, def_id: DefId) {
0 commit comments