1; RUN: llc < %s -mtriple=i686-pc-win32 -mcpu=generic | 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 14define i64 @double_ui64(double %x) nounwind { 15entry: 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 26define i64 @float_ui64(float %x) nounwind { 27entry: 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 38define 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 %2 to i64 67 %4 = fptoui double %1 to i64 68 %5 = sub i64 %4, %3 69 ret i64 %5 70} 71 72define 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 106define {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 %y to i64 125 %2 = fptoui double %x to i64 126 %3 = sub i64 %2, %1 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 132define 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 139define 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