Skip to content

Commit 7e7aa77

Browse files
committed
Handle pointers with offset for asm const
1 parent 706d967 commit 7e7aa77

3 files changed

Lines changed: 39 additions & 13 deletions

File tree

compiler/rustc_codegen_cranelift/src/global_asm.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
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::{Path, PathBuf};
67
use std::process::{Command, Stdio};
78

89
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
910
use rustc_codegen_ssa::traits::{AsmCodegenMethods, GlobalAsmOperandRef};
10-
use rustc_middle::mir::interpret::{GlobalAlloc, Scalar as ConstScalar};
11+
use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar as ConstScalar};
1112
use rustc_middle::ty::TyCtxt;
1213
use rustc_middle::ty::layout::{
1314
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 = match global_alloc {
128128
GlobalAlloc::Function { instance } => {
@@ -151,6 +151,11 @@ fn codegen_global_asm_inner<'tcx>(
151151
symbol.name.to_owned()
152152
};
153153
global_asm.push_str(&escape_symbol_name(tcx, &symbol_name, span));
154+
155+
if offset != Size::ZERO {
156+
let offset = tcx.sign_extend_to_target_isize(offset.bytes());
157+
write!(global_asm, "{offset:+}").unwrap();
158+
}
154159
}
155160
}
156161
}

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
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;
@@ -11,7 +13,7 @@ use rustc_codegen_ssa::traits::{
1113
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::{DUMMY_SP, 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, true).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 sym = const_syms.remove(0);
514514
// FIXME(@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(sym.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
}
@@ -953,7 +959,6 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
953959

954960
Scalar::Ptr(ptr, _) => {
955961
let (prov, offset) = ptr.prov_and_relative_offset();
956-
assert_eq!(offset.bytes(), 0);
957962
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
958963
let symbol_name = match global_alloc {
959964
GlobalAlloc::Function { instance } => {
@@ -974,6 +979,12 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
974979
}
975980
};
976981
template_str.push_str(symbol_name.name);
982+
983+
if offset != Size::ZERO {
984+
let offset =
985+
self.sign_extend_to_target_isize(offset.bytes());
986+
write!(template_str, "{offset:+}").unwrap();
987+
}
977988
}
978989
}
979990
}

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;
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, false).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
}
@@ -446,7 +451,6 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
446451

447452
ConstScalar::Ptr(ptr, _) => {
448453
let (prov, offset) = ptr.prov_and_relative_offset();
449-
assert_eq!(offset.bytes(), 0);
450454
let global_alloc = self.tcx.global_alloc(prov.alloc_id());
451455
let llval = self.alloc_to_backend(global_alloc, true).unwrap();
452456

@@ -457,6 +461,12 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
457461
.expect("symbol is not valid UTF-8");
458462
template_str
459463
.push_str(&escape_symbol_name(self.tcx, &symbol, span));
464+
465+
if offset != Size::ZERO {
466+
let offset =
467+
self.sign_extend_to_target_isize(offset.bytes());
468+
write!(template_str, "{offset:+}").unwrap();
469+
}
460470
}
461471
}
462472
}

0 commit comments

Comments
 (0)