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

Reply via email to