| Issue |
170404
|
| Summary |
[Aarch64] float-to-i8 truncation does not zero-extend/mask upper bits, causing incorrect icmp results
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
hlyix
|
In i32->i8
```cpp
int compare(int a, int b) {
char c = a;
char d = b;
return c < d;
}
```
It dose i8 extend to i32, `and 255` and add `uxtb`
```cpp
compare:
and w8, w0, #0xff
cmp w8, w1, uxtb
cset w0, lo
ret
```
But in float->i8
```cpp
int compare(float a, float b) {
char c = a;
char d = b;
return c < d;
}
```
It dose not mask upper bits.(see [examples](https://gcc.godbolt.org/z/a4zcjfEez))
```
compare:
fcvtzs w8, s0
fcvtzs w9, s1
cmp w8, w9
cset w0, lo
ret
```
In GCC, they do mask!
```
.arch armv8-a
.file "test_cvt.cpp"
.text
.align 2
.p2align 3,,7
.global _Z7compareff
.type _Z7compareff, %function
_Z7compareff:
.LFB0:
.cfi_startproc
fcvtzu w0, s1
fcvtzu w1, s0
and w0, w0, 255
cmp w0, w1, uxtb
cset w0, hi
ret
.cfi_endproc
.LFE0:
.size _Z7compareff, .-_Z7compareff
.ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0"
.section .note.GNU-stack,"",@progbits
```
## problem
```
float a = 256.f
float b = 1.f
(char)a < (char)b
```
in gcc, return true
in clang, return false
but int will align to gcc
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs