Skip to content

Commit 255b7cd

Browse files
committed
Auto merge of #158416 - JonathanBrouwer:rollup-yCDE4Az, r=JonathanBrouwer
Rollup of 15 pull requests Successful merges: - #155535 (export symbols: support macos/windows(32/64)) - #158253 (codegen_ssa: multiply scalable vec size by `vscale`) - #158308 (Fix bug when rustdoc "go to only result" setting is not working as expected") - #158345 (Use `transmute_neo` in `assume_init`) - #158369 (std: abort when `resume_unwind` is called inside the panic hook) - #158374 (disallow tail calling extern "rust-call" functions) - #158380 (Revert "rebuild LLVM when `bootstrap.toml` config changes") - #154398 (Add test for async Send with PhantomData<*mut ()> + unsafe impl Send + dyn Trait) - #157181 (autodiff: stop always needing an alloca) - #158278 (autodiff - typtree cleanups) - #158311 (doc(unstable-book): fix typo "earier" -> "earlier" in default-visibility flag) - #158318 (Make normalization in a test case resilient to dist compilation) - #158338 (Reorganize `tests/ui/issues` [14/N]) - #158343 (Include `Item::const_stability` info in rustdoc JSON.) - #158390 (Fix: auto trait, const trait bound)
2 parents fa36a47 + 65153e0 commit 255b7cd

58 files changed

Lines changed: 1107 additions & 412 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_abi/src/extern_abi.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,16 @@ impl ExternAbi {
343343
// This ABI does not support calls at all (except via assembly).
344344
false
345345
}
346+
Self::RustCall => {
347+
// Argument untupling requires additional support for tail calls to be possible,
348+
// see <https://github.com/rust-lang/rust/pull/158248>. There is no real uses of
349+
// tail calling `extern "rust-call"` functions
350+
false
351+
}
352+
346353
Self::C { .. }
347354
| Self::System { .. }
348355
| Self::Rust
349-
| Self::RustCall
350356
| Self::RustCold
351357
| Self::RustInvalid
352358
| Self::Unadjusted

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
14591459
);
14601460
}
14611461

1462+
fn vscale(&mut self, _: Self::Type) -> Self::Value {
1463+
unimplemented!("`rustc_codegen_gcc` doesn't support scalable vectors yet")
1464+
}
1465+
14621466
fn select(
14631467
&mut self,
14641468
cond: RValue<'gcc>,

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
12261226
}
12271227
}
12281228

