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