Skip to content

Commit 745d698

Browse files
committed
Auto merge of #160149 - lqd:fix-windows-pac, r=<try>
Fix Windows on Arm PAC default try-job: aarch64-msvc-2
2 parents 83709ee + 9fdd8e7 commit 745d698

24 files changed

Lines changed: 105 additions & 66 deletions

File tree

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
[submodule "src/llvm-project"]
2626
path = src/llvm-project
2727
url = https://github.com/rust-lang/llvm-project.git
28-
branch = rustc/22.1-2026-05-19
28+
branch = rustc/23.1-2026-07-22
2929
shallow = true
3030
[submodule "src/doc/embedded-book"]
3131
path = src/doc/embedded-book

compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,19 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
141141
) -> Cow<'_, [Value]> {
142142
// FIXME any way to reuse the abi adjustment code in rustc_target?
143143

144-
// Pass i128 arguments by-ref on Windows.
144+
// Pass and return f128 indirectly on s390x and x86_64 Windows.
145+
let indirect_f128 = self.tcx.sess.target.arch == Arch::S390x
146+
|| (self.tcx.sess.target.is_like_windows && self.tcx.sess.target.arch == Arch::X86_64);
147+
148+
// Pass i128 arguments by-ref on s390x and Windows.
145149
let (params, args): (Vec<_>, Cow<'_, [_]>) =
146150
if self.tcx.sess.target.is_like_windows || self.tcx.sess.target.arch == Arch::S390x {
147151
let (params, args): (Vec<_>, Vec<_>) = params
148152
.into_iter()
149153
.zip(args)
150154
.map(|(param, &arg)| {
151155
if param.value_type == types::I128
152-
|| (self.tcx.sess.target.arch == Arch::S390x
153-
&& param.value_type == types::F128)
156+
|| (indirect_f128 && param.value_type == types::F128)
154157
{
155158
let arg_ptr = self.create_stack_slot(16, 16);
156159
arg_ptr.store(self, arg, MemFlagsData::trusted());
@@ -166,19 +169,20 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
166169
(params, args.into())
167170
};
168171

169-
if self.tcx.sess.target.is_like_windows
170-
&& matches!(*returns, [AbiParam { value_type: types::I128, .. }])
171-
{
172+
let ret_single_i128 = matches!(*returns, [AbiParam { value_type: types::I128, .. }]);
173+
let ret_single_f128 = matches!(*returns, [AbiParam { value_type: types::F128, .. }]);
174+
if ret_single_i128 && self.tcx.sess.target.is_like_windows {
172175
// Return i128 using the vector ABI on Windows
173176
returns[0].value_type = types::I64X2;
174177

175178
let ret = self.lib_call_unadjusted(name, params, returns, &args)[0];
176179

177180
Cow::Owned(vec![codegen_bitcast(self, types::I128, ret)])
178-
} else if self.tcx.sess.target.arch == Arch::S390x
179-
&& matches!(*returns, [AbiParam { value_type: types::I128 | types::F128, .. }])
181+
} else if (ret_single_i128 && self.tcx.sess.target.arch == Arch::S390x)
182+
|| (ret_single_f128 && indirect_f128)
180183
{
181-
// Return i128 and f128 using a return area pointer on s390x.
184+
// Return x86_64 Windows f128 and s390x i128 indirectly (sret in LLVM terminology).
185+
let ret_ty = returns[0].value_type;
182186
let mut params = params;
183187
let mut args = args.to_vec();
184188

@@ -188,7 +192,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
188192

189193
self.lib_call_unadjusted(name, params, vec![], &args);
190194

191-
Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlagsData::trusted())])
195+
Cow::Owned(vec![ret_ptr.load(self, ret_ty, MemFlagsData::trusted())])
192196
} else {
193197
Cow::Borrowed(self.lib_call_unadjusted(name, params, returns, &args))
194198
}

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,9 +530,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
530530
to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.sanitizers));
531531

