
#12915: cmmImplementSwitchPlans creates duplicate blocks -------------------------------------+------------------------------------- Reporter: alexbiehl | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Given this c-- code *after* common block elimination and *before* cmmImplementSwitchPlans: {{{#!hs ... cfzc: _sfh3::P64 = R1; _cfB7::I64 = %MO_UU_Conv_W32_W64(I32[I64[_sfh3::P64 - 1] - 4]); switch [0 .. 20] _cfB7::I64 { case 2 : goto cfAR; case 4 : goto cfAV; case 6 : goto cfAZ; default: goto cfAC; } cfAZ: _sfh6::I64 = I64[_sfh3::P64 + 7]; _sfgp::I64 = 1; goto sfgo; cfAV: _sfh5::I64 = I64[_sfh3::P64 + 7]; _sfgp::I64 = 1; goto sfgo; cfAR: _sfh4::I64 = I64[_sfh3::P64 + 7]; _sfgp::I64 = 1; goto sfgo; sfgo: ... }}} Everything is fine, the blocks cfAZ, cfAV and cfAR are all a little different. But after cmmImplementSwitchPlans the code becomes: {{{#!hs ... cfzc: _sfgl::I64 = I64[Sp + 24]; _sfgn::P64 = P64[Sp + 16]; _cfB7::I64 = %MO_UU_Conv_W32_W64(I32[I64[R1 - 1] - 4]); if (_cfB7::I64 < 5) goto ufBe; else goto ufBg; ufBe: if (_cfB7::I64 < 4) goto ufBf; else goto cfAV; ufBf: if (_cfB7::I64 != 2) goto cfAC; else goto cfAR; cfAR: _sfgp::I64 = 1; goto sfgo; cfAV: _sfgp::I64 = 1; goto sfgo; ufBg: if (_cfB7::I64 != 6) goto cfAC; else goto cfAZ; cfAZ: _sfgp::I64 = 1; goto sfgo; sfgo: ... }}} We can now see that cfAZ, cfAV and cfAR are code duplicates! Now, https://github.com/ghc/ghc/blob/master/compiler/cmm/CmmPipeline.hs#L72 states {{{ ... ----------- Eliminate common blocks ------------------------------------- g <- {-# SCC "elimCommonBlocks" #-} condPass Opt_CmmElimCommonBlocks elimCommonBlocks g Opt_D_dump_cmm_cbe "Post common block elimination" -- Any work storing block Labels must be performed _after_ -- elimCommonBlocks g <- {-# SCC "createSwitchPlans" #-} runUniqSM $ cmmImplementSwitchPlans dflags g dump Opt_D_dump_cmm_switch "Post switch plan" g ... }}} For some reason I don't understand cmmImplementSwitchPlans is run *after* elimCommonBlocks. Although it seems elimCommonBlocks can deal with the constructs introduced in cmmImplementSwitchPlans. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12915 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler