[X86] Fix a bug in WIN_FTOL_32/64 handling.
authorMichael Kuperstein <michael.m.kuperstein@intel.com>
Tue, 30 Jun 2015 14:38:57 +0000 (14:38 +0000)
committerMichael Kuperstein <michael.m.kuperstein@intel.com>
Tue, 30 Jun 2015 14:38:57 +0000 (14:38 +0000)
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

llvm/lib/Target/X86/X86FloatingPoint.cpp
llvm/test/CodeGen/X86/win_ftol2.ll

index 3b0bd03..40b9c8a 100644 (file)
@@ -1530,7 +1530,7 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &Inst) {
     if (Op.isKill())
       moveToTop(FPReg, Inst);
     else
-      duplicateToTop(FPReg, FPReg, Inst);
+      duplicateToTop(FPReg, ScratchFPReg, Inst);
 
     // Emit the call. This will pop the operand.
     BuildMI(*MBB, Inst, MI->getDebugLoc(), TII->get(X86::CALLpcrel32))
index 1459124..dfa6e3a 100644 (file)
@@ -142,3 +142,25 @@ define i64 @double_ui64_5(double %X) {
   %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
+}