Skip to content

Commit d1faee2

Browse files
committed
Handle pointers with offset for asm const
1 parent 0bd2c42 commit d1faee2

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

compiler/rustc_codegen_cranelift/src/global_asm.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
22
//! standalone executable.
33
4+
use std::fmt::Write as _;
45
use std::io::Write;
56
use std::path::PathBuf;
67
use std::process::{Command, Stdio};
78
use std::sync::Arc;
89

910
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
1011
use rustc_codegen_ssa::traits::{AsmCodegenMethods, GlobalAsmOperandRef};
11-
use rustc_middle::mir::interpret::{GlobalAlloc, Scalar as ConstScalar};
12+
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar as ConstScalar};
1213
use rustc_middle::ty::TyCtxt;
1314
use rustc_middle::ty::layout::{
1415
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -122,7 +123,6 @@ fn codegen_global_asm_inner<'tcx>(
122123

123124
ConstScalar::Ptr(ptr, _) => {
124125
let (prov, offset) = ptr.prov_and_relative_offset();
125-
assert_eq!(offset.bytes(), 0);
126126
let global_alloc = tcx.global_alloc(prov.alloc_id());
127127
let symbol_name = match global_alloc {
128128
GlobalAlloc::Function { instance } => {
@@ -145,7 +145,13 @@ fn codegen_global_asm_inner<'tcx>(
145145
| GlobalAlloc::VTable(..)
146146
| GlobalAlloc::TypeId { .. } => unreachable!(),
147147
};
148+
148149
global_asm.push_str(symbol_name.name);
150+
151+
if offset != Size::ZERO {
152+
let offset = tcx.sign_extend_to_target_isize(offset.bytes());
153+
write!(global_asm, "{offset:+}").unwrap();
154+
}
149155
}
150156
}
151157
}

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
// cSpell:ignoreRegExp [afkspqvwy]reg
22

33
use std::borrow::Cow;
4+
use std::fmt::Write;
45

56
use gccjit::{LValue, RValue, ToRValue, Type};
7+
use rustc_abi::Size;
68
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
79
use rustc_codegen_ssa::mir::operand::OperandValue;
810
use rustc_codegen_ssa::mir::place::PlaceRef;
911
use rustc_codegen_ssa::traits::{
1012
AsmBuilderMethods, AsmCodegenMethods, BaseTypeCodegenMethods, BuilderMethods,
11-
GlobalAsmOperandRef, InlineAsmOperandRef, ConstCodegenMethods,
13+
ConstCodegenMethods, GlobalAsmOperandRef, InlineAsmOperandRef,
1214
};
1315
use rustc_middle::bug;
14-
use rustc_middle::mir::interpret::{GlobalAlloc, Scalar};
16+
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
1517
use rustc_middle::ty::Instance;
1618
use rustc_middle::ty::layout::LayoutOf;
1719
use rustc_span::Span;
@@ -405,8 +407,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
405407
InlineAsmOperandRef::Const { value, ty: _ } => match value {
406408
Scalar::Int(_) => (),
407409
Scalar::Ptr(ptr, _) => {
408-
let (prov, offset) = ptr.prov_and_relative_offset();
409-
assert_eq!(offset.bytes(), 0);
410+
let (prov, _) = ptr.prov_and_relative_offset();
410411
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
411412
let (val, sym) = self.cx.alloc_to_backend(global_alloc).unwrap();
412413
const_syms.push(sym.unwrap());
@@ -509,12 +510,17 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
509510

510511
Scalar::Ptr(ptr, _) => {
511512
let (_, offset) = ptr.prov_and_relative_offset();
512-
assert_eq!(offset.bytes(), 0);
513513
let instance = const_syms.remove(0);
514514
// TODO(@Amanieu): Additional mangling is needed on
515515
// some targets to add a leading underscore (Mach-O)
516516
// or byte count suffixes (x86 Windows).
517517
template_str.push_str(self.tcx.symbol_name(instance).name);
518+
519+
if offset != Size::ZERO {
520+
let offset =
521+
self.sign_extend_to_target_isize(offset.bytes());
522+
write!(template_str, "{offset:+}").unwrap();
523+
}
518524
}
519525
}
520526
}
@@ -922,7 +928,6 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
922928

