BT reg,reg instructions retain full width index dependencies after partial register writes

bt64_reg:
    mov al, cl
    bt rdx, rax
    setc al
    movzx eax, al
    ret

At MMAT_GENERATED:

; USE: ah.1,rax^2.6,rdx.8,cl.1
; DEF: cf.1,rax.8

mov cl.1, al.1 ; u=cl.1 d=al.1
mov call !_bittest64<fast:"const __int64 *" &(rdx.8)<8/0>.8,"unsigned __int64" rax.8>
    => "unsigned __int8" .1, cf.1 ; u=rax.16,(ALLMEM) d=cf.1

At MMAT_LVARS:

; USE: ah.1,rax^2.6,rdx.8,cl.1,(GLBLOW,GLBHIGH)
; DEF: rax.8

mov cl0.1{1}, rax0.1{1} ; u=cl.1 d=al.1
xdu call !_bittest64<fast:"const __int64 *" &(rdx0.8)<8/0>.8,"unsigned __int64" rax0.8>
    => "unsigned __int8" .1, result.8 ; u=rax.16,(GLBLOW,GLBHIGH) d=rax.8
__int64 __fastcall bt64_reg(char a1, __int64 a2)
{
  unsigned __int64 v2; // rax

  LOBYTE(v2) = a1;
  return _bittest64(&a2, v2);
}

For the register form bt rdx, rax, the bit index is RAX & 63, therefore only the low six bits of AL can affect the result after mov al, cl.

The expected recovery is:

return _bittest64(&a2, (unsigned __int8)a1);
// or 
return (a2 >> ((unsigned __int8)a1 & 63)) & 1;

For comparison, the explicitly zero extended variant (using movzx eax, cl) is recovered to _bittest64(&a2, (unsigned __int8)a1), which makes me think this is just an issue with the simplification for partial registers in this case. Who knows.

I will also note that the BTS/BTR/BTC C translations are UB, but this is more of a complaint about semantics.