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

Reply via email to