-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
[Mips] Fix missing sign extension in expansion of sub-word atomic max #77072
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
0cdecec
to
d96c168
Compare
@topperc Could you help review this patch? Thanks. |
@topperc Hello, could you help review this patch at your convenience? Thanks. |
@MaskRay Hello, could you help review this patch at your convenience? Thanks. |
@MaskRay ? |
@yingopq Ping. |
0d2741e
to
c8b484f
Compare
1 similar comment
; MIPS32-NEXT: $BB4_1: # %entry | ||
; MIPS32-NEXT: # =>This Inner Loop Header: Depth=1 | ||
; MIPS32-NEXT: ll $2, 0($6) | ||
; MIPS32-NEXT: and $2, $2, $8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these and
instructions needed? The srav will move the 16 bit chunk to the LSBs, then the sll+sra pair will fill the upper 16 bits with the sign of the lower 16 bits. Doesn't seem like anything needs ANDed before hand.
Add sign extension "SEB/SEH" before compare. Fix llvm#61881
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…llvm#77072) Add sign extension "SEB/SEH" before compare. Fix llvm#61881 (cherry picked from commit 755b439)
…llvm#77072) Add sign extension "SEB/SEH" before compare. Fix llvm#61881 (cherry picked from commit 755b439)
…llvm#77072) Add sign extension "SEB/SEH" before compare. Fix llvm#61881 (cherry picked from commit 755b439)
Hello, I started to see MIPS failures in the Rust standard library tests after this change. For example, this program begins to fail after this change: fn main() {
let x = std::sync::atomic::AtomicI8::new(23);
assert_eq!(x.fetch_max(42, std::sync::atomic::Ordering::SeqCst), 23);
} Please see rust-lang/rust#123772 for more details. This seems quite problematic, so please let me know if I can help investigate this somehow. |
hi, please use code 0e501db to test again, because we submit another patch after fbb27d1. This issue include two patch. |
@yingopq As I understand it, this was reproduced with the release/18.x branch (or rust's fork, which is essentially the same), which already contains that second commit as well. |
In rust-lang/rust#123772, he comments |
Hi @yingopq, thank you for the reply and for the tip. I double-checked, and I get the test failure also with 0e501db. I also tested some extra commits just to be sure. Here are my results:
Please let me know if you would like me to perform more tests. |
Thanks, I would check it. |
I have reduced to the following code: target datalayout = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
target triple = "mipsel-unknown-linux-gnu"
define i32 @main() {
%1 = call signext i8 @test()
%2 = sext i8 %1 to i32
ret i32 %2
}
define signext i8 @test() {
%i = alloca i8, align 1
store i8 23, ptr %i, align 1
%i1 = atomicrmw max ptr %i, i8 42 seq_cst, align 1
ret i8 %i1
} https://llvm.godbolt.org/z/4Mxnc1Eda @yingopq I hope this can be of some use. There might be no need to create a variable: define i8 @test(ptr %arg) {
%i6 = atomicrmw max ptr %arg, i8 42 seq_cst, align 1
ret i8 %i6
} |
Clarify: I don't have any knowledge about MIPS, and the following is only confirmed from the output logs. Please correct me if there is any mistake. :) TL;DR: All issues have been fixed in LLVM 17. This appears to be an incorrect patch; we might consider reverting it. But I hope @yingopq and others can come to confirm this. Consider the following two pieces of code: ; v1.ll https://github.com/rust-lang/rust/issues/100650
define i8 @test(ptr %arg) {
%i6 = atomicrmw max ptr %arg, i8 -25 seq_cst, align 1
%i7 = load atomic i8, ptr %arg seq_cst, align 1
ret i8 %i7
}
define i32 @main() {
%i = alloca i8, align 1
store i8 30, ptr %i, align 1
%1 = call i8 @test(ptr %i)
%2 = sext i8 %1 to i32
ret i32 %2
} and ; v2.ll https://github.com/rust-lang/rust/issues/123772
define i8 @test(ptr %arg) {
%i6 = atomicrmw max ptr %arg, i8 42 seq_cst, align 1
ret i8 %i6
}
define i32 @main() {
%i = alloca i8, align 1
store i8 23, ptr %i, align 1
%1 = call signext i8 @test(ptr %i)
%2 = sext i8 %1 to i32
ret i32 %2
} I can confirm that the return value of This is my verification script: LLC=path/llc
MIPSEL_GCC=path/mipsel-unknown-linux-gnu-gcc
$LLC -march=mipsel -O0 -mcpu=mips32 -verify-machineinstrs v1.ll -filetype=obj -o v1.o
$MIPSEL_GCC -o v1 v1.o
qemu-mipsel v1
mipsel=$?
$LLC -O0 -march=x86-64 v1.ll -filetype=obj -o v1.o
clang -o v1 v1.o
./v1
x86=$?
echo "v1: $mipsel == $x86"
$LLC -march=mipsel -O0 -mcpu=mips32 -verify-machineinstrs v2.ll -filetype=obj -o v2.o
$MIPSEL_GCC -o v2 v2.o
qemu-mipsel v2
mipsel=$?
$LLC -O0 -march=x86-64 v2.ll -filetype=obj -o v2.o
clang -o v2 v2.o
./v2
x86=$?
if [ "$mipsel" != "$x86" ]; then
bad=$((bad + 1))
fi
echo "v2: $mipsel == $x86" |
Thanks for your detail comment. |
Thank you very much for looking into it. Would you mind temporarily reverting these two commits? :> |
…omic max (llvm#77072)" These changes caused correctness regressions observed in Rust, see llvm#77072 (comment). This reverts commit 0e501db. This reverts commit fbb27d1.
There's definitely an issue in this sequence
The move and movn need to use the values in $2 and $7 before the srav and seh. The rest of the code expect the 16 bit value to be in the same place in the register as it was when it came out of the load. |
…omic max (llvm#77072)" These changes caused correctness regressions observed in Rust, see llvm#77072 (comment). This reverts commit 0e501db. This reverts commit fbb27d1.
@topperc Thanks so much for pointing out the key to the problem, and I have verified that this is indeed the problem. I would submit patch again. |
Add sign extension "SEB/SEH" before compare.
Fix #61881