[GHC] #10124: Simple case analyses generate too many branches
GHC
ghc-devs at haskell.org
Sat Feb 28 18:13:26 UTC 2015
#10124: Simple case analyses generate too many branches
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.4
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple | Blocked By:
Test Case: | Related Tickets:
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Take the following example,
{{{#!hs
f :: Int -> Bool
f a = case a of
1 -> True
5 -> True
8 -> True
9 -> True
11 -> True
19 -> True
_ -> False
{-# NOINLINE f #-}
main = print $ f 8
}}}
This gets lowered to the following Core (by GHC 7.8),
{{{#!hs
f
f =
\ a_s3EH ->
case a_s3EH of _ { I# ds_s3EJ ->
case ds_s3EJ of _ {
__DEFAULT -> False;
1 -> True;
5 -> True;
8 -> True;
9 -> True;
11 -> True;
19 -> True
}
}
}}}
I have expected GHC to lower this into a nice string of logical
operations, with perhaps a couple of branches at the end to determine the
result.
Unfortunately, this is not what happens. Instead the C-- is a sea of
branches,
{{{
c3F7:
_s3EK::I64 = I64[R1 + 7];
if (%MO_S_Lt_W64(_s3EK::I64, 9)) goto c3Fz; else goto c3FA;
c3Fz:
if (%MO_S_Lt_W64(_s3EK::I64, 5)) goto c3Fq; else goto c3Fr;
c3Fq:
if (_s3EK::I64 != 1) goto c3Ff; else goto c3Fg;
c3Fr:
if (%MO_S_Lt_W64(_s3EK::I64, 8)) goto c3Fn; else goto c3Fo;
c3Fn:
if (_s3EK::I64 != 5) goto c3Ff; else goto c3Fg;
c3Fo:
if (_s3EK::I64 != 8) goto c3Ff; else goto c3Fg;
c3FA:
if (%MO_S_Lt_W64(_s3EK::I64, 11)) goto c3Fw; else goto c3Fx;
c3Fw:
if (_s3EK::I64 != 9) goto c3Ff; else goto c3Fg;
c3Fx:
if (%MO_S_Lt_W64(_s3EK::I64, 19)) goto c3Ft; else goto c3Fu;
c3Ft:
if (_s3EK::I64 != 11) goto c3Ff; else goto c3Fg;
c3Fu:
if (_s3EK::I64 != 19) goto c3Ff; else goto c3Fg;
c3Ff:
R1 = False_closure+1;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
c3Fg:
R1 = True_closure+2;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
...
}}}
Which gets turned into the branchy assembler that you would expect. To my
surprise even the LLVM backend isn't able to bring this back into a
branchless form.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10124>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list