Writing down binary data... with padding bytes

No, loop unrolling is fine for the reasons you described. What I'm talking about is optimizations that replace a (sequence of) side effects with another sequence that would be equivalent but isn't is poison is implicitly frozen for each individual side effect. I actually realized now there's even existing syscalls that semi-realistically might exhibit this: vectored I/O or gather/scatter I/O.

For example, this Linux program snippet (which surely has mistakes since I haven't tried it):

struct iovec bufs[2] = { {&c, 1}, {&c, 1} };
writev(STDOUT_FILENO, bufs, 2);

... makes a single system call to write the same character (from the same memory location, even) twice. It seems valid for a compiler might replace that with:

char buf[2] = { c, c };
write(STDOUT_FILENO, buf, 2);

which is really all-around better: it makes the same number of syscalls, uses a simpler and presumably faster syscall, and even consumes less stack space. But if the semantics of syscalls are to freeze memory, then this can e.g. output ab (because there's two bytes being frozen) while the first version can only output aa, bb, etc.

I don't claim this is an optimization that any compiler actually implements, but it seems like a reasonable optimization to me (at least, no less reasonable than other optimizations of standardized I/O functions) and I believe it is only correct if side effects depending on poison are UB.

2 Likes