Issue 134305
Summary [LSR] Seemingly incorrect folding
Labels new issue
Assignees
Reporter ashermancinelli
    https://godbolt.org/z/3834noxac

You can link and run this test if you have the fortran runtime built (`flang test.ll` before and after LSR). The essence is that we convert from i64->fp128->i64 and check that the round trip was exact, and if not, abort with failure message.

```
;; before
3: ; preds = %16, %0
  %.014 = phi i64 [ 100, %0 ], [ %17, %16 ]
  %.0913 = phi i64 [ 9223372026854775807, %0 ], [ %18, %16 ]

  ; When this is an sitofp, loop-reduce doesn't do anything weird
  %4 = uitofp i64 %.0913 to fp128
  %5 = tail call i64 @llvm.fptosi.sat.i64.f128(fp128 %4)
  %.not = icmp eq i64 %5, %.0913
  br i1 %.not, label %12, label %6

;; after
3: ; preds = %16, %0
  %lsr.iv1 = phi i64 [ %lsr.iv.next2, %16 ], [ 9223372026954775807, %0 ]
  %lsr.iv = phi i64 [ %lsr.iv.next, %16 ], [ -100, %0 ]
  %IV.S. = phi fp128 [ 0xL7000000000000000403DFFFFFFF6AFD0, %0 ], [ %IV.S.next., %16 ]
  %4 = add i64 %lsr.iv1, -100000000
  %5 = tail call i64 @llvm.fptosi.sat.i64.f128(fp128 %IV.S.)
  %.not = icmp eq i64 %4, %5
  br i1 %.not, label %13, label %split

```
With a little libquadmath test program, it looks like `0xL7000000000000000403DFFFFFFF6AFD0` is one greater than `%4`, which causes this test to fail. 

```
9223372026954775807 | %lsr.iv1 on entry
         -100000000 |
------------------- |
9223372026854775807 | %4
                    |
9223372026854775808 | this hex value converted to int
                    | 0xL7000000000000000403DFFFFFFF6AFD0
```
---
Extra context: In the IR flang outputs directly after lowering from mlir, the int to float conversion is an `sitofp` instruction, but instcombine changes this to a `uitofp` earlier in the pipeline. If we change the `uitofp` back into an `sitofp` in the godbolt then we get a passing test again.

This is the Fortran source:
```
real(kind=16) dd, lowest, highest
integer(kind=8) :: i, incr, big
integer :: n = 100
incr = 100000000_8
do i = huge(i) - 10000000000_8,huge(i)-incr,incr
  if (int(real(i,kind=16),kind=8).ne.i) then
  print *,i,real(i,kind=16),int(real(i,kind=16),kind=8)
  stop 'FAIL'
  endif
enddo
print *,'ok'
end
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to