Skip to content

Cmm lint error in GHC.Bits when compiled without optimisation

Repro, add the OPTIONS_GHC pragma to the top of GHC.Bits

{-# OPTIONS_GHC -O0 -}
./hadrian/build --flavour=validate -o_validate  -j4 _validate/stage1/libraries/base/build/GHC/Bits.o 

Gives the following Cmm lint error:

Cmm lint error:
  in basic block c2E2
    Shift operation MO_U_Shr W64 has out-of-range offset 64. This will result in undefined behavior
Program was:
  {offset
    c2CU: // global
        _s1YF::P64 = R3;   // CmmAssign
        _s1YE::P64 = R2;   // CmmAssign
        if ((old + 0) - <highSp> < SpLim) (likely: False) goto c2CY; else goto c2CZ;   // CmmCondBranch
    c2CY: // global
        R3 = _s1YF::P64;   // CmmAssign
        R2 = _s1YE::P64;   // CmmAssign
        R1 = $crotate2_r1Hc_closure;   // CmmAssign
        call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8;   // CmmCall
    c2CZ: // global
        I64[(young<c2CR> + 8)] = c2CR;   // CmmStore
        R1 = _s1YE::P64;   // CmmAssign
        if (R1 & 7 != 0) goto c2CR; else goto c2CS;   // CmmCondBranch
    c2CS: // global
        call (I64[R1])(R1) returns to c2CR, args: 8, res: 8, upd: 8;   // CmmCall
    c2CR: // global
        _s1YG::P64 = R1;   // CmmAssign
        _s1YH::I64 = I64[_s1YG::P64 + 7];   // CmmAssign
        I64[(young<c2CX> + 8)] = c2CX;   // CmmStore
        R1 = _s1YF::P64;   // CmmAssign
        if (R1 & 7 != 0) goto c2CX; else goto c2D1;   // CmmCondBranch
    c2D1: // global
        call (I64[R1])(R1) returns to c2CX, args: 8, res: 8, upd: 8;   // CmmCall
    c2CX: // global
        _s1YI::P64 = R1;   // CmmAssign
        _s1YJ::I64 = I64[_s1YI::P64 + 7];   // CmmAssign
        _c2D6::I64 = _s1YJ::I64 & 63;   // CmmAssign
        _s1YK::I64 = _c2D6::I64;   // CmmAssign
        switch [-9223372036854775808 .. 9223372036854775807] _s1YK::I64 {
            case 0 : goto c2DK;
            default: {goto c2Db;}
        }   // CmmSwitch
    c2DK: // global
        // slowCall
        I64[(young<c2DO> + 8)] = c2DO;   // CmmStore
        R2 = 1;   // CmmAssign
        R1 = isTrue#_closure;   // CmmAssign
        call stg_ap_n_fast(R2,
                           R1) returns to c2DO, args: 8, res: 8, upd: 8;   // CmmCall
    c2DO: // global
        _s1YQ::P64 = R1;   // CmmAssign
        // slow_call for isTrue#_closure with pat stg_ap_n
        _c2Ec::P64 = _s1YQ::P64 & 7;   // CmmAssign
        switch [1 .. 2] _c2Ec::P64 {
            case 1 : goto c2E0;
            case 2 : goto c2E7;
        }   // CmmSwitch
    c2E7: // global
        Hp = Hp + 16;   // CmmAssign
        if (Hp > HpLim) (likely: False) goto c2Ea; else goto c2E9;   // CmmCondBranch
    c2Ea: // global
        HpAlloc = 16;   // CmmAssign
        R1 = _s1YQ::P64;   // CmmAssign
        call stg_gc_unpt_r1(R1) returns to c2DO, args: 8, res: 8, upd: 8;   // CmmCall
    c2E9: // global
        // allocHeapClosure
        I64[Hp - 8] = W#_con_info;   // CmmStore
        I64[Hp] = _s1YH::I64;   // CmmStore
        _c2E6::P64 = Hp - 7;   // CmmAssign
        R1 = _c2E6::P64;   // CmmAssign
        call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;   // CmmCall
    c2E0: // global
        Hp = Hp + 16;   // CmmAssign
        if (Hp > HpLim) (likely: False) goto c2E3; else goto c2E2;   // CmmCondBranch
    c2E3: // global
        HpAlloc = 16;   // CmmAssign
        R1 = _s1YQ::P64;   // CmmAssign
        call stg_gc_unpt_r1(R1) returns to c2DO, args: 8, res: 8, upd: 8;   // CmmCall
    c2E2: // global
        _c2DS::I64 = _s1YH::I64 >> 64;   // CmmAssign
        _s1YR::I64 = _c2DS::I64;   // CmmAssign
        _c2DV::I64 = _s1YH::I64 | _s1YR::I64;   // CmmAssign
        _s1YS::I64 = _c2DV::I64;   // CmmAssign
        // allocHeapClosure
        I64[Hp - 8] = W#_con_info;   // CmmStore
        I64[Hp] = _s1YS::I64;   // CmmStore
        _c2DY::P64 = Hp - 7;   // CmmAssign
        R1 = _c2DY::P64;   // CmmAssign
        call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;   // CmmCall
    c2Db: // global
        // slowCall
        I64[(young<c2Df> + 8)] = c2Df;   // CmmStore
        R2 = 0;   // CmmAssign
        R1 = isTrue#_closure;   // CmmAssign
        call stg_ap_n_fast(R2,
                           R1) returns to c2Df, args: 8, res: 8, upd: 8;   // CmmCall
    c2Df: // global
        _s1YL::P64 = R1;   // CmmAssign
        // slow_call for isTrue#_closure with pat stg_ap_n
        _c2Eb::P64 = _s1YL::P64 & 7;   // CmmAssign
        switch [1 .. 2] _c2Eb::P64 {
            case 1 : goto c2Dx;
            case 2 : goto c2DE;
        }   // CmmSwitch
    c2DE: // global
        Hp = Hp + 16;   // CmmAssign
        if (Hp > HpLim) (likely: False) goto c2DH; else goto c2DG;   // CmmCondBranch
    c2DH: // global
        HpAlloc = 16;   // CmmAssign
        R1 = _s1YL::P64;   // CmmAssign
        call stg_gc_unpt_r1(R1) returns to c2Df, args: 8, res: 8, upd: 8;   // CmmCall
    c2DG: // global
        // allocHeapClosure
        I64[Hp - 8] = W#_con_info;   // CmmStore
        I64[Hp] = _s1YH::I64;   // CmmStore
        _c2DD::P64 = Hp - 7;   // CmmAssign
        R1 = _c2DD::P64;   // CmmAssign
        call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;   // CmmCall
    c2Dx: // global
        Hp = Hp + 16;   // CmmAssign
        if (Hp > HpLim) (likely: False) goto c2DA; else goto c2Dz;   // CmmCondBranch
    c2DA: // global




























        HpAlloc = 16;   // CmmAssign
        R1 = _s1YL::P64;   // CmmAssign
        call stg_gc_unpt_r1(R1) returns to c2Df, args: 8, res: 8, upd: 8;   // CmmCall
    c2Dz: // global
        _c2Dj::I64 = 64 - _s1YK::I64;   // CmmAssign
        _s1YN::I64 = _c2Dj::I64;   // CmmAssign
        _c2Dm::I64 = _s1YH::I64 >> _s1YN::I64;   // CmmAssign
        _s1YO::I64 = _c2Dm::I64;   // CmmAssign
        _c2Dp::I64 = _s1YH::I64 << _s1YK::I64;   // CmmAssign
        _s1YM::I64 = _c2Dp::I64;   // CmmAssign
        _c2Ds::I64 = _s1YM::I64 | _s1YO::I64;   // CmmAssign
        _s1YP::I64 = _c2Ds::I64;   // CmmAssign
        // allocHeapClosure
        I64[Hp - 8] = W#_con_info;   // CmmStore
        I64[Hp] = _s1YP::I64;   // CmmStore
        _c2Dv::P64 = Hp - 7;   // CmmAssign
        R1 = _c2Dv::P64;   // CmmAssign
        call (P64[(old + 8)])(R1) args: 8, res: 0, upd: 8;   // CmmCall
  }

<no location info>: error: 
Compilation had errors


Command failed
Build failed.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information