Cmm backend commons up variables with different types from different codeblocks if they share an unique.
Compiling this:
my_test ( W_ x1, W_ x2 ) {
if (x1 == 0) {
bits64 z;
z = x2;
return (z);
} else {
bits32 z;
z = %lobits32(x2);
return (z);
}
}
Gives us this bogus cmm code:
==================== Parsed Cmm ====================
[my_test() { // [R2, R1]
{ info_tbls: []
stack_info: arg_space: 8
}
{offset
c8: _c2::I64 = R2;
_c1::I64 = R1;
if (_c1::I64 == 0) goto c3; else goto c5;
c3: _c6::I32 = _c2::I64;
R1 = %MO_UU_Conv_W32_W64(_c6::I32);
call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
c5: _c6::I32 = %MO_UU_Conv_W64_W32(_c2::I64);
R1 = %MO_UU_Conv_W32_W64(_c6::I32);
call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;
}
}]
Which triggers lint because we end up giving both z
variables the same type:
Cmm lint error:
in basic block c3
in assignment:
_c6::I32 = _c2::I64;
Reg ty: I32
Rhs ty: I64