Optimization problem

Our application crashes during execution a floating point instruction. It seems to be an incorrect optimization.

When the method 'CLPController::StopPlaying' is called from the 'CLPController::SetLogTime', a floating point value is remaining on the top of the FPU stack:

00AC4575  call        CLPController::StopPlaying (0AC3090h)
00AC457A  fstp        qword ptr [esi+24h]

'CLPController::StopPlaying' indirectly calls the ::MoveWindowW function which sometimes empties the FPU stack. It causes a crash at a next FPU instruction (in the another place) because the 'invalid instruction' flag is set.

Both methods are noninline and are defined in the same .cpp file.

In this place the problem can be solved by adding any __asm instruction which suppresses optimisation, but we can't be sure we've fixed this problem anywhere.

Sergey Ryazanov,
Transas, VTS Department

--------------------------------------------------------------------------------
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86

/O2 /G7 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LOG_IMPL" /D "_AFXEXT" /D "_HASLANGDLL_" /D "ENABLE_ASSURE" /D "ENABLE_TRACE" /D "USE_WINSOCK2" /D "_WINDLL" /D "_AFXDLL" /D "_UNICODE" /Gm /EHsc /MD /Zp1 /GR /Yu"GUI\StdGUI.h" /Fp".\..\..\VCOBJ\Release Unicode\Log\Log.pch" /Fo".\..\..\VCOBJ\Release Unicode\Log\\" /Fd".\..\..\VCOBJ\Release Unicode\Log\vc70.pdb" /W4 /nologo /c /Zi


// FULL_TIME - double
--- c:\work\current\vts\src\log\logplay\lpservice.cpp --------------------------

void CLPController::SetLogTime(FULL_TIME time) {
00AC4500  push        esi 
00AC4501  mov         esi,ecx
  _assure( Player != NULL );
00AC4503  cmp         dword ptr [esi+4],0
00AC4507  push        edi 
00AC4508  mov         edi,dword ptr [__imp___assure_fail (0ACDBF8h)]
00AC450E  jne         CLPController::SetLogTime+29h (0AC4529h)
00AC4510  push        8Dh 
00AC4515  push        offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC451A  push        offset string L"" (0ACDEDCh)
00AC451F  push        offset string L"Player != 0" (0AD827Ch)
00AC4524  call        edi 
00AC4526  add         esp,10h

  GUARD_IF_NOT ( MinTime <= time && time <= MaxTime )
00AC4529  fld         qword ptr [esp+0Ch]
00AC452D  fcom        qword ptr [esi+1Ch]
00AC4530  fnstsw      ax  
00AC4532  test        ah,1
00AC4535  jne         CLPController::SetLogTime+41h (0AC4541h)
00AC4537  fcom        qword ptr [esi+2Ch]
00AC453A  fnstsw      ax  
00AC453C  test        ah,41h
00AC453F  jnp         CLPController::SetLogTime+5Fh (0AC455Fh)
00AC4541  push        8Fh 
00AC4546  fstp        st(0)
00AC4548  push        offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC454D  push        offset string L"" (0ACDEDCh)
00AC4552  push        offset string L"MinTime <= time && t"... (0AD8D68h)
00AC4557  call        edi 
  {
    time = MinTime;
00AC4559  fld         qword ptr [esi+1Ch]
00AC455C  add         esp,10h
  }

  if (IsTimeEqual(LogTime, time)) return;
00AC455F  fld         qword ptr [esi+24h]
00AC4562  fsub        st,st(1)
00AC4564  fabs            
00AC4566  fcomp       qword ptr [__real@4059000000000000 (0AD4788h)]
00AC456C  fnstsw      ax  
00AC456E  test        ah,5
00AC4571  jnp         CLPController::SetLogTime+90h (0AC4590h)

  StopPlaying();
00AC4573  mov         ecx,esi
00AC4575  call        CLPController::StopPlaying (0AC3090h)

  // __asm { fwait } // this code solves the problem

  LogTime = time;
00AC457A  fstp        qword ptr [esi+24h]
  OnTimeChanged();
00AC457D  mov         eax,dword ptr [esi]
00AC457F  mov         ecx,esi
00AC4581  call        dword ptr [eax+20h]

  NeedleDown();
00AC4584  mov         ecx,esi
00AC4586  call        CLPController::NeedleDown (0AC4000h)
00AC458B  pop         edi 
00AC458C  pop         esi 
}
00AC458D  ret         8   
00AC4590  pop         edi 

  NeedleDown();
