Visual Studio 2022 generates bad code (UPDATE: not any more)

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Visual Studio 2022 generates bad code (UPDATE: not any more)

Postby gm_matthew » Fri Dec 31, 2021 4:48 pm

I recently came across the issue of some games not working in Supermodel when using a Visual Studio 2022 release build. After hours of searching for a root cause, I discovered that it's due to the optimizing compiler generating bad code.

Here is the code that is incorrectly compiled, when ppc603_exception(EXCEPTION_IRQ) is called:

Code: Select all
            if( msr & MSR_IP )
               ppc.npc = 0xfff00000 | 0x0500;
            else
               ppc.npc = 0x00000000 | 0x0500;

            ppc_change_pc(ppc.npc);

If the MSR_IP flag is set, then we should be passing 0xFFF00500 to the ppc_change_pc() function, otherwise we should be passing 0x00000500. But the VS2022 compiler generates code that always passes 0xFFF00500, regardless of whether MSP_IP is set or not.

Here are some relevant excerpts from the generated assembly file:

Code: Select all
; 51   :             if (msr & MSR_IP)

   mov   edx, 1280            ; 00000500H
   bt   ebx, 6
   mov   eax, edx
   mov   ecx, -1047296            ; fff00500H
   cmovb   eax, ecx

; 235  :          {
; 236  :             ppc603_exception(EXCEPTION_IRQ);
; 237  :          }

   jmp   $LN199@ppc603_che

ebx contains the value of MSR and is tested for the MSR_IP flag (0x40); if it is set, eax is set to 0xFFF00500, otherwise it is set to 0x00000500. So far, so good.

Code: Select all
   test   ebx, 64               ; 00000040H
$LN199@ppc603_che:
   cmove   ecx, edx
   mov   DWORD PTR ?ppc@@3UPPC_REGS@@A+136, eax
   add   rsp, 32               ; 00000020H
   pop   rbx
   jmp   ?ppc_change_pc@@YAXI@Z         ; ppc_change_pc


The intention is to set ecx (0xFFF00500) to the value of edx (0x00000500) if the MSR_FLAG is not set. However, the compiler has messed up and is using the wrong compare instruction; instead of checking the carry flag (which is the one that stores the result of a bit test), it is checking the zero flag which, while correct for a regular test instruction, is undefined after a bit test. In this case, ecx is not being set to 0x00000500 and the ppc_change_pc() function is passed the wrong value (it should be noted that ppc.npc is always set to the correct value). Eventually, at some point the PowerPC interpreter fetches the wrong opcode and chaos ensues.

I'm going to switch back to Visual Studio 2019 for the time being since it compiles this code correctly. We shouldn't have to try and work around a bug with the VS2022 compiler.
Last edited by gm_matthew on Fri Sep 01, 2023 5:17 am, edited 1 time in total.
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Visual Studio 2022 generates bad code

Postby Ian » Fri Dec 31, 2021 5:50 pm

That's pretty damn rare to find such a compiler bug. Should definitely file the bug to Microsoft. They are generally quite fast from what I understand in fixing them.

https://docs.microsoft.com/en-us/visual ... ual-studio

I think you can post it on the community pages too
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Visual Studio 2022 generates bad code

Postby Ian » Mon Sep 19, 2022 2:02 pm

Eric Brumer [MSFT] has posted a new comment on VS2022 compiler bug compiling supermodel emulator

Hi, thanks for the bug report. With the latest upload I confirm that there's incorrect codegen in the compiler. The bug is in a "test -> bt" optimization.
It finds these instructions (written in pseudo-asm code... destinations are on the left):
cc = test ebx, 64
eax = mov adx
eax = cmovne cc_zf, ecx, eax
LN1:
ecx = cmove cc_zf, edx, ecx
... other instructions ...
cc = test ebx, 64
jmp LN1
Of note:
There's a cmove instruction that has two paths into it. Each path has a 'cc = test ebx, 64' on it. The first path is fallthrough from above, and the second path is from the 'jmp LN1' later on.
The first test instruction feeds the cmove, and it also feeds the cmovne.
It looks like we have identified the test -> cmovne and changed that into a bt -> cmovb, but we didn't change the cmove instruction (or the 2nd test), which is what's causing the bad codegen.
We'll see if there's a viable workaround here, but this code is super old and I'm not seeing any recent changes to it. I suspect you're getting unlucky and the issue was exposed due to other optimizations. We'll reply back here as we have a fix ready.
Thanks,
Eric Brumer
Visual C++ Team
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Visual Studio 2022 generates bad code

Postby Ian » Tue Nov 01, 2022 3:32 pm

Feedback Bot has changed the status of VS2022 compiler bug compiling supermodel emulator on Visual Studio Developer Community to Pending Release.

A fix for this issue has been internally implemented and is being prepared for release. We'll update you once it becomes available for download.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Visual Studio 2022 generates bad code

Postby Ian » Thu Feb 23, 2023 3:57 am

This issue has been marked as closed. So I guess it should compile with vs2022 now lol
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Visual Studio 2022 generates bad code

Postby gm_matthew » Mon Apr 10, 2023 10:09 am

VS2022 64-bit release builds are still not working properly, tested with version 17.5.3 :x
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Visual Studio 2022 generates bad code

Postby Ian » Mon Apr 10, 2023 10:51 am

Same error?
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Visual Studio 2022 generates bad code

Postby gm_matthew » Mon Apr 10, 2023 11:14 am

Ian wrote:Same error?

Yep
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK

Re: Visual Studio 2022 generates bad code

Postby Ian » Mon Apr 10, 2023 11:51 am

Eric Brumer actually messaged me about this bug on reddit. I'll give him a shout directly to confirm the fix is actually in the latest version.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Visual Studio 2022 generates bad code

Postby gm_matthew » Thu Aug 31, 2023 5:44 pm

Supermodel now compiles properly in the latest version of VS2022 :D
gm_matthew
 
Posts: 224
Joined: Fri Oct 07, 2011 7:29 am
Location: Bristol, UK


Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest