Whoha, I found a compiler bug
Thursday, February 18, 2010 | Permalink
I gave Visual Studio 2010 RC a few quick runs and while doing so I noticed that it doesn't always generate optimal code with the StringHash code I
mentioned recently. Often it behaves just like you expect and outputs the constant directly, but it happens that it generates some clearly suboptimal results. This is a call to Context::SetConstantBuffer():
mov eax, dword ptr [ebx+9D0h]
push eax
push ecx
mov eax, esp
mov dword ptr [eax], 0
mov dword ptr [eax], 54h
mov dword ptr [eax], 541514h
mov dword ptr [eax], 29C53055h
mov dword ptr [eax], 77DBE55Eh
mov dword ptr [eax], 647B726Bh
mov dword ptr [eax], 2CCC28C8h
mov dword ptr [eax], 2F060985h
mov dword ptr [eax], 9C015834h
mov dword ptr [eax], 0BC88B513h
mov dword ptr [eax], 1AB79019h
mov dword ptr [eax], 23457696h
mov dword ptr [eax], 24AE2F4Ch
mov dword ptr [eax], 3629A415h
mov dword ptr [eax], 0F8546197h
mov dword ptr [eax], 7E5B047Ch
mov dword ptr [eax], 1CE21AF8h
mov dword ptr [eax], 369CA37Ah
mov dword ptr [eax], 14063B6Fh
mov dword ptr [eax], 28F7A0BFh
push esi
mov dword ptr [eax], 0B5AF8F68h
call Context::SetConstantBuffer (404750h)
Clearly there's a lot of superfluous writes that should have been optimized away. At first I thought this was a new bug in Visual Studio 2010, so I tried it in Visual Studio 2008 and it did the same thing. It's unclear why this happens, or what triggers this behavior, but I just noticed it happening in a certain location in my program.
So I rewrote the StringHash() constructor in this way, which appears to fix the problem:
StringHash(const char (&str)[4])
{
uint32 hash0 = 0;
uint32 hash1 = hash0 * 65599 + str[0];
uint32 hash2 = hash1 * 65599 + str[1];
m_Hash = hash2 * 65599 + str[2];
}
[
9 comments |
Last comment by Aslan Dzodzikov (2010-05-14 18:43:42) ]