| Issue |
185467
|
| Summary |
[SDAG] miscompile of abs(add(v, 1)) when v is known non-negative
|
| Labels |
miscompilation
|
| Assignees |
|
| Reporter |
aleks-tmb
|
During downstream testing we found a miscompile with the following reduced test case:
```llvm
@x = global i32 1, align 4
declare i32 @llvm.abs.i32(i32, i1 immarg)
define i32 @main() {
%v = load i32, ptr @x, align 4, !range !0
%v1 = add i32 %v, 1
%absx = call i32 @llvm.abs.i32(i32 %v1, i1 false)
ret i32 %absx
}
!0 = !{i32 0, i32 2147483647}
```
This function should return 2. However, when compiled with llc (https://godbolt.org/z/o5hWfKWbx), the generated code returns -2:
```asm
main: # @main
mov rax, qword ptr [rip + x@GOTPCREL]
mov ecx, dword ptr [rax]
lea edx, [rcx + 1]
mov eax, -1
sub eax, ecx
cmovb eax, edx
ret
x:
.long 1 # 0x1
```
Running the generated code produces -2, while the expected result is 2.
We bisected this issue and identified the following commit as the likely culprit: https://github.com/llvm/llvm-project/commit/fbda30607c5176f9e54ac86e75435cc57f322674
It seems the emitted `cmovbl` (CF-based) is problematic here, since it never triggers because CF is always 0 after `subl %ecx, 0xFFFFFFFF` - no unsigned borrow is possible. The result stays at -V instead of V.
Before the patch (https://godbolt.org/z/K8K1vsvah), llc emits `cmovsl` (SF-based) instead. SF is set correctly by `negl %eax`, so the move triggers and returns the right value.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs