Okay. I don't think we regularly test the compiler for 32-bit hosts, so you may find places you need to tweak the code to get that to work. In this case I think it'd be fine to change the static assert to say sizeof(SymbolicValue) <= 2 * sizeof(uint32_t) + sizeof(void *), …) (and we would accept a PR to that effect).
That <= was deliberate, although I'm a little surprised that that's not the final size of the type. It seems to me like alignment would force it into that.
swiftc compiles with -fno-rtti, so only classes with virtual methods will have the extra pointer. (Unless you're somehow not getting an -fno-rtti build?)
In general I suspect you'll get a bunch of these static assertions, and maybe some runtime ones as well. For the alignment cases, feel free to use alignas where necessary to provide the alignment that's expected. For the static assertions, figure out what the equivalent rule would be in a 32-bit world. (For example, I think it's worth figuring out what the size of SymbolicValue actually is and why.)
Why does the pointer pair type have to be 16-byte aligned in the first place? That seems like a minuscule optimization, if that's what it's for.
Also, if Swift isn't really intended for 32-bit systems, can it really be said to be a cross platform language? 32-bit systems will be around for years.
The compiler implementation overaligns certain types (even in 64-bit mode) in order to store flags in the same word as a pointer. Is it an important optimization? Sometimes yes, sometimes we're probably being overzealous. It is a balance against wasting alignment padding, and we haven't measured that specifically, and particularly not for a 32-bit host.