-
Notifications
You must be signed in to change notification settings - Fork 13.9k
rustc_codegen_llvm: Require opt-level >= 1 for index-based write_operand_repeatedly() loop
#147462
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
base: master
Are you sure you want to change the base?
Conversation
To make debugger stepping intuitive with `-Copt-level=0`. See the adjusted `basic-stepping.rs` test. This is kind of a revert of bd0aae9, except we don't revert it, we just make it conditional on `opt-level`. That commit regressed `basic-stepping.rs`, but it was not noticed since that test did not exist back then. I have retroactively bisected to find that out. It seems messy to sprinkle if-cases inside of the `write_operand_repeatedly()` so make the whole function conditional. The test that bd0aae9 added in `tests/codegen/issues/issue-111603.rs` already use `-Copt-level=3`, so we don't need to adjust the compiler flags for it to keep passing.
|
rustbot has assigned @jdonszelmann. Use |
opt-level >= 1 for index-based loopopt-level >= 1 for index-based write_operand_repeatedly() loop
|
r? saethlin |
|
Do you know why this codegen change made the stepping work differently? It's not clear to me at all what this diff has to do with the stepping order, but clearly it does. So I can't tell if this is actually papering over a bug in LLVM, or deeper in our debuginfo handling. |
|
@saethlin Good call. I have investigated more deeply now. Stepping stopped working because the only emitted LLVM instructions with debug location metadata were removed. No LLVM instructions with debug location metadata remained. However, simply adding debug info to all remaining instructions does not work well, because then stepping will loop for as many times as we repeat. Let's look at the details with this program: fn main() {
let whatever = ["whatever"; 8];
}When stepping worked, it looked like this: rustc +nightly-2023-04-23 -g --emit=llvm-ir $src/whatever.rs; whatever::main
; Function Attrs: nonlazybind uwtable
define internal void @_ZN8whatever4main17h46e92f5877e9c5b3E() unnamed_addr #1 !dbg !175 {
start:
%whatever = alloca [8 x { ptr, i64 }], align 8
call void @llvm.dbg.declare(metadata ptr %whatever, metadata !179, metadata !DIExpression()), !dbg !189
%0 = getelementptr inbounds [8 x { ptr, i64 }], ptr %whatever, i64 0, i64 0, !dbg !190
%1 = getelementptr inbounds [8 x { ptr, i64 }], ptr %whatever, i64 0, i64 8, !dbg !190
br label %repeat_loop_header, !dbg !190
repeat_loop_header: ; preds = %repeat_loop_body, %start
%2 = phi ptr [ %0, %start ], [ %6, %repeat_loop_body ]
%3 = icmp ne ptr %2, %1
br i1 %3, label %repeat_loop_body, label %repeat_loop_next
repeat_loop_body: ; preds = %repeat_loop_header
%4 = getelementptr inbounds { ptr, i64 }, ptr %2, i32 0, i32 0
store ptr @alloc_3db654700ddfbbbd22c59221279a79d2, ptr %4, align 8
%5 = getelementptr inbounds { ptr, i64 }, ptr %2, i32 0, i32 1
store i64 8, ptr %5, align 8
%6 = getelementptr inbounds { ptr, i64 }, ptr %2, i64 1
br label %repeat_loop_header
repeat_loop_next: ; preds = %repeat_loop_header
ret void, !dbg !191
}
!190 = !DILocation(line: 2, column: 20, scope: !175)stepping worked because of (note that these instructions don't repeat): %0 = getelementptr inbounds [8 x { ptr, i64 }], ptr %whatever, i64 0, i64 0, !dbg !190
%1 = getelementptr inbounds [8 x { ptr, i64 }], ptr %whatever, i64 0, i64 8, !dbg !190We can make stepping work if we add ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc -g --emit=llvm-ir $src/whatever.rs; whatever::main
; Function Attrs: nonlazybind uwtable
define hidden void @_ZN8whatever4main17h0930ac910df4df44E() unnamed_addr #0 !dbg !159 {
start:
%whatever = alloca [128 x i8], align 8
#dbg_declare(ptr %whatever, !163, !DIExpression(), !173)
br label %repeat_loop_header, !dbg !174
repeat_loop_header: ; preds = %repeat_loop_body, %start
%0 = phi i64 [ 0, %start ], [ %4, %repeat_loop_body ], !dbg !174
%1 = icmp ult i64 %0, 8, !dbg !174
br i1 %1, label %repeat_loop_body, label %repeat_loop_next, !dbg !174
repeat_loop_body: ; preds = %repeat_loop_header
%2 = getelementptr inbounds nuw { ptr, i64 }, ptr %whatever, i64 %0, !dbg !174
store ptr @alloc_3db654700ddfbbbd22c59221279a79d2, ptr %2, align 8, !dbg !174
%3 = getelementptr inbounds i8, ptr %2, i64 8, !dbg !174
store i64 8, ptr %3, align 8, !dbg !174
%4 = add nuw i64 %0, 1, !dbg !174
br label %repeat_loop_header, !dbg !174
repeat_loop_next: ; preds = %repeat_loop_header
ret void, !dbg !175
}
!174 = !DILocation(line: 2, column: 20, scope: !159)Now stepping works, but since all instructions with I don't have any good idea on how to solve this. The only thing I can think of is to force emission of a no-op instruction before we enter the loop and then attach Maybe you have some other idea? |
Is that true? I'm looking at this IR: ; demo::main
; Function Attrs: nonlazybind uwtable
define hidden void @_ZN4demo4main17h1e5d7b00d81e2d71E() unnamed_addr #0 !dbg !151 {
start:
%h = alloca [128 x i8], align 8
#dbg_declare(ptr %h, !155, !DIExpression(), !165)
br label %repeat_loop_header, !dbg !166
repeat_loop_header: ; preds = %repeat_loop_body, %start
%0 = phi i64 [ 0, %start ], [ %4, %repeat_loop_body ]
%1 = icmp ult i64 %0, 8
br i1 %1, label %repeat_loop_body, label %repeat_loop_next
repeat_loop_body: ; preds = %repeat_loop_header
%2 = getelementptr inbounds nuw { ptr, i64 }, ptr %h, i64 %0
store ptr @alloc_3db654700ddfbbbd22c59221279a79d2, ptr %2, align 8
%3 = getelementptr inbounds i8, ptr %2, i64 8
store i64 8, ptr %3, align 8
%4 = add nuw i64 %0, 1
br label %repeat_loop_header
repeat_loop_next: ; preds = %repeat_loop_header
ret void, !dbg !167
}In the start block, I see dbg 165 and 166 mentioned, and those are !165 = !DILocation(line: 2, column: 9, scope: !156)
!166 = !DILocation(line: 2, column: 13, scope: !151)Which are the the It almost seems like the |
To make debugger stepping intuitive with
-Copt-level=0. See the adjustedbasic-stepping.rstest.This is kind of a revert of bd0aae9 (cg_llvm: use index-based loop in write_operand_repeatedly), except we don't revert it, we just make it conditional on
opt-level. That commit regressedbasic-stepping.rs, but it was not noticed since that test did not exist back then (it was added later in #144876). I have retroactively bisected to find that out.It seems messy to sprinkle if-cases inside of
write_operand_repeatedly()so make the whole function conditional.The test that bd0aae9 added in
tests/codegen/issues/issue-111603.rsalready use-Copt-level=3, so we don't need to adjust the compiler flags for it to keep passing.This PR takes us one step closer to fixing #33013.
CC #147426 which is related (there will be trivial conflicts for me to resolve in basic-stepping.rs once one of them lands)