[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)

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

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.