Feng -

FYI, Microsoft has agreed that this is an issue, which they will not fix until 
the next major release. Please see:

https://connect.microsoft.com/VisualStudio/feedback/details/788991/ltcg-code-generation-bug-in-x64

They said:

"Thanks for the clarification! You are correct, this is indeed a bug in the 
compiler optimizer.

The optimizer is attempting to use "length" to determine the offset into "y", 
so we can avoid incrementing "y" in the loop.
However, we incorrectly calculate the base value of "y".

We will look into addressing this bug for the next major release. If you can 
change the source, you can workaround the bug by defining "length" as volatile.

VC++ Compiler Team"

From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Friday, May 24, 2013 6:05 PM
To: edk2-devel@lists.sourceforge.net
Cc: Jinson Tsai
Subject: Re: [edk2] LTCG and fixed address pointers.

Feng -

FYI, here is the shorter version of my test files without the 2nd function. As 
you can see, it is fairly simple. This is why we are worried about possible 
side-effects with LTCG.

Tim



From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Friday, May 24, 2013 9:16 AM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Cc: Jinson Tsai
Subject: Re: [edk2] LTCG and fixed address pointers.

Feng -

I have been able to remove the 2nd function, and still have the issue. I have 
reported it to Microsoft on the forums, no respone.

My problem is: it is very hard to scan the source code to find these conditions.

Tim

From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Friday, May 24, 2013 2:52 AM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Cc: Jinson Tsai
Subject: Re: [edk2] LTCG and fixed address pointers.

Hi, Tim

I have reproduced your case at my side with VS2008x86_amd64 tool chain.

I found this issue only happen when the calling sequence is same with your 
example.

It needs two internal functions which uses the same PCD pointer as parameter. 
It also needs a for() loop and a while() loop in these two functions. It needs 
a return value in the first function. If one of these conditions couldn't meet, 
the compiler would not generate the problematic code at my side.

Looks like Visual studio's bug:( a workaround I can think is try to merge 
TestLen() and BvdtLibAscii2Unicode() into one function call. Have you tried 
this way?

Thanks
Feng

From: Tian, Feng
Sent: Friday, May 24, 2013 14:50
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Cc: Jinson Tsai; Tian, Feng
Subject: RE: [edk2] LTCG and fixed address pointers.

Hi, Tim

I completely followed your steps and didn't get your result. Please refer to 
the dump.txt.

Whether the difference is I am using VS2008x86 with win7 64bit OS but you are 
using VS2008 64bit version with win7 64bit OS?

Thanks
Feng

From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Friday, May 24, 2013 02:55
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Cc: Jinson Tsai
Subject: Re: [edk2] LTCG and fixed address pointers.

Feng -

Our compiler options are the same as yours for VS2008. Here is a small function 
which duplicates the problem.

Compile with:

cl /c /GL /O1b2is /Gy /GF /GS- x.c aa.c
link /DEBUG /LTCG /OPT:REF /OPT:ICF=10 /SECTION:.xdata,D /SECTION:.pdata,D 
/IGNORE:4254 /MERGE:.data=.text /MERGE:.rdata=.text x.obj aa.obj
dumpbin /disasm x.exe >output.txt

Here is the code generated for main:

main:
  00000001400076D0: 48 81 EC 98 00 00  sub         rsp,98h
                    00
  00000001400076D7: BA 4F 8B FE FF     mov         edx,0FFFE8B4Fh
  00000001400076DC: 33 C0              xor         eax,eax
  00000001400076DE: 38 02              cmp         byte ptr [rdx],al
  00000001400076E0: 74 18              je          00000001400076FA
  00000001400076E2: 48 FF C0           inc         rax
  00000001400076E5: 80 B8 4F 8B FE FF  cmp         byte ptr [rax-174B1h],0
                    00
  00000001400076EC: 75 F4              jne         00000001400076E2
  00000001400076EE: 83 F8 32           cmp         eax,32h
  00000001400076F1: 7E 07              jle         00000001400076FA
  00000001400076F3: B8 FB FF FF FF     mov         eax,0FFFFFFFBh
  00000001400076F8: EB 2A              jmp         0000000140007724
  00000001400076FA: 4C 8D 44 24 20     lea         r8,[rsp+20h]
  00000001400076FF: 0F BE 0A           movsx       ecx,byte ptr [rdx]
  0000000140007702: 48 FF C2           inc         rdx
  0000000140007705: 66 41 89 08        mov         word ptr [r8],cx
  0000000140007709: 4D 8D 40 02        lea         r8,[r8+2]
  000000014000770D: 84 C9              test        cl,cl
  000000014000770F: 75 EE              jne         00000001400076FF
  0000000140007711: 48 8D 54 24 20     lea         rdx,[rsp+20h]
  0000000140007716: 48 8D 0D DB FE FF  lea         
