Given the following minimal example:
repro:
xor ecx, ecx
mov rax, 1122334455667788h
mov rdx, 0BEEFh
cmovo eax, edx
ret
Since xor ecx, ecx clears OF, the conditional move is not taken.
At MMAT_GENERATED, the CMOVO is lowered into:
lnot of.1, tt.1 ; u=of.1 d=tt.1
jcnd tt.1, $locret_16 ; u=tt.1
With the following operations only on the conditionally executed path:
mov edx.4, eax.4 ; u=edx.4 d=eax.4
xdu eax.4, rax.8 ; u=eax.4 d=rax^4.4
At MMAT_LVARS:
mov #0x1122334455667788.8, rax.8 ; u= d=rax.8
Resulting in:
return 0x1122334455667788LL;
However, in 64-bit mode, a 32-bit CMOVcc clears bits 63:32 of the destination register even when the condition is false.
The expected result is:
return 0x55667788;
The xdu operation is currently placed only on the path where the move occurs. The upper 32 bits should also be cleared when the condition is false, while preserving the original low 32 bits.