1229+
fn vscale(&mut self, ty: &'ll Type) -> &'ll Value {
1230+
unsafe { llvm::LLVMRustBuildVScale(self.llbuilder, ty) }
1231+
}
1232+
12291233
fn select(
12301234
&mut self,
12311235
cond: &'ll Value,

compiler/rustc_codegen_llvm/src/builder/autodiff.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use std::ptr;
33
use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode};
44
use rustc_ast::expand::typetree::FncTree;
55
use rustc_codegen_ssa::common::TypeKind;
6+
use rustc_codegen_ssa::mir::IntrinsicResult;
7+
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
8+
use rustc_codegen_ssa::mir::place::PlaceValue;
69
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
710
use rustc_data_structures::thin_vec::ThinVec;
811
use rustc_hir::attrs::RustcAutodiff;
@@ -11,7 +14,7 @@ use rustc_middle::{bug, ty};
1114
use rustc_target::callconv::PassMode;
1215
use tracing::debug;
1316

14-
use crate::builder::{Builder, PlaceRef, UNNAMED};
17+
use crate::builder::{Builder, UNNAMED};
1518
use crate::context::SimpleCx;
1619
use crate::declare::declare_simple_fn;
1720
use crate::llvm::{self, TRUE, Type, Value};
@@ -296,9 +299,10 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
296299
ret_ty: &'ll Type,
297300
fn_args: &[&'ll Value],
298301
attrs: &RustcAutodiff,
299-
dest: PlaceRef<'tcx, &'ll Value>,
302+
dest_layout: ty::layout::TyAndLayout<'tcx>,
303+
dest_place: Option<PlaceValue<&'ll Value>>,
300304
fnc_tree: FncTree,
301-
) {
305+
) -> IntrinsicResult<'tcx, &'ll Value> {
302306
// We have to pick the name depending on whether we want forward or reverse mode autodiff.
303307
let mut ad_name: String = match attrs.mode {
304308
DiffMode::Forward => "__enzyme_fwddiff",
@@ -381,11 +385,18 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>(
381385
let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None);
382386

383387
let fn_ret_ty = builder.cx.val_ty(call);
384-
if fn_ret_ty != builder.cx.type_void() && fn_ret_ty != builder.cx.type_struct(&[], false) {
388+
if fn_ret_ty == builder.cx.type_void() || fn_ret_ty == builder.cx.type_struct(&[], false) {
385389
// If we return void or an empty struct, then our caller (due to how we generated it)
386390
// does not expect a return value. As such, we have no pointer (or place) into which
387391
// we could store our value, and would store into an undef, which would cause UB.
388392
// As such, we just ignore the return value in those cases.
389-
builder.store_to_place(call, dest.val);
393+
IntrinsicResult::Operand(OperandValue::ZeroSized)
394+
} else if let Some(dest_place) = dest_place {
395+
builder.store_to_place(call, dest_place);
396+
IntrinsicResult::WroteIntoPlace
397+
} else {
398+
IntrinsicResult::Operand(
399+
OperandRef::from_immediate_or_packed_pair(builder, call, dest_layout).val,
400+
)
390401
}
391402
}

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -978,10 +978,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
978978
}
979979

980980
fn intrinsic_call_expects_place_always(&self, name: Symbol) -> bool {
981-
matches!(
982-
name,
983-
sym::autodiff | sym::volatile_load | sym::unaligned_volatile_load | sym::black_box
984-
)
981+
matches!(name, sym::volatile_load | sym::unaligned_volatile_load | sym::black_box)
985982
}
986983
}
987984

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use crate::errors::{
4343
AutoDiffWithoutEnable, AutoDiffWithoutLto, IntrinsicSignatureMismatch, IntrinsicWrongArch,
4444
OffloadWithoutEnable, OffloadWithoutFatLTO, UnknownIntrinsic,
4545
};
46+
use crate::intrinsic::ty::typetree::fnc_typetrees;
4647
use crate::llvm::{self, Type, Value};
4748
use crate::type_of::LayoutLlvmExt;
4849
use crate::va_arg::emit_va_arg;
@@ -223,12 +224,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
223224
)
224225
}
225226
sym::autodiff => {
226-
let result = PlaceRef {
227-
val: result_place.unwrap(),
228-
layout: result_layout,
229-
};
230-
codegen_autodiff(self, tcx, instance, args, result);
231-
return IntrinsicResult::WroteIntoPlace;
227+
return codegen_autodiff(self, tcx, instance, args, result_layout, result_place);
232228
}
233229
sym::offload => {
234230
if tcx.sess.opts.unstable_opts.offload.is_empty() {
@@ -1728,8 +1724,9 @@ fn codegen_autodiff<'ll, 'tcx>(
17281724
tcx: TyCtxt<'tcx>,
17291725
instance: ty::Instance<'tcx>,
17301726
args: &[OperandRef<'tcx, &'ll Value>],
1731-
result: PlaceRef<'tcx, &'ll Value>,
1732-
) {
1727+
result_layout: ty::layout::TyAndLayout<'tcx>,
1728+
result_place: Option<PlaceValue<&'ll Value>>,
1729+
) -> IntrinsicResult<'tcx, &'ll Value> {
17331730
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
17341731
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
17351732
}
@@ -1769,9 +1766,9 @@ fn codegen_autodiff<'ll, 'tcx>(
17691766
diff_id,
17701767
diff_args
17711768
),
1772-
Err(_) => {
1769+
Err(err) => {
17731770
// An error has already been emitted
1774-
return;
1771+
return IntrinsicResult::Err(err);
17751772
}
17761773
};
17771774

@@ -1791,7 +1788,7 @@ fn codegen_autodiff<'ll, 'tcx>(
17911788
&mut diff_attrs.input_activity,
17921789
);
17931790

1794-
let fnc_tree = rustc_middle::ty::fnc_typetrees(tcx, source_fn_ptr_ty);
1791+
let fnc_tree = fnc_typetrees(tcx, source_fn_ptr_ty);
17951792

17961793
// Build body
17971794
generate_enzyme_call(
@@ -1802,9 +1799,10 @@ fn codegen_autodiff<'ll, 'tcx>(
18021799
llret_ty,
18031800
&val_arr,
18041801
&diff_attrs,
1805-
result,
1802+
result_layout,
1803+
result_place,
18061804
fnc_tree,
1807-
);
1805+
)
18081806
}
18091807

18101808
// Generates the LLVM code to offload a Rust function to a target device (e.g., GPU).

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,6 +2139,8 @@ unsafe extern "C" {
21392139
IsVolatile: bool,
21402140
) -> &'a Value;
21412141

2142+
pub(crate) fn LLVMRustBuildVScale<'a>(B: &Builder<'a>, Ty: &'a Type) -> &'a Value;
2143+
21422144
pub(crate) fn LLVMRustTimeTraceProfilerInitialize();
21432145

21442146
pub(crate) fn LLVMRustTimeTraceProfilerFinishThread();

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use rustc_session::{Session, filesearch};
4747
use rustc_span::Symbol;
4848
use rustc_target::spec::crt_objects::CrtObjects;
4949
use rustc_target::spec::{
50-
BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents,
50+
Arch, BinaryFormat, Cc, CfgAbi, Env, LinkOutputKind, LinkSelfContainedComponents,
5151
LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, Os, RelocModel,
5252
RelroLevel, SanitizerSet, SplitDebuginfo,
5353
};
@@ -2413,6 +2413,69 @@ fn add_rpath_args(
24132413
}
24142414
}
24152415

