Repository navigation
Codegen Patterns Od
These observations apply to the noted compiler modes. /Od preserves many source-level choices, so temporary values, argument order, and even empty branches can be visible in the output.
Symptom: Before a call, a value is copied from one register to another (mov ecx,[slot]; mov edx,ecx). Likely source: a call result is passed inline as an argument, instead of first being assigned to a named local.
consume(reader.read());A named local often produces a direct reload for the argument:
int value = reader.read();
consume(value);Symptom: A float argument is spilled, then loaded immediately before the call (movss xmm0,[slot]; movaps xmm1,xmm0). Likely source: the float rvalue was written inline in the call rather than saved in a named local.
object->set(static_cast<float>(compute(other())));Symptom: The executable loads A, compares against B (comiss xmm0,[B]), then branches with jae. Likely source: an expression shaped like B > A may produce that operand order under MSVC 19.16; syntactically similar comparisons can reverse loads and select different conditions.
float result = (b > a) ? b : a;Try source spellings against the actual compiler rather than inferring solely from the branch mnemonic.
Symptom: A 12-byte structure copy uses rep movsb, sometimes with the source pointer still in rax. Likely source: the callee takes a small structure by value; if the copy comes straight from the result register, the call may be nested directly in the argument list.
consume(makePoint());A named temporary changes stack-slot placement and may change the emitted sequence:
auto point = makePoint();
consume(point);Symptom: The code loads an object pointer, moves it through a register, then calls a helper; a base-class view would pass this directly. Likely source: the helper operates on the object's first member, not on the object itself.
struct View { Buffer first; };
helper(&reinterpret_cast<View*>(object)->first);Symptom: A switch dispatch is followed by extra jmp end instructions before the first real case body. Likely source: empty case N: break; labels before the first real case body. In the observed older compiler, the dispatch can omit comparisons for cases targeting the end while retaining their body jumps.
switch (code) {
case 1: break;
case 2: break;
case 3: handle(); break;
}Symptom: Extra copies, argument slots, or cleanup calls appear despite a seemingly simple expression. Likely source: an implicit conversion, a by-value parameter, or a full-expression temporary. Preserve the original expression shape and scope when testing a match; replacing it with a named local can change both copy elision and lifetime.
consume(makeValue()); // Preserve the direct rvalue form when evidence supports it.