1 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=FTOL 2 ; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT 3 ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=COMPILERRT 4 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s -check-prefix=COMPILERRT 5 ; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=COMPILERRT 6 ; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s -check-prefix=COMPILERRT 7 ; RUN: llc < %s -mattr=-sse -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=FTOL_2 8 9 ; Win32 targets use the MSVCRT _ftol2 runtime function for fptoui to i64. This 10 ; function has a nonstandard calling convention: the input value is expected on 11 ; the x87 stack instead of the callstack. The input value is popped by the 12 ; callee. Mingw32 uses normal cdecl compiler-rt functions. 13 14 define i64 @double_ui64(double %x) nounwind { 15 entry: 16 ; COMPILERRT: @double_ui64 17 ; COMPILERRT-NOT: calll __ftol2 18 ; FTOL: @double_ui64 19 ; FTOL: fldl 20 ; FTOL: calll __ftol2 21 ; FTOL-NOT: fstp 22 %0 = fptoui double %x to i64 23 ret i64 %0 24 } 25 26 define i64 @float_ui64(float %x) nounwind { 27 entry: 28 ; COMPILERRT: @float_ui64 29 ; COMPILERRT-NOT: calll __ftol2 30 ; FTOL: @float_ui64 31 ; FTOL: flds 32 ; FTOL: calll __ftol2 33 ; FTOL-NOT: fstp 34 %0 = fptoui float %x to i64 35 ret i64 %0 36 } 37 38 define i64 @double_ui64_2(double %x, double %y, double %z) nounwind { 39 ; COMPILERRT: @double_ui64_2 40 ; FTOL: @double_ui64_2 41 ; FTOL_2: @double_ui64_2 42 ;; stack is empty 43 ; FTOL_2: fldl 44 ;; stack is %z 45 ; FTOL_2: fldl 46 ;; stack is %y %z 47 ; FTOL_2: fldl 48 ;; stack is %x %y %z 49 ; FTOL_2: fdiv %st(0), %st(1) 50 ;; stack is %x %1 %z 51 ; FTOL_2: fsubp %st(2) 52 ;; stack is %1 %2 53 ; FTOL_2: fxch 54 ; FTOL_2-NOT: fld 55 ; FTOL_2-NOT: fst 56 ;; stack is %2 %1 57 ; FTOL_2: calll __ftol2 58 ; FTOL_2-NOT: fxch 59 ; FTOL_2-NOT: fld 60 ; FTOL_2-NOT: fst 61 ; FTOL_2: calll __ftol2 62 ;; stack is empty 63 64 %1 = fdiv double %x, %y 65 %2 = fsub double %x, %z 66 %3 = fptoui double %1 to i64 67 %4 = fptoui double %2 to i64 68 %5 = sub i64 %3, %4 69 ret i64 %5 70 } 71 72 define i64 @double_ui64_3(double %x, double %y, double %z) nounwind { 73 ; COMPILERRT: @double_ui64_3 74 ; FTOL: @double_ui64_3 75 ; FTOL_2: @double_ui64_3 76 ;; stack is empty 77 ; FTOL_2: fldl 78 ;; stack is %z 79 ; FTOL_2: fldl 80 ;; stack is %y %z 81 ; FTOL_2: fldl 82 ;; stack is %x %y %z 83 ; FTOL_2: fdiv %st(0), %st(1) 84 ;; stack is %x %1 %z 85 ; FTOL_2: fsubp %st(2) 86 ;; stack is %1 %2 87 ; FTOL_2-NOT: fxch 88 ; FTOL_2-NOT: fld 89 ; FTOL_2-NOT: fst 90 ;; stack is %1 %2 (still) 91 ; FTOL_2: calll __ftol2 92 ; FTOL_2-NOT: fxch 93 ; FTOL_2-NOT: fld 94 ; FTOL_2-NOT: fst 95 ; FTOL_2: calll __ftol2 96 ;; stack is empty 97 98 %1 = fdiv double %x, %y 99 %2 = fsub double %x, %z 100 %3 = fptoui double %1 to i64 101 %4 = fptoui double %2 to i64 102 %5 = sub i64 %4, %3 103 ret i64 %5 104 } 105 106 define {double, i64} @double_ui64_4(double %x, double %y) nounwind { 107 ; COMPILERRT: @double_ui64_4 108 ; FTOL: @double_ui64_4 109 ; FTOL_2: @double_ui64_4 110 ;; stack is empty 111 ; FTOL_2: fldl 112 ;; stack is %y 113 ; FTOL_2: fldl 114 ;; stack is %x %y 115 ; FTOL_2: fxch 116 ;; stack is %y %x 117 ; FTOL_2: calll __ftol2 118 ;; stack is %x 119 ; FTOL_2: fld %st(0) 120 ;; stack is %x %x 121 ; FTOL_2: calll __ftol2 122 ;; stack is %x 123 124 %1 = fptoui double %x to i64 125 %2 = fptoui double %y to i64 126 %3 = sub i64 %1, %2 127 %4 = insertvalue {double, i64} undef, double %x, 0 128 %5 = insertvalue {double, i64} %4, i64 %3, 1 129 ret {double, i64} %5 130 } 131 132 define i32 @double_ui32_5(double %X) { 133 ; FTOL: @double_ui32_5 134 ; FTOL: calll __ftol2 135 %tmp.1 = fptoui double %X to i32 136 ret i32 %tmp.1 137 } 138 139 define i64 @double_ui64_5(double %X) { 140 ; FTOL: @double_ui64_5 141 ; FTOL: calll __ftol2 142 %tmp.1 = fptoui double %X to i64 143 ret i64 %tmp.1 144 } 145