2416+
fn strip_numeric_suffix<'a>(base: &'a str, suffix: impl AsRef<str>, fallback: &'a str) -> &'a str {
2417+
if suffix.as_ref().parse::<u32>().is_ok() { base } else { fallback }
2418+
}
2419+
2420+
fn undecorate_c_symbol<'a>(
2421+
name: &'a str,
2422+
sess: &Session,
2423+
kind: SymbolExportKind,
2424+
) -> Option<&'a str> {
2425+
match sess.target.binary_format {
2426+
BinaryFormat::MachO => {
2427+
// Mach-O: strip the leading underscore that all external symbols have.
2428+
// The Darwin linker's export_symbols will add it back.
2429+
name.strip_prefix('_')
2430+
}
2431+
BinaryFormat::Coff => {
2432+
// MSVC C++ mangled names start with '?' and use a completely different
2433+
// decorating scheme that includes '@@' as structural delimiters.
2434+
// They must not be subjected to C calling-convention undecoration.
2435+
if name.starts_with('?') {
2436+
return Some(name);
2437+
}
2438+
Some(match sess.target.arch {
2439+
Arch::X86 => {
2440+
// COFF 32-bit: strip calling-convention decorations.
2441+
if let Some(rest) = name.strip_prefix('@') {
2442+
// fastcall: @foo@N -> foo
2443+
rest.rsplit_once('@')
2444+
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
2445+
.unwrap_or(name)
2446+
} else if let Some(stripped) = name.strip_prefix('_') {
2447+
if let Some((base, suffix)) = stripped.rsplit_once('@') {
2448+
// stdcall: _foo@N -> foo
2449+
strip_numeric_suffix(base, suffix, stripped)
2450+
} else {
2451+
// cdecl: _foo -> foo
2452+
stripped
2453+
}
2454+
} else {
2455+
// vectorcall: foo@@N -> foo
2456+
name.rsplit_once("@@")
2457+
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
2458+
.unwrap_or(name)
2459+
}
2460+
}
2461+
Arch::X86_64 => {
2462+
// COFF 64-bit: vectorcall mangling (foo@@N -> foo) also applies on x86_64.
2463+
name.rsplit_once("@@")
2464+
.map(|(base, suffix)| strip_numeric_suffix(base, suffix, name))
2465+
.unwrap_or(name)
2466+
}
2467+
Arch::Arm64EC if kind == SymbolExportKind::Text => {
2468+
// Arm64EC: `#` prefix distinguishes ARM64EC text symbols from x64 thunks.
2469+
name.strip_prefix('#').unwrap_or(name)
2470+
}
2471+
_ => name,
2472+
})
2473+
}
2474+
// ELF: no decoration
2475+
_ => Some(name),
2476+
}
2477+
}
2478+
24162479
fn add_c_staticlib_symbols(
24172480
sess: &Session,
24182481
lib: &NativeLib,
@@ -2454,7 +2517,14 @@ fn add_c_staticlib_symbols(
24542517
}
24552518

24562519
for symbol in object.symbols() {
2457-
if symbol.scope() != object::SymbolScope::Dynamic {
2520+
// The `object` crate returns `Dynamic` for ELF/Mach-O global symbols,
2521+
// but always returns `Linkage` for COFF external symbols.
2522+
// Accept both for COFF (Windows and UEFI).
2523+
let scope = symbol.scope();
2524+
if scope != object::SymbolScope::Dynamic
2525+
&& !(sess.target.binary_format == BinaryFormat::Coff
2526+
&& scope == object::SymbolScope::Linkage)
2527+
{
24582528
continue;
24592529
}
24602530

@@ -2469,9 +2539,10 @@ fn add_c_staticlib_symbols(
24692539
_ => continue,
24702540
};
24712541

2472-
// FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple.
2473-
// Need to be resolved.
2474-
out.push((name.to_string(), export_kind));
2542+
let Some(undecorated) = undecorate_c_symbol(name, sess, export_kind) else {
2543+
continue;
2544+
};
2545+
out.push((undecorated.to_string(), export_kind));
24752546
}
24762547
}
24772548

compiler/rustc_codegen_ssa/src/traits/builder.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,11 @@ pub trait BuilderMethods<'a, 'tcx>:
476476
flags: MemFlags,
477477
);
478478

