Cmm sinking does not eliminate dead code in loops
Cmm code shown in #8326 is suboptimal. For this Haskell code:
isTrue# :: Int# -> Bool
isTrue# 1# = True
isTrue# _ = False
f :: Int# -> Int
f x | isTrue# (x ># 0#) = I# x
| otherwise = -(I# x)
we get Cmm that contains dead code in a loop:
cFg: // False branch
Hp = Hp + 16;
if (Hp > HpLim) goto cFy; else goto cFx;
cFy: // not enough heap, call GC
HpAlloc = 16;
I64[Sp - 16] = cFf;
R1 = _sEV::I64;
I64[Sp - 8] = _sEU::I64;
Sp = Sp - 16;
call stg_gc_unbx_r1(R1) returns to cFf, args: 8, res: 8, upd: 8;
cFf: // re-do the False branch
_sEU::I64 = I64[Sp + 8];
Sp = Sp + 16;
_sEV::I64 = R1;
goto cFg;
cFx: // RHS of False branch
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = -_sEU::I64;
R1 = Hp - 7;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
Notice that _sEV is dead - we should optimize it away. This is a known deficiency in the Cmm sinking pass (i.e. it does not work for loops). I'm putting this on Trac so we have this documented.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.7 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |