Skip to content

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.

Edited by Andreas Klebinger
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information