00AC4591  fstp        st(0)
00AC4593  pop         esi 
}
00AC4594  ret         8


--- c:\work\current\vts\src\log\logplay\lpservice.cpp --------------------------

void CLPController::StopPlaying()
{
00AC3090  push        esi 
00AC3091  mov         esi,ecx
   _assure( Player != NULL );
00AC3093  cmp         dword ptr [esi+4],0
00AC3097  push        edi 
00AC3098  mov         edi,dword ptr [__imp___assure_fail (0ACDBF8h)]
00AC309E  jne         CLPController::StopPlaying+45h (0AC30D5h)
00AC30A0  push        0D2h
00AC30A5  push        offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC30AA  push        offset string L"" (0ACDEDCh)
00AC30AF  push        offset string L"Player != 0" (0AD827Ch)
00AC30B4  call        edi 
00AC30B6  add         esp,10h

   if ( IsPlaying () )
00AC30B9  cmp         dword ptr [esi+4],0
00AC30BD  jne         CLPController::StopPlaying+45h (0AC30D5h)
00AC30BF  push        6Ch 
00AC30C1  push        offset string L"\\Work\\Current\\vts\\Sr"... (0AD88B8h)
00AC30C6  push        offset string L"" (0ACDEDCh)
00AC30CB  push        offset string L"Player != 0" (0AD827Ch)
00AC30D0  call        edi 
00AC30D2  add         esp,10h
00AC30D5  mov         eax,dword ptr [esi+4]
00AC30D8  cmp         byte ptr [eax+219h],0
00AC30DF  pop         edi 
00AC30E0  je          CLPController::StopPlaying+5Ah (0AC30EAh)
   {
      Player -> Stop ();
00AC30E2  mov         ecx,eax
00AC30E4  mov         edx,dword ptr [ecx]
00AC30E6  pop         esi 
00AC30E7  jmp         dword ptr [edx+30h]
00AC30EA  pop         esi 
   }
}
00AC30EB  ret




Answer this question

Optimization problem

  • rexian

    Sounds Good!

    Please go ahead and report the bug and the responsible folks will have a look. After the bug is reported, keep checking the site for workarounds or additional feedback on the bug.

    Thanks for raising the issue Sergey!

    Thanks,
      Ayman Shoukry
      VC++ Team



  • moebiusproject

    You can cotact microsoft to report such a bug by using the info at:
    http://support.microsoft.com/gp/contactbug

    In addition, it would still be great if report the bug on lab.msdn.microsoft.com so that the reponsible folks would investigate if it can still be reproduced using VS 2005. Mention in your report that it reproduces in VS 2003 as well. After folks look at it, they would probably update the bug entry with workarounds if possible.

    Thanks,
       Ayman Shoukry
       VC++ Team.

  • Rogvi Knudsen

    From the asm, it looks like an optmization issue but I can't say for sure unless there are more info on how exactly StopPlaying calls MoveWindowW and of course the asm generated for MoveWindowW.

    Any ways, could you make sure that the debug build doesn't reproduce the problem

    If that is the case, then please report a bug at
    http://lab.msdn.microsoft.com with all the extra needed info.

    Also, I have noticed you are not using VS2005 where a whole new floating point model is introduced giving the developer more control over the FP optmizations.
    Here is a nice link discussing such model: http://msdn.microsoft.com/library/default.asp url=/library/en-us/dv_vstechart/html/floapoint.asp

    Thanks for raising the issue!

    Ayman Shoukry
    VC++ Team

  • shorinsamurai

    This site (http://lab.msdn.microsoft.com) accepts only VC++ 2005 issues, but the problem has been found in VC++ 2003.


  • ChiragGandhi

    Method StopPlaying calls virtual method Stop ('Player -> Stop ();'). The method 'Stop' calls 'MoveWindow' indirectly (through 5-10 another mwthods).

    I think an asm code of MoveWidnowW is unessential because it is permissible behaviour (by the way, it's been reproduced under Win2000 and WinXP). It is enough that the 'Stop' method is virtual.

    I'm sure that this problem isn't reproduced in the debug configuration. Moreover, local suppressing of optimization (by __asm {fwait} instruction) is enough.

    I'll report at this site, but I don't know what extra information I can provide. I haven't managed to reproduce the same problem outside our application.

    Sergey Ryazanov,
    Transas, VTS Department



  • Optimization problem