3 ms·
The Rust output: define noundef i32 @square(i32 noundef %x, i32 noundef %y) unnamed_addr #0 !dbg !7 { %_0 = add i32 %y, %x, !dbg !12 ret i32 %_0, !db
by steveklabnik 2y ago
The Rust output:
define noundef i32 @square(i32 noundef %x, i32 noundef %y) unnamed_addr #0 !dbg !7 {
%_0 = add i32 %y, %x, !dbg !12
ret i32 %_0, !dbg !13
}
Let's compare like to like, here's one with equivalent C++ code: https://godbolt.org/z/Y4MnGeof4 https://godbolt.org/z/Y4MnGeof4
The C++ output:
define dso_local noundef i32 @square(int, int)(i32 noundef %0, i32 noundef %1) local_unnamed_addr #0 !dbg !99 {
tail call void @llvm.dbg.value(metadata i32 %0, metadata !104, metadata !DIExpression()), !dbg !106
tail call void @llvm.dbg.value(metadata i32 %1, metadata !105, metadata !DIExpression()), !dbg !106
%3 = add nsw i32 %1, %0, !dbg !107
ret i32 %3, !dbg !108
}
> LLVM addition produces poison when signed wrap happens.
https://llvm.org/docs/LangRef.html#add-instruction https://llvm.org/docs/LangRef.html#add-instruction
> nuw and nsw stand for “No Unsigned Wrap” and “No Signed Wrap”, respectively. If the nuw and/or nsw keywords are present, the result value of the add is a poison value if unsigned and/or signed overflow, respectively, occurs.
Note that Rust produces `add`. The C++ produces `add nsw`. No poison in Rust, poison in C++.
Here is an example of these differences producing different results, due to the differences in behavior:
https://godbolt.org/z/Gaonnc985 https://godbolt.org/z/Gaonnc985
Rust:
define noundef zeroext i1 @test() unnamed_addr #0 !dbg !14 {
ret i1 true, !dbg !15
}
C++:
define dso_local noundef zeroext i1 @test()() local_unnamed_addr #0 !dbg !123 {
tail call void @llvm.dbg.value(metadata i32 undef, metadata !128, metadata !DIExpression()), !dbg !129
ret i1 false, !dbg !130
}
This is because in Rust, the wrapping behavior means that this will always be true, but in C++, because it is UB, the compiler assumes it will always be false.
> I'm a little bit puzzled about the vehement responses in the comments wow.
You are claiming that Rust has semantics that it was very, very deliberately designed to not have.