about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs10
-rw-r--r--tests/codegen/cast-target-abi.rs22
3 files changed, 34 insertions, 16 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index e8da9842882..61f57c9030a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -230,10 +230,20 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let layout = start_bx.layout_of(fx.monomorphize(decl.ty));
             assert!(!layout.ty.has_erasable_regions());
 
-            if local == mir::RETURN_PLACE && fx.fn_abi.ret.is_indirect() {
-                debug!("alloc: {:?} (return place) -> place", local);
-                let llretptr = start_bx.get_param(0);
-                return LocalRef::Place(PlaceRef::new_sized(llretptr, layout));
+            if local == mir::RETURN_PLACE {
+                match fx.fn_abi.ret.mode {
+                    PassMode::Indirect { .. } => {
+                        debug!("alloc: {:?} (return place) -> place", local);
+                        let llretptr = start_bx.get_param(0);
+                        return LocalRef::Place(PlaceRef::new_sized(llretptr, layout));
+                    }
+                    PassMode::Cast { ref cast, .. } => {
+                        debug!("alloc: {:?} (return place) -> place", local);
+                        let size = cast.size(&start_bx);
+                        return LocalRef::Place(PlaceRef::alloca_size(&mut start_bx, size, layout));
+                    }
+                    _ => {}
+                };
             }
 
             if memory_locals.contains(local) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 449fd9ae0db..97d5bb83128 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -109,8 +109,16 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         layout: TyAndLayout<'tcx>,
     ) -> Self {
+        Self::alloca_size(bx, layout.size, layout)
+    }
+
+    pub fn alloca_size<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+        bx: &mut Bx,
+        size: Size,
+        layout: TyAndLayout<'tcx>,
+    ) -> Self {
         assert!(layout.is_sized(), "tried to statically allocate unsized place");
-        PlaceValue::alloca(bx, layout.size, layout.align.abi).with_type(layout)
+        PlaceValue::alloca(bx, size, layout.align.abi).with_type(layout)
     }
 
     /// Returns a place for an indirect reference to an unsized place.
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
index 13b74d68f76..34e52d38bbe 100644
--- a/tests/codegen/cast-target-abi.rs
+++ b/tests/codegen/cast-target-abi.rs
@@ -102,9 +102,9 @@ pub extern "C" fn returns_twou16s() -> TwoU16s {
     // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
     // The other targets copy the cast ABI type to an alloca.
 
-    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]]
-    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]]
-    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]]
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:2]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:2]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:2]]
     // x86_64:      [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]]
 
     // aarch64:     [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
@@ -145,10 +145,10 @@ pub extern "C" fn returns_fiveu16s() -> FiveU16s {
     // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
     // The other targets copy the cast ABI type to an alloca.
 
-    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]]
-    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]]
-    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]]
-    // x86_64:      [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]]
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]]
+    // x86_64:      [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]]
 
     // aarch64:     [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
     // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
@@ -231,10 +231,10 @@ pub extern "C" fn returns_three32s() -> Three32s {
     // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
     // The other targets copy the cast ABI type to an alloca.
 
-    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]]
-    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]]
-    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]]
-    // x86_64:      [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]]
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]]
+    // x86_64:      [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]]
 
     // aarch64:     [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
     // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]