923929
Scalar::Ptr(ptr, _) => {
924930
let (prov, offset) = ptr.prov_and_relative_offset();
925-
assert_eq!(offset.bytes(), 0);
926931
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
927932
let symbol_name = match global_alloc {
928933
GlobalAlloc::Function { instance } => {
@@ -934,14 +939,21 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
934939
self.tcx.symbol_name(instance)
935940
}
936941
_ => {
937-
let (_, syms) = self.alloc_to_backend(global_alloc).unwrap();
942+
let (_, syms) =
943+
self.alloc_to_backend(global_alloc).unwrap();
938944
// TODO(antoyo): set the global variable as used.
939945
// TODO(@Amanieu): Additional mangling is needed on
940946
// some targets to add a leading underscore (Mach-O).
941947
self.tcx.symbol_name(syms.unwrap())
942948
}
943949
};
944950
template_str.push_str(symbol_name.name);
951+
952+
if offset != Size::ZERO {
953+
let offset =
954+
self.sign_extend_to_target_isize(offset.bytes());
955+
write!(template_str, "{offset:+}").unwrap();
956+
}
945957
}
946958
}
947959
}

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use std::assert_matches::assert_matches;
2+
use std::fmt::Write;
23

3-
use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar};
4+
use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar, Size};
45
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
56
use rustc_codegen_ssa::mir::operand::OperandValue;
67
use rustc_codegen_ssa::traits::*;
78
use rustc_data_structures::fx::FxHashMap;
8-
use rustc_middle::mir::interpret::Scalar as ConstScalar;
9+
use rustc_middle::mir::interpret::{PointerArithmetic, Scalar as ConstScalar};
910
use rustc_middle::ty::Instance;
1011
use rustc_middle::ty::layout::TyAndLayout;
1112
use rustc_middle::{bug, span_bug};
@@ -161,8 +162,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
161162
InlineAsmOperandRef::Const { value, ty: _ } => match value {
162163
ConstScalar::Int(_) => (),
163164
ConstScalar::Ptr(ptr, _) => {
164-
let (prov, offset) = ptr.prov_and_relative_offset();
165-
assert_eq!(offset.bytes(), 0);
165+
let (prov, _) = ptr.prov_and_relative_offset();
166166
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
167167
let (value, _) = self.cx.alloc_to_backend(global_alloc).unwrap();
168168
inputs.push(value);
@@ -226,11 +226,16 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
226226
}
227227
ConstScalar::Ptr(ptr, _) => {
228228
let (_, offset) = ptr.prov_and_relative_offset();
229-
assert_eq!(offset.bytes(), 0);
230229

231230
// Only emit the raw symbol name
232231
template_str
233232
.push_str(&format!("${{{}:c}}", op_idx[&operand_idx]));
233+
234+
if offset != Size::ZERO {
235+
let offset =
236+
self.sign_extend_to_target_isize(offset.bytes());
237+
write!(template_str, "{offset:+}").unwrap();
238+
}
234239
}
235240
}
236241
}
@@ -444,7 +449,6 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
444449

445450
ConstScalar::Ptr(ptr, _) => {
446451
let (prov, offset) = ptr.prov_and_relative_offset();
447-
assert_eq!(offset.bytes(), 0);
448452
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
449453
let (llval, sym) = self.alloc_to_backend(global_alloc).unwrap();
450454
assert!(sym.is_some());
@@ -455,6 +459,12 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
455459
})
456460
.expect("symbol is not valid UTF-8");
457461
template_str.push_str(&symbol);
462+
463+
if offset != Size::ZERO {
464+
let offset =
465+
self.sign_extend_to_target_isize(offset.bytes());
466+
write!(template_str, "{offset:+}").unwrap();
467+
}
458468
}
459469
}
460470
}

0 commit comments

Comments
 (0)