Calling tagToEnum#, and then branching on the result produces bad code.
It results in Cmm like this:
unwind Sp = Just Sp;
//The "call" to tagToEnum#
_s3S8::P64 = I64[(_s3S5::I64 << 3) + Main.ItemType_closure_tbl];
//The usual "check if evaluated - if not evaluate prolog
//where we spill all the live variables.
I64[Sp - 184] = c5Qc;
R1 = _s3S8::P64;
P64[Sp - 176] = P64[_s3S4::P64 + 63];
P64[Sp - 168] = P64[_s3S4::P64 + 47];
P64[Sp - 160] = P64[_s3S4::P64 + 71];
P64[Sp - 152] = P64[_s3S4::P64 + 7];
P64[Sp - 144] = P64[_s3S4::P64 + 39];
P64[Sp - 136] = P64[_s3S4::P64 + 23];
P64[Sp - 128] = P64[_s3S4::P64 + 31];
I64[Sp - 120] = I64[_s3S4::P64 + 151];
I64[Sp - 112] = I64[_s3S4::P64 + 143];
P64[Sp - 104] = P64[_s3S4::P64 + 15];
P64[Sp - 96] = P64[_s3S4::P64 + 79];
P64[Sp - 88] = P64[_s3S4::P64 + 135];
P64[Sp - 80] = P64[_s3S4::P64 + 127];
P64[Sp - 72] = P64[_s3S4::P64 + 119];
P64[Sp - 64] = P64[_s3S4::P64 + 55];
P64[Sp - 56] = P64[_s3S4::P64 + 111];
P64[Sp - 48] = P64[_s3S4::P64 + 103];
P64[Sp - 40] = P64[_s3S4::P64 + 87];
P64[Sp - 32] = P64[_s3S4::P64 + 95];
P64[Sp - 24] = _s3S4::P64;
I64[Sp - 16] = _s3S5::I64;
P64[Sp - 8] = _s3S8::P64;
Sp = Sp - 184;
unwind Sp = Just Sp + 184;
//Check tag
if (R1 & 7 != 0) goto c5Qc; else goto c5Uv;
c5Uv:
unwind Sp = Just Sp + 184;
//Enter closure if untaged
call (I64[R1])(R1) returns to c5Qc, args: 8, res: 8, upd: 8;
c5Qc:
//Having ensured the closure is tagged we can finally branch on the result.
unwind Sp = Just Sp + 184;
_c5Va::P64 = R1 & 7;
if (_c5Va::P64 < 3) goto u5Ve; else goto u5Vf;
I noticed this while working on tag inference. Maybe we could be altogether smarter here. After all tagToEnum# will always produce a tagged value.
#16970 (closed) is one way how we could avoid this.