-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Use the aligned size for alloca at args/ret when the pass mode is cast #127168
Conversation
@DianQK what's the LLVMIR of the example after this patch? |
The LLVMIR after this PR now seems to be this: ; ModuleID = 'miscompiled_arg.4dadb824ae4952c2-cgu.0'
source_filename = "miscompiled_arg.4dadb824ae4952c2-cgu.0"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: nounwind nonlazybind uwtable
define { i64, i32 } @foo({ i64, i32 } %0) unnamed_addr #0 {
start:
%_0 = alloca [12 x i8], align 4
%1 = alloca [16 x i8], align 8
%arg = alloca [12 x i8], align 4
store { i64, i32 } %0, ptr %1, align 8
call void @llvm.memcpy.p0.p0.i64(ptr align 4 %arg, ptr align 8 %1, i64 12, i1 false)
call void @llvm.memcpy.p0.p0.i64(ptr align 4 %_0, ptr align 4 %arg, i64 12, i1 false)
%2 = load { i64, i32 }, ptr %_0, align 4
ret { i64, i32 } %2
}
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1
attributes #0 = { nounwind nonlazybind uwtable "probe-stack"="inline-asm" "target-cpu"="x86-64" }
attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}
!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 2, !"RtLibUseGOT", i32 1}
!2 = !{!"rustc version 1.81.0-dev"} But Alive2 still flags this as UB, and what needs to happen is this: - %_0 = alloca [12 x i8], align 4
+ %_0 = alloca [16 x i8], align 4 |
What was I thinking? @.@ @rustbot author |
Thank you for your work on this, and please don't feel bad about making a mistake. 💖 Code review is precisely for checking for errors, sometimes silly-seeming ones, and this is... certainly not the easiest part of rustc to work with. |
Don't worry. I'm just complaining about I show a bug that I'm fixing in the PR. Probably because I simplified the code while debugging. :3 |
I split the changes into three commits for review. The latest commit includes updates to the return value. @rustbot ready |
The `load` and `store` instructions in LLVM access the aligned size.
Everything seems in order. Confirmed the codegen passes Alive2 after pulling and building. If this PR needs further fixes, I think we can do it as a followup. @bors r+ |
Use the aligned size for alloca at args/ret when the pass mode is cast Fixes rust-lang#75839. Fixes rust-lang#121028. The `load` and `store` instructions in LLVM access the aligned size. For example, `load { i64, i32 }` accesses 16 bytes on x86_64: https://alive2.llvm.org/ce/z/n8CHAp. BTW, this example is expected to be optimized to immediate UB by Alive2: https://rust.godbolt.org/z/b7xK7hv1c and https://alive2.llvm.org/ce/z/vZDtZH. r? compiler
💔 Test failed - checks-actions |
@bors retry |
A job failed! Check out the build log: (web) (plain) Click to see the possible cause of the failure (guessed by this bot)
|
I don't think that this is the right way to fix the issue. Instead of changing the alloca size, we should remove the use of aggregate loads/stores (load/store member-wise instead). |
But we always need to return a |
Yes, I mean using insertvalue. LLVM will ultimately convert it to that form, which is why this is not a problem with optimizations. But we should directly generate that instead of going through an aggregate load in the first place. |
This makes sense to me. I think that as a bugfix PR, the current changes can make the sanitizers work correctly and LLVM can also optimize most of it with insertvalue. I prefer to treat insertvalue as a separate PR for improving compilation time. |
…iaskrgr Rollup of 10 pull requests Successful merges: - rust-lang#126883 (Parenthesize break values containing leading label) - rust-lang#127136 (Fix `FnMut::call_mut`/`Fn::call` shim for async closures that capture references) - rust-lang#127146 (Uplift fast rejection to new solver) - rust-lang#127152 (Bootstrap: Try renaming the file if removing fails) - rust-lang#127168 (Use the aligned size for alloca at args/ret when the pass mode is cast) - rust-lang#127203 (Fix import suggestion error when path segment failed not from starting) - rust-lang#127212 (Update books) - rust-lang#127224 (Make `FloatTy` checks exhaustive in pretty print) - rust-lang#127230 (chore: remove duplicate words) - rust-lang#127243 (Add test for adt_const_params) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 10 pull requests Successful merges: - rust-lang#126883 (Parenthesize break values containing leading label) - rust-lang#127136 (Fix `FnMut::call_mut`/`Fn::call` shim for async closures that capture references) - rust-lang#127146 (Uplift fast rejection to new solver) - rust-lang#127152 (Bootstrap: Try renaming the file if removing fails) - rust-lang#127168 (Use the aligned size for alloca at args/ret when the pass mode is cast) - rust-lang#127203 (Fix import suggestion error when path segment failed not from starting) - rust-lang#127212 (Update books) - rust-lang#127224 (Make `FloatTy` checks exhaustive in pretty print) - rust-lang#127230 (chore: remove duplicate words) - rust-lang#127243 (Add test for adt_const_params) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#127168 - DianQK:cast-size, r=workingjubilee Use the aligned size for alloca at args/ret when the pass mode is cast Fixes rust-lang#75839. Fixes rust-lang#121028. The `load` and `store` instructions in LLVM access the aligned size. For example, `load { i64, i32 }` accesses 16 bytes on x86_64: https://alive2.llvm.org/ce/z/n8CHAp. BTW, this example is expected to be optimized to immediate UB by Alive2: https://rust.godbolt.org/z/b7xK7hv1c and https://alive2.llvm.org/ce/z/vZDtZH. r? compiler
yes, I assumed that we already intended to remove our aggregate load/stores and that this not doing so is because fixing "emitting LLVMIR with UB" is a smaller patch worth independently addressing. |
I'll give it a try. :) @rustbot label +beta-nominated |
Follow-up PR: #128969. |
Fixes #75839. Fixes #121028.
The
load
andstore
instructions in LLVM access the aligned size. For example,load { i64, i32 }
accesses 16 bytes on x86_64: https://alive2.llvm.org/ce/z/n8CHAp.BTW, this example is expected to be optimized to immediate UB by Alive2: https://rust.godbolt.org/z/b7xK7hv1c and https://alive2.llvm.org/ce/z/vZDtZH.
r? compiler