mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
16ecf4031e
Duplicating an FP register "as itself" is a bad idea, since it violates the invariant that every FP register is mapped to at most one FPU stack slot. Use the scratch FP register instead. This fixes PR23957. llvm-svn: 241069
167 lines
4.0 KiB
LLVM
167 lines
4.0 KiB
LLVM
; RUN: llc < %s -mtriple=i686-pc-win32 -mcpu=generic | FileCheck %s -check-prefix=FTOL
|
|
; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT
|
|
; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=COMPILERRT
|
|
; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=COMPILERRT
|
|
; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT
|
|
; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s -check-prefix=COMPILERRT
|
|
; RUN: llc < %s -mattr=-sse -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=FTOL_2
|
|
|
|
; Win32 targets use the MSVCRT _ftol2 runtime function for fptoui to i64. This
|
|
; function has a nonstandard calling convention: the input value is expected on
|
|
; the x87 stack instead of the callstack. The input value is popped by the
|
|
; callee. Mingw32 uses normal cdecl compiler-rt functions.
|
|
|
|
define i64 @double_ui64(double %x) nounwind {
|
|
entry:
|
|
; COMPILERRT: @double_ui64
|
|
; COMPILERRT-NOT: calll __ftol2
|
|
; FTOL: @double_ui64
|
|
; FTOL: fldl
|
|
; FTOL: calll __ftol2
|
|
; FTOL-NOT: fstp
|
|
%0 = fptoui double %x to i64
|
|
ret i64 %0
|
|
}
|
|
|
|
define i64 @float_ui64(float %x) nounwind {
|
|
entry:
|
|
; COMPILERRT: @float_ui64
|
|
; COMPILERRT-NOT: calll __ftol2
|
|
; FTOL: @float_ui64
|
|
; FTOL: flds
|
|
; FTOL: calll __ftol2
|
|
; FTOL-NOT: fstp
|
|
%0 = fptoui float %x to i64
|
|
ret i64 %0
|
|
}
|
|
|
|
define i64 @double_ui64_2(double %x, double %y, double %z) nounwind {
|
|
; COMPILERRT: @double_ui64_2
|
|
; FTOL: @double_ui64_2
|
|
; FTOL_2: @double_ui64_2
|
|
;; stack is empty
|
|
; FTOL_2: fldl
|
|
;; stack is %z
|
|
; FTOL_2: fldl
|
|
;; stack is %y %z
|
|
; FTOL_2: fldl
|
|
;; stack is %x %y %z
|
|
; FTOL_2: fdiv %st(0), %st(1)
|
|
;; stack is %x %1 %z
|
|
; FTOL_2: fsubp %st(2)
|
|
;; stack is %1 %2
|
|
; FTOL_2: fxch
|
|
; FTOL_2-NOT: fld
|
|
; FTOL_2-NOT: fst
|
|
;; stack is %2 %1
|
|
; FTOL_2: calll __ftol2
|
|
; FTOL_2-NOT: fxch
|
|
; FTOL_2-NOT: fld
|
|
; FTOL_2-NOT: fst
|
|
; FTOL_2: calll __ftol2
|
|
;; stack is empty
|
|
|
|
%1 = fdiv double %x, %y
|
|
%2 = fsub double %x, %z
|
|
%3 = fptoui double %2 to i64
|
|
%4 = fptoui double %1 to i64
|
|
%5 = sub i64 %4, %3
|
|
ret i64 %5
|
|
}
|
|
|
|
define i64 @double_ui64_3(double %x, double %y, double %z) nounwind {
|
|
; COMPILERRT: @double_ui64_3
|
|
; FTOL: @double_ui64_3
|
|
; FTOL_2: @double_ui64_3
|
|
;; stack is empty
|
|
; FTOL_2: fldl
|
|
;; stack is %z
|
|
; FTOL_2: fldl
|
|
;; stack is %y %z
|
|
; FTOL_2: fldl
|
|
;; stack is %x %y %z
|
|
; FTOL_2: fdiv %st(0), %st(1)
|
|
;; stack is %x %1 %z
|
|
; FTOL_2: fsubp %st(2)
|
|
;; stack is %1 %2
|
|
; FTOL_2-NOT: fxch
|
|
; FTOL_2-NOT: fld
|
|
; FTOL_2-NOT: fst
|
|
;; stack is %1 %2 (still)
|
|
; FTOL_2: calll __ftol2
|
|
; FTOL_2-NOT: fxch
|
|
; FTOL_2-NOT: fld
|
|
; FTOL_2-NOT: fst
|
|
; FTOL_2: calll __ftol2
|
|
;; stack is empty
|
|
|
|
%1 = fdiv double %x, %y
|
|
%2 = fsub double %x, %z
|
|
%3 = fptoui double %1 to i64
|
|
%4 = fptoui double %2 to i64
|
|
%5 = sub i64 %4, %3
|
|
ret i64 %5
|
|
}
|
|
|
|
define {double, i64} @double_ui64_4(double %x, double %y) nounwind {
|
|
; COMPILERRT: @double_ui64_4
|
|
; FTOL: @double_ui64_4
|
|
; FTOL_2: @double_ui64_4
|
|
;; stack is empty
|
|
; FTOL_2: fldl
|
|
;; stack is %y
|
|
; FTOL_2: fldl
|
|
;; stack is %x %y
|
|
; FTOL_2: fxch
|
|
;; stack is %y %x
|
|
; FTOL_2: calll __ftol2
|
|
;; stack is %x
|
|
; FTOL_2: fld %st(0)
|
|
;; stack is %x %x
|
|
; FTOL_2: calll __ftol2
|
|
;; stack is %x
|
|
|
|
%1 = fptoui double %y to i64
|
|
%2 = fptoui double %x to i64
|
|
%3 = sub i64 %2, %1
|
|
%4 = insertvalue {double, i64} undef, double %x, 0
|
|
%5 = insertvalue {double, i64} %4, i64 %3, 1
|
|
ret {double, i64} %5
|
|
}
|
|
|
|
define i32 @double_ui32_5(double %X) {
|
|
; FTOL: @double_ui32_5
|
|
; FTOL: calll __ftol2
|
|
%tmp.1 = fptoui double %X to i32
|
|
ret i32 %tmp.1
|
|
}
|
|
|
|
define i64 @double_ui64_5(double %X) {
|
|
; FTOL: @double_ui64_5
|
|
; FTOL: calll __ftol2
|
|
%tmp.1 = fptoui double %X to i64
|
|
ret i64 %tmp.1
|
|
}
|
|
|
|
define double @pr23957_32(double %A) {
|
|
; FTOL-LABEL: @pr23957_32
|
|
; FTOL: fldl
|
|
; FTOL-NEXT: fld %st(0)
|
|
; FTOL-NEXT: calll __ftol2
|
|
%B = fptoui double %A to i32
|
|
%C = uitofp i32 %B to double
|
|
%D = fsub double %C, %A
|
|
ret double %D
|
|
}
|
|
|
|
define double @pr23957_64(double %A) {
|
|
; FTOL-LABEL: @pr23957_64
|
|
; FTOL: fldl
|
|
; FTOL-NEXT: fld %st(0)
|
|
; FTOL-NEXT: calll __ftol2
|
|
%B = fptoui double %A to i64
|
|
%C = uitofp i64 %B to double
|
|
%D = fsub double %C, %A
|
|
ret double %D
|
|
}
|