-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[MIPS] __builtin_bswap16 miscompilation #103035
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
Comments
@llvm/issue-subscribers-backend-mips Author: Markus F.X.J. Oberhumer (markus-oberhumer)
clang 18.1.8 MIPS miscompilation in Debug mode
// clang -target mips-linux-musl bug.c -o bug.out
// qemu-mips ./bug.out
unsigned bswap16_fails(unsigned v) {
// FAILS - cast seems ignored ??
return __builtin_bswap16((unsigned short) v);
}
unsigned bswap16_ok(unsigned v) {
return __builtin_bswap16((unsigned short) (v & 0xffff)); // OK
}
int main() {
if (bswap16_ok(0x04030201) != 0x0102)
return 1;
if (bswap16_fails(0x04030201) != 0x0102)
return 2; // ERROR HERE
} |
https://godbolt.org/z/MGWGPz1aE
I cannot reproduce this issue. |
@dtcxzyw Please try this link https://gcc.godbolt.org/z/cseeoKe35 This bug might be a clang/frontend issue. (Edit: note that the bug only happens when using NO optimizations) |
These two pieces of assembly code look equivalent. cc @topperc |
I get
(Edit: using qemu-mips) |
Best guess is it's a problem with fast-isel. Can you try with |
@topperc Indeed, |
We need to mask the SRL result to 8 bits before ORing in the SLL. This is needed in case bits 23:16 of the input aren't zero. They will have been shifted into bits 15:8. We don't need to AND the result with 0xffff. It's ok if the upper 16 bits of the register is garbage. Fixes llvm#103035.
Can you check what you get for |
Are there any command line flags I could testing enabling/disabling |
So it does appear that byte 0 and byte 2 are ORed together to form byte 1 or the result. But the godbolt link doesn't show any OR instructions https://gcc.godbolt.org/z/cseeoKe35 Can you confirm with objdump if you are getting the same assembly as godbolt? |
Ok, here is what I get - it looks like $ zig cc -target mips-linux-musl -c bug.c
$ llvm-objdump -d bug.o bug.o: file format elf32-mips
Disassembly of section .text:
00000000 <bswap16_fails>:
0: 27 bd ff f0 addiu $sp, $sp, -0x10 <bswap16_ok+0xffffffffffffffac>
4: af bf 00 0c sw $ra, 0xc($sp)
8: af be 00 08 sw $fp, 0x8($sp)
c: 03 a0 f0 25 move $fp, $sp
10: af c4 00 04 sw $4, 0x4($fp)
14: 8f c2 00 04 lw $2, 0x4($fp)
18: 00 02 0a 00 sll $1, $2, 0x8 <bswap16_fails+0x8>
1c: 00 02 12 02 srl $2, $2, 0x8 <bswap16_fails+0x8>
20: 00 22 08 25 or $1, $1, $2
24: 30 21 ff ff andi $1, $1, 0xffff <bswap16_ok+0xffbb>
28: 30 22 ff ff andi $2, $1, 0xffff <bswap16_ok+0xffbb>
2c: 03 c0 e8 25 move $sp, $fp
30: 8f be 00 08 lw $fp, 0x8($sp)
34: 8f bf 00 0c lw $ra, 0xc($sp)
38: 27 bd 00 10 addiu $sp, $sp, 0x10 <bswap16_fails+0x10>
3c: 03 e0 00 08 jr $ra
40: 00 00 00 00 nop <bswap16_fails>
00000044 <bswap16_ok>:
44: 27 bd ff f0 addiu $sp, $sp, -0x10 <bswap16_ok+0xffffffffffffffac>
48: af bf 00 0c sw $ra, 0xc($sp)
4c: af be 00 08 sw $fp, 0x8($sp)
50: 03 a0 f0 25 move $fp, $sp
54: af c4 00 04 sw $4, 0x4($fp)
58: 8f c1 00 04 lw $1, 0x4($fp)
5c: 34 02 ff ff ori $2, $zero, 0xffff <bswap16_ok+0xffbb>
60: 00 22 10 24 and $2, $1, $2
64: 00 02 0a 00 sll $1, $2, 0x8 <bswap16_fails+0x8>
68: 00 02 12 02 srl $2, $2, 0x8 <bswap16_fails+0x8>
6c: 00 22 08 25 or $1, $1, $2
70: 30 21 ff ff andi $1, $1, 0xffff <bswap16_ok+0xffbb>
74: 30 22 ff ff andi $2, $1, 0xffff <bswap16_ok+0xffbb>
78: 03 c0 e8 25 move $sp, $fp
7c: 8f be 00 08 lw $fp, 0x8($sp)
80: 8f bf 00 0c lw $ra, 0xc($sp)
84: 27 bd 00 10 addiu $sp, $sp, 0x10 <bswap16_fails+0x10>
88: 03 e0 00 08 jr $ra
8c: 00 00 00 00 nop <bswap16_fails> |
Update: just found the obvious So your patch at #103398 looks good. P.S: Sorry for the confusion, I'm no MIPS expert. |
We need to mask the SRL result to 8 bits before ORing in the SLL. This is needed in case bits 23:16 of the input aren't zero. They will have been shifted into bits 15:8. We don't need to AND the result with 0xffff. It's ok if the upper 16 bits of the register are garbage. Fixes #103035.
/cherry-pick ebe7265 |
We need to mask the SRL result to 8 bits before ORing in the SLL. This is needed in case bits 23:16 of the input aren't zero. They will have been shifted into bits 15:8. We don't need to AND the result with 0xffff. It's ok if the upper 16 bits of the register are garbage. Fixes llvm#103035. (cherry picked from commit ebe7265)
/pull-request #104745 |
We need to mask the SRL result to 8 bits before ORing in the SLL. This is needed in case bits 23:16 of the input aren't zero. They will have been shifted into bits 15:8. We don't need to AND the result with 0xffff. It's ok if the upper 16 bits of the register are garbage. Fixes llvm#103035. (cherry picked from commit ebe7265)
(EDIT: I've added a new Godbolt link and updated the example to make it clear that the bug needs
-march=mips32
to trigger)Godbolt link: https://gcc.godbolt.org/z/vMGc86deh
clang 18.1.8 MIPS miscompilation in Debug mode
The text was updated successfully, but these errors were encountered: