-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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