Determining if argument register retains original value

I discovered an interesting bug with the -fzero-call-used-regs feature. It appears that sometimes an argument register (e.g. %rdi) might not be callee-saved before the call, because the called function has the same argument in the same order, and presumably doesn’t modify that register (or restores it before exiting). So something like this:

void foo(struct bar *b) {
    qux(b);
}

void qux(struct bar *b) {
}

Is there a way to determine whether the ending value of a live-in register is equal to the exit value? I.e. that the %rdi register has the value of the first argument, %rsi the second argument, etc. upon return?

You can tell if a call MachineInstr uses a register based on the operands; for example, in this case there would be an “implicit $rdi” operand.

Argument registers on x86 are generally caller-save (i.e. not preserved by a call).

Yeah, after more thought I came up with a hypothesis of what might be going on. A caller-saved reg would be, well, saved if it were to be overwritten. However, since these are “static” functions, Clang seems to violate that because either the value in %rdi will be restored before returning or the value in %rdi isn’t live afterward returning. If this is true, then the problematic code needs to make sure this situation isn’t happening before zeroing out caller-saved registers.