diff options
| author | DianQK <dianqk@dianqk.net> | 2024-06-30 21:33:46 +0800 |
|---|---|---|
| committer | DianQK <dianqk@dianqk.net> | 2024-07-02 06:33:35 +0800 |
| commit | c453dcd62abba536d0580ad9b880b86d46e911ce (patch) | |
| tree | 1988d22a2a95635292ac894ef03ef7dc71ccbc49 /compiler | |
| parent | 09e0abb0d19822455bfc40a8cf31f8fd5a675ba9 (diff) | |
| download | rust-c453dcd62abba536d0580ad9b880b86d46e911ce.tar.gz rust-c453dcd62abba536d0580ad9b880b86d46e911ce.zip | |
Use the aligned size for alloca at args when the pass mode is cast.
The `load` and `store` instructions in LLVM access the aligned size.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/abi.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 8 |
3 files changed, 10 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index a6a3f0f9646..d034f9b5256 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -226,7 +226,8 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { // when passed by value, making it smaller. // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes // when passed by value, making it larger. - let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes()); + let copy_bytes = + cmp::min(cast.unaligned_size(bx).bytes(), self.layout.size.bytes()); // Allocate some scratch space... let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57138d3b9db..d4da13068d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1540,7 +1540,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // when passed by value, making it smaller. // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes // when passed by value, making it larger. - let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes()); + let copy_bytes = cmp::min(cast.unaligned_size(bx).bytes(), arg.layout.size.bytes()); // Allocate some scratch space... let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 5713542c17d..8058130f441 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -339,7 +339,9 @@ impl CastTarget { } } - pub fn size<C: HasDataLayout>(&self, _cx: &C) -> Size { + /// When you only access the range containing valid data, you can use this unaligned size; + /// otherwise, use the safer `size` method. + pub fn unaligned_size<C: HasDataLayout>(&self, _cx: &C) -> Size { // Prefix arguments are passed in specific designated registers let prefix_size = self .prefix @@ -353,6 +355,10 @@ impl CastTarget { prefix_size + rest_size } + pub fn size<C: HasDataLayout>(&self, cx: &C) -> Size { + self.unaligned_size(cx).align_to(self.align(cx)) + } + pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align { self.prefix .iter() |
