T20137 might be depending on C undefined behavior on 32-bit platforms
Consider the following C file reduced from test case T20137:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void foo(void *p) {
printf("%" PRIx64 "\n", (uint64_t) p);
}
int main(void) {
foo(0x88888888);
}
On wasm32, it outputs 88888888, which looks like a sensible answer: the 32-bit unsigned pointer p is casted to a 64-bit unsigned integer, therefore it should be a zero-extension. And it's the same result on i386 if compiled by clang. However, on i386, if compiled by gcc, the runtime result is ...ffffffff88888888!
It's obvious that gcc emits assembly that performs a signed extension when casting void* to uint64_t. Consider:
unsigned long long foo(void *p) { return p; }
gcc emits:
foo:
mov eax, DWORD PTR [esp+4]
cdq
ret
clang emits:
foo: # @foo
mov eax, dword ptr [esp + 4]
xor edx, edx
ret
Is it a bug in gcc? Or are we encountering some form of C undefined behavior here? I'm leaning towards the latter. Anyway, the 32-bit version of expected stdout of T20137 is dependent on the ill-defined behavior of sign-extending void* to uint64_t. Unless there are objections, I'll correct the expected stdout and mark this test as fragile on i386.