about summary refs log tree commit diff
path: root/compiler/rustc_target/src
diff options
context:
space:
mode:
authorErik Desjardins <erikdesjardins@users.noreply.github.com>2023-05-20 16:11:09 -0400
committerErik Desjardins <erikdesjardins@users.noreply.github.com>2023-07-10 19:19:38 -0400
commited317e4a479b4bacf102188445d03fabfb81a2c5 (patch)
tree6665df282145b0592ee265f42564bb09218dcd59 /compiler/rustc_target/src
parent7089321c6deabb3c25cf0ec829ca209f77b8ee5a (diff)
downloadrust-ed317e4a479b4bacf102188445d03fabfb81a2c5.tar.gz
rust-ed317e4a479b4bacf102188445d03fabfb81a2c5.zip
i686-windows: pass arguments with requested alignment > 4 indirectly
Diffstat (limited to 'compiler/rustc_target/src')
-rw-r--r--compiler/rustc_target/src/abi/call/x86.rs29
-rw-r--r--compiler/rustc_target/src/abi/mod.rs8
-rw-r--r--compiler/rustc_target/src/lib.rs1
3 files changed, 34 insertions, 4 deletions
diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index d2c604fafa6..dd52b3cb520 100644
--- a/compiler/rustc_target/src/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
@@ -54,7 +54,31 @@ where
             continue;
         }
 
-        if arg.layout.is_aggregate() {
+        // FIXME: MSVC 2015+ will pass the first 3 vector arguments in [XYZ]MM0-2
+        // See https://reviews.llvm.org/D72114 for Clang behavior
+
+        let t = cx.target_spec();
+        let align_4 = Align::from_bytes(4).unwrap();
+        let align_16 = Align::from_bytes(16).unwrap();
+
+        if t.is_like_msvc
+            && arg.layout.is_adt()
+            && let Some(requested_align) = arg.layout.repr_options().align
+            && requested_align > align_4
+        {
+            // MSVC has special rules for overaligned arguments: https://reviews.llvm.org/D72114.
+            // Summarized here:
+            // - Arguments with _requested_ alignment > 4 are passed indirectly.
+            // - For backwards compatibility, arguments with natural alignment > 4 are still passed
+            //   on stack (via `byval`). For example, this includes `double`, `int64_t`,
+            //   and structs containing them, provided they lack an explicit alignment attribute.
+            assert!(arg.layout.align.abi >= requested_align,
+                "abi alignment {:?} less than requested alignment {:?}",
+                arg.layout.align.abi,
+                requested_align
+            );
+            arg.make_indirect();
+        } else if arg.layout.is_aggregate() {
             // We need to compute the alignment of the `byval` argument. The rules can be found in
             // `X86_32ABIInfo::getTypeStackAlignInBytes` in Clang's `TargetInfo.cpp`. Summarized
             // here, they are:
@@ -87,9 +111,6 @@ where
                 }
             }
 
-            let t = cx.target_spec();
-            let align_4 = Align::from_bytes(4).unwrap();
-            let align_16 = Align::from_bytes(16).unwrap();
             let byval_align = if arg.layout.align.abi < align_4 {
                 // (1.)
                 align_4
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 589cd3cf96b..aecf8b339f0 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -55,6 +55,7 @@ pub trait TyAbiInterface<'a, C>: Sized {
     fn is_never(this: TyAndLayout<'a, Self>) -> bool;
     fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
     fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
+    fn repr_options(this: TyAndLayout<'a, Self>) -> ReprOptions;
 }
 
 impl<'a, Ty> TyAndLayout<'a, Ty> {
@@ -125,6 +126,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
         Ty::is_unit(self)
     }
 
+    pub fn repr_options<C>(self) -> ReprOptions
+    where
+        Ty: TyAbiInterface<'a, C>,
+    {
+        Ty::repr_options(self)
+    }
+
     pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>) -> Size
     where
         Ty: TyAbiInterface<'a, C>,
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index a7b54766bc6..3307244a217 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -12,6 +12,7 @@
 #![feature(associated_type_bounds)]
 #![feature(exhaustive_patterns)]
 #![feature(iter_intersperse)]
+#![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]