rcx,[??_C@_03NNECAHIM@?$CFS?6?$AA@]
                    FF
  000000014000771D: E8 22 00 00 00     call        printf
  0000000140007722: 33 C0              xor         eax,eax
  0000000140007724: 48 81 C4 98 00 00  add         rsp,98h
                    00
  000000014000772B: C3                 ret

From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Thursday, May 23, 2013 12:08 AM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.

Hi, Tim

It's weird why I didn't meet your issue?

VariableDxe.c.patch is what I modified to emulate your case.

The pcd definition is updated to:
  ## 64-bit Base address of the NV variable range in flash device
  
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0xFFE00008|UINT64|0x80000001

The CC flag is:
  DEBUG_VS2008x86_X64_CC_FLAGS     = /nologo /c /WX /GS- /X /W4 /Gs32768 /D 
UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gm
The Link flag is:
  DEBUG_VS2008x86_X64_DLINK_FLAGS  = /NOLOGO /NODEFAULTLIB /IGNORE:4001 
/OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D 
/Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) 
/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG

[From above build flag, we can know LTO feature is enabled as /GL and /LTCG has 
been used]

The output.txt is the disassembly file of "dmpbin.exe", in which line 26 ~28, I 
don't see the assembly code segment like you shown. (due to 512k mail size 
limitation, I have to trim some output in output.txt)

The disassembly code is:
  0000000000000A12: B8 08 01 E0 FF     mov         eax,0FFE00108h
  0000000000000A17: B9 08 00 E0 FF     mov         ecx,0FFE00008h
  0000000000000A1C: 80 38 00           cmp         byte ptr [rax],0

So what build flag are you using?

Thanks
Feng

From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Thursday, May 23, 2013 09:30
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.

To follow up further, the problem appears to be an encoding error:

The bytes for the encoding are below. The value of the PCD was 
0x00000000ffe8b00e

  0000000000063B24: 44 38 B0 0E B0 E8 FF cmp         byte ptr [rax-174FF2h],r14b

44 = extend the R field in the mod R/M byte.
38 = compare
B0 = modrm = [rax+disp32], and r = r14
Disp32 = ffe8b0038

Notice that the PCD value is encoded directly as a displacement. But, in 64-bit 
modes, displacements are sign-extended (see 2.2.1.3 in Vol 2 of the Intel Ref) 
to 64-bits, which means it acts, -effectively, like a subtraction. For an 
unsigned integer, it must be encoded with a register. In fact, a few 
instructions before, you can see:

  0000000000063B14: BA 0E B0 E8 FF     mov         edx,0FFE8B00Eh

So this would have been better encoded as cmp byte ptr [rax + rdx], r14b

Tim


From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Tuesday, May 21, 2013 9:41 PM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.

We tried as a UINT64. Same result. Tim

From: Tian, Feng [mailto:feng.t...@intel.com]
Sent: Tuesday, May 21, 2013 8:26 PM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: Re: [edk2] LTCG and fixed address pointers.

How about defining this Pcd as UINT64? We defined PcdPciExpressBaseAddress like 
this way.

So your code should be:

In Dec file:
  gXxxTokenSpaceGuid.PcdXxxAddress|0xFFe8B00E|UINT64|0x12345678

In C code:
  StrPtr = PcdGet64 (PcdXXX) + 0x100;

From: Tim Lewis [mailto:tim.le...@insyde.com]
Sent: Wednesday, May 22, 2013 01:16
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Subject: [edk2] LTCG and fixed address pointers.

We are having trouble with link-time code generation under Visual Studio when 
using PCDs to specify a specific address and convert it to a pointer, when 
accessed from a library. In a library, the FixedAtBuild PCDs (on x64) are 
defned as extern const UINT32 PcdXXXX; and PcdXXXX contains 0xffe8b00e. The 
code generated by VS2008/2010/2012 linker shows:


xor         r12d,r12d         // r12d = 0

mov         eax,r12d          // eax = r12d == 0  rax = ?

cmp         byte ptr [rax-174FF2h],r12b

Notice LTCG is trying to optimize by using a relative offset from 0. "0 - 
174ff2" is FFFFFFFFFFE8B00E (not FFe8B00e).

The code in question is in the form:

CHAR8 *StrPtr;

StrPtr = (CHAR8 *)(UINTN) (PcdGet(PcdXXXX) + 0x100))
while (*StrPtr != '\0') {
...
}

We have tried nearly everything we can think of, other than turning off LTCG 
for the module or even the specific lines. I am worried about what happens with 
MMIO and other "fixed" addresses. I have tried (CHAR8 *)(UINTN) (UINT32)  and 
almost every possible combination of typecases on the PCD result and the 0x100, 
etc. Even did & 0xffffffff. No effect.

If I turn off LTCG, it correctly creates a 32-bit address.

I haven't been able to get any response on the MS forums.

Anyone have any experience with this?

Tim
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to