Issue |
90532
|
Summary |
miscompile of non-canonical IR by AArch64 global isel backend
|
Labels |
backend:AArch64,
llvm:codegen,
miscompilation,
llvm:globalisel
|
Assignees |
|
Reporter |
regehr
|
here's an odd-looking little fellow:
```llvm
define i1 @f(i1 %V) {
%C1 = fcmp false double 0.000000e+00, 0.000000e+00
%brmerge = select i1 %C1, i1 true, i1 %V
br i1 %brmerge, label %common.ret, label %SW_C
common.ret:
%common.ret.op = phi i1 [ %C, %SW_C ], [ false, %0 ]
ret i1 %common.ret.op
SW_C:
%Y = icmp ult i1 false, false
%C = icmp ule i1 %Y, false
br label %common.ret
}
```
the SDAG backend (correctly) compiles it to this:
```
_f:
mov w8, w0
mov w0, wzr
cbnz wzr, LBB0_3
tbnz w8, #0, LBB0_3
mov w0, #1
LBB0_3:
ret
```
but global isel gives:
```
_f:
movi d0, #0000000000000000
fcmp d0, #0.0
b.nv LBB0_3
tbnz w0, #0, LBB0_3
mov w0, #1
ret
LBB0_3:
mov w0, wzr
ret
```
which I believe is incorrect. to see this, I'll give Alive's work showing why the function should return 1 when invoked as `f(0)`:
```
i1 %C1 = #x0 (0)
i1 %brmerge = #x0 (0)
>> Jump to %SW_C
i1 %Y = #x0 (0)
i1 %C = #x1 (1)
>> Jump to %common.ret
i1 %common.ret.op = #x1 (1)
```
but on the other hand, if we use this driver:
```c
#include <stdio.h>
unsigned f(unsigned);
int main(void) {
printf("%x\n", f(0));
}
```
then we get:
```
Johns-MacBook-Pro:reduce regehr$ ~/llvm-project/for-alive/bin/llc foo.ll
Johns-MacBook-Pro:reduce regehr$ clang foo.s driver.c && ./a.out
1
Johns-MacBook-Pro:reduce regehr$ ~/llvm-project/for-alive/bin/llc foo.ll -global-isel
Johns-MacBook-Pro:reduce regehr$ clang foo.s driver.c && ./a.out
0
Johns-MacBook-Pro:reduce regehr$
```
cc @DataCorrupted
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs