Skip to content

Commit c453dcd

Browse files
committed
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.
1 parent 09e0abb commit c453dcd

File tree

5 files changed

+21
-31
lines changed

5 files changed

+21
-31
lines changed

compiler/rustc_codegen_llvm/src/abi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
226226
// when passed by value, making it smaller.
227227
// - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
228228
// when passed by value, making it larger.
229-
let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes());
229+
let copy_bytes =
230+
cmp::min(cast.unaligned_size(bx).bytes(), self.layout.size.bytes());
230231
// Allocate some scratch space...
231232
let llscratch = bx.alloca(scratch_size, scratch_align);
232233
bx.lifetime_start(llscratch, scratch_size);

compiler/rustc_codegen_ssa/src/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
15401540
// when passed by value, making it smaller.
15411541
// - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
15421542
// when passed by value, making it larger.
1543-
let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes());
1543+
let copy_bytes = cmp::min(cast.unaligned_size(bx).bytes(), arg.layout.size.bytes());
15441544
// Allocate some scratch space...
15451545
let llscratch = bx.alloca(scratch_size, scratch_align);
15461546
bx.lifetime_start(llscratch, scratch_size);

compiler/rustc_target/src/abi/call/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,9 @@ impl CastTarget {
339339
}
340340
}
341341

342-
pub fn size<C: HasDataLayout>(&self, _cx: &C) -> Size {
342+
/// When you only access the range containing valid data, you can use this unaligned size;
343+
/// otherwise, use the safer `size` method.
344+
pub fn unaligned_size<C: HasDataLayout>(&self, _cx: &C) -> Size {
343345
// Prefix arguments are passed in specific designated registers
344346
let prefix_size = self
345347
.prefix
@@ -353,6 +355,10 @@ impl CastTarget {
353355
prefix_size + rest_size
354356
}
355357

358+
pub fn size<C: HasDataLayout>(&self, cx: &C) -> Size {
359+
self.unaligned_size(cx).align_to(self.align(cx))
360+
}
361+
356362
pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
357363
self.prefix
358364
.iter()

tests/codegen/cast-target-abi.rs

+9-26
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,7 @@ pub extern "C" fn returns_twou16s() -> TwoU16s {
128128
#[no_mangle]
129129
#[inline(never)]
130130
pub extern "C" fn receives_fiveu16s(x: FiveU16s) {
131-
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
132-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
133-
// powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
134-
// sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
135-
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]]
131+
// CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
136132

137133
// CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align [[RUST_ALIGN:2]]
138134

@@ -218,11 +214,7 @@ pub extern "C" fn returns_doubledouble() -> DoubleDouble {
218214
#[no_mangle]
219215
#[inline(never)]
220216
pub extern "C" fn receives_three32s(x: Three32s) {
221-
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
222-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
223-
// powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
224-
// sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
225-
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]]
217+
// CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
226218

227219
// CHECK: [[RUST_ALLOCA:%.+]] = alloca [12 x i8], align [[RUST_ALIGN:4]]
228220

@@ -271,7 +263,7 @@ pub extern "C" fn returns_three32s() -> Three32s {
271263
#[inline(never)]
272264
pub extern "C" fn receives_doublefloat(x: DoubleFloat) {
273265
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
274-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]]
266+
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
275267
// powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
276268
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
277269

@@ -382,11 +374,7 @@ pub fn return_twou16s() -> TwoU16s {
382374
// CHECK-LABEL: @call_fiveu16s
383375
#[no_mangle]
384376
pub fn call_fiveu16s() {
385-
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
386-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
387-
// powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
388-
// sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
389-
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]]
377+
// CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
390378

391379
// CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align 2
392380

@@ -416,7 +404,7 @@ pub fn return_fiveu16s() -> FiveU16s {
416404
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
417405
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
418406
// sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
419-
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]]
407+
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
420408

421409
// aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s()
422410
// loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s()
@@ -501,7 +489,7 @@ pub fn return_doubledouble() -> DoubleDouble {
501489
#[no_mangle]
502490
pub fn call_doublefloat() {
503491
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
504-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]]
492+
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
505493
// powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
506494
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
507495

@@ -544,7 +532,7 @@ pub fn return_doublefloat() -> DoubleFloat {
544532
// The other targets copy the cast ABI type to an alloca.
545533

546534
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
547-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]]
535+
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
548536
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
549537

550538
// aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]]
@@ -568,12 +556,7 @@ pub fn return_doublefloat() -> DoubleFloat {
568556
// CHECK-LABEL: @call_three32s
569557
#[no_mangle]
570558
pub fn call_three32s() {
571-
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
572-
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
573-
// powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
574-
// sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
575-
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]]
576-
559+
// CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
577560
// CHECK: [[RUST_ALLOCA:%.+]] = alloca [12 x i8], align [[RUST_ALIGN:4]]
578561
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false)
579562

@@ -600,7 +583,7 @@ pub fn return_three32s() -> Three32s {
600583
// aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
601584
// loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
602585
// sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
603-
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]]
586+
// x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]]
604587

605588
// aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s()
606589
// loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s()

tests/codegen/cffi/ffi-out-of-bounds-loads.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@ revisions: linux apple
2-
//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes
2+
//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes -C passes=lint
33

44
//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
55
//@[linux] needs-llvm-components: x86
@@ -36,7 +36,7 @@ extern "C" {
3636
pub fn test() {
3737
let s = S { f1: 1, f2: 2, f3: 3 };
3838
unsafe {
39-
// CHECK: [[ALLOCA:%.+]] = alloca [12 x i8], align 8
39+
// CHECK: [[ALLOCA:%.+]] = alloca [16 x i8], align 8
4040
// CHECK: [[LOAD:%.+]] = load { i64, i32 }, ptr [[ALLOCA]], align 8
4141
// CHECK: call void @foo({ i64, i32 } [[LOAD]])
4242
foo(s);

0 commit comments

Comments
 (0)