479+
// Produce a value from calling the `vscale` intrinsic (containing the `vscale` multiplier that
480+
// a scalable vector's element size and count can be multiplied by to get the real size of the
481+
// vector)
482+
fn vscale(&mut self, ty: Self::Type) -> Self::Value;
483+
479484
/// *Typed* copy for non-overlapping places.
480485
///
481486
/// Has a default implementation in terms of `memcpy`, but specific backends
@@ -513,6 +518,12 @@ pub trait BuilderMethods<'a, 'tcx>:
513518
temp.val.store_with_flags(self, dst.with_type(layout), flags);
514519
} else if !layout.is_zst() {
515520
let bytes = self.const_usize(layout.size.bytes());
521+
let bytes = if layout.peel_transparent_wrappers(self).ty.is_scalable_vector() {
522+
let vscale = self.vscale(self.type_i64());
523+
self.mul(vscale, bytes)
524+
} else {
525+
bytes
526+
};
516527
self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags, None);
517528
}
518529
}

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,10 @@ LLVMRustBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
14971497
unwrap(Size), IsVolatile));
14981498
}
14991499

1500+
extern "C" LLVMValueRef LLVMRustBuildVScale(LLVMBuilderRef B, LLVMTypeRef Ty) {
1501+
return wrap(unwrap(B)->CreateVScale(unwrap(Ty)));
1502+
}
1503+
15001504
extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst,
15011505
unsigned DstAlign, LLVMValueRef Val,
15021506
LLVMValueRef Size,

0 commit comments

Comments
 (0)