532532
// For non-naked functions, set branch protection attributes on aarch64.
533-
if let Some(BranchProtection { bti, pac_ret, gcs }) =
534-
sess.opts.unstable_opts.branch_protection
535-
{
533+
if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.branch_protection() {
536534
assert!(sess.target.arch == Arch::AArch64);
537535
if bti {
538536
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,7 @@ pub(crate) unsafe fn create_module<'ll>(
405405
);
406406
}
407407

408-
if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection
409-
{
408+
if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.branch_protection() {
410409
if sess.target.arch == Arch::AArch64 {
411410
llvm::add_module_flag_u32(
412411
llmod,
@@ -420,7 +419,11 @@ pub(crate) unsafe fn create_module<'ll>(
420419
"sign-return-address",
421420
pac_ret.is_some().into(),
422421
);
423-
let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, pc: false, key: PAuthKey::A });
422+
let pac_opts = pac_ret.unwrap_or_else(|| {
423+
// Windows on Arm only supports PAC key B.
424+
let key = if sess.target.os == Os::Windows { PAuthKey::B } else { PAuthKey::A };
425+
PacRet { leaf: false, pc: false, key }
426+
});
424427
llvm::add_module_flag_u32(
425428
llmod,
426429
llvm::ModuleFlagMergeBehavior::Min,

compiler/rustc_session/src/options.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,10 @@ pub mod parse {
20162016
match opt {
20172017
"bti" => slot.bti = true,
20182018
"pac-ret" if slot.pac_ret.is_none() => {
2019+
// Note: some targets only support certain keys (Windows on ARM only
2020+
// supports Key B) and this possible discrepancy is handled by the
2021+
// session's `branch_protection` accessor, when we have both the target
2022+
// tuple and branch protection information available.
20192023
slot.pac_ret = Some(PacRet { leaf: false, pc: false, key: PAuthKey::A })
20202024
}
20212025
"leaf" => match slot.pac_ret.as_mut() {
@@ -2385,6 +2389,7 @@ options! {
23852389
(default: no)"),
23862390
box_noalias: bool = (true, parse_bool, [TRACKED],
23872391
"emit noalias metadata for box (default: yes)"),
2392+
#[rustc_lint_opt_deny_field_access("use `Session::branch_protection` instead of this field")]
23882393
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED] { TARGET_MODIFIER: BranchProtection },
23892394
"set options for branch target identification and pointer authentication on AArch64"),
23902395
build_sdylib_interface: bool = (false, parse_bool, [UNTRACKED],

compiler/rustc_session/src/session.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ use rustc_target::spec::{
3636
use crate::code_stats::CodeStats;
3737
pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
3838
use crate::config::{
39-
self, Cfg, CheckCfg, CoverageLevel, CoverageOptions, CrateType, DebugInfo, ErrorOutputType,
40-
FunctionReturn, Input, InstrumentCoverage, InstrumentMcount, NATIVE_CPU, OptLevel, OutFileName,
41-
OutputType, PointerAuthOption, SwitchWithOptPath,
39+
self, BranchProtection, Cfg, CheckCfg, CoverageLevel, CoverageOptions, CrateType, DebugInfo,
40+
ErrorOutputType, FunctionReturn, Input, InstrumentCoverage, InstrumentMcount, NATIVE_CPU,
41+
OptLevel, OutFileName, OutputType, PAuthKey, PointerAuthOption, SwitchWithOptPath,
4242
};
4343
use crate::filesearch::FileSearch;
4444
use crate::lint::LintId;
@@ -999,6 +999,30 @@ impl Session {
999999
}
10001000
}
10011001

1002+
/// Returns the `-Zbranch-protection` info. Note that it is adjusted to the current target, e.g.
1003+
/// some targets only support certain Pointer Authentication Code keys.
1004+
///
1005+
/// Accessing the session's unstable `branch_protection` option fields directly is linted
1006+
/// against.
1007+
pub fn branch_protection(&self) -> Option<BranchProtection> {
1008+
let mut bp = self.opts.unstable_opts.branch_protection;
1009+
1010+
if let Some(bp) = bp.as_mut() {
1011+
// Windows on Arm only supports PAC Key B for return address signing, as shown in
1012+
// https://github.com/llvm/llvm-project/pull/203989. We parse the CLI flags for branch
1013+
// protection and target separately though, so we adjust this possible discrepancy here.
1014+
if self.target.os == Os::Windows && self.target.arch == Arch::AArch64 {
1015+
if let Some(pac_ret) = bp.pac_ret.as_mut()
1016+
&& pac_ret.key == PAuthKey::A
1017+
{
1018+
pac_ret.key = PAuthKey::B;
1019+
}
1020+
}
1021+
}
1022+
1023+
bp
1024+
}
1025+
10021026
pub fn must_emit_unwind_tables(&self) -> bool {
10031027
// This is used to control the emission of the `uwtable` attribute on
10041028
// LLVM functions. The `uwtable` attribute according to LLVM is:

compiler/rustc_target/src/callconv/x86_win64.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_abi::{BackendRepr, Float, Integer, Primitive, Size, TyAbiInterface};
1+
use rustc_abi::{BackendRepr, Integer, Primitive, Size, TyAbiInterface};
22

33
use crate::callconv::{ArgAbi, FnAbi, Reg};
44
use crate::spec::{HasTargetSpec, RustcAbi};
@@ -35,11 +35,7 @@ where
3535
// FIXME(#134288): This may change for the `-msvc` targets in the future.
3636
a.cast_to(Reg::opaque_vector(Size::from_bits(128)));
3737
}
38-
} else if a.layout.size.bytes() > 8
39-
&& !matches!(scalar.primitive(), Primitive::Float(Float::F128))
40-
{
41-
// Match what LLVM does for `f128` so that `compiler-builtins` builtins match up
42-
// with what LLVM expects.
38+
} else if a.layout.size.bytes() > 8 {
4339
a.make_indirect();
4440
} else {
4541
a.extend_integer_width_to(32);

library/compiler-builtins/compiler-builtins/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ mod c {
362362
("__aeabi_div0", "arm/aeabi_div0.c"),
363363
("__aeabi_drsub", "arm/aeabi_drsub.c"),
364364
("__aeabi_frsub", "arm/aeabi_frsub.c"),
365+
("__aeabi_uread4", "arm/aeabi_uread4.S"),
366+
("__aeabi_uread8", "arm/aeabi_uread8.S"),
367+
("__aeabi_uwrite4", "arm/aeabi_uwrite4.S"),
368+
("__aeabi_uwrite8", "arm/aeabi_uwrite8.S"),
365369
("__bswapdi2", "arm/bswapdi2.S"),
366370
("__bswapsi2", "arm/bswapsi2.S"),
367371
("__divmodsi4", "arm/divmodsi4.S"),

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,7 @@ fn copy_src_dirs(
10681068

10691069
static LLVM_PROJECTS: &[&str] = &[
10701070
"llvm-project/clang",
1071+
"llvm-project/libc",
10711072
"llvm-project/libunwind",
10721073
"llvm-project/lld",
10731074
"llvm-project/lldb",

src/bootstrap/src/core/build_steps/llvm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ impl CommandLineStep for Llvm {
410410
// equally well everywhere.
411411
if builder.llvm_link_shared() {
412412
cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
413+
// Keep the pre-LLVM23 behavior for now.
414+
cfg.define("LLVM_VERSIONED_DYLIB_NAME_ON_DARWIN", "OFF");
413415
}
414416

415417
if (target.starts_with("csky")

0 commit comments

Comments
 (0)