How does a compiler know the alignment of a physical address?

Virtual address is not mapped to just any physical address. Virtual memory comes in pages that are mapped in an aligned manner to physical pages. (generally aligned to 4096).

See: Virtual memory and alignment - how do they factor together?


Alignment is a very useful attribute for object code, partly because some machines insist on "aligned access" but in modern computers because cache lines have huge impact on performance and thus cache-alignment of code/loops/data/locks is thus a requirement from your local friendly compiler.

Virtally all the loaders in the world support loading of code at power-of-two aligned boundaries of some modest size and on up. (Assemblers and linkers support this too with various ALIGNMENT directives). Often linkers and loaders just align the first loaded value anyway to a well-known boundary size; OSes with virtual memory often provide a convenient boundary based on VM page size (ties to other answer).

So a compiler can essentially know what the alignment of its emitted code/data is. And by keeping track of how much code it has emitted, it can know what the alignment of any emitted value is. If it needs alignment, it can issue a linker directive, or for modest sizes, simply pad until the emitted amount of code is suitably aligned.

Because of this, you can be pretty sure most compilers will not place code or data constructs in ways that cross cache line (or other architecture imposed) boundaries in a way that materially affects performance unless directed to do so.