
#14754: -O1 changes result at runtime -------------------------------------+------------------------------------- Reporter: Bodigrim | Owner: (none) Type: bug | Status: new Priority: highest | Milestone: 8.4.1 Component: Compiler | Version: 8.4.1-alpha1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): Indeed the problem here is that the CBE logic in the above patch find these two blocks to be equivalent: {{{ c4N2: // global _s4Kg::I64 = _s4Kg::I64; _s4Kf::I64 = _s4Kr::I64; goto c4M3; c4N5: // global _s4Kf::I64 = _s4Kg::I64; _s4Kg::I64 = _s4Kr::I64; goto c4M3; }}} The reason is that the implementation walks the two blocks, zipping together their nodes and building a correspondence between their local registers. In the first node we have {{{ c4N2 c4N5 ---------------- --------------- s4Kg = s4Kg s4Kf = s4Kg }}} As the RHSs of the assignments are identical, this results in the correspondence `s4Kg(c4N2) ~> s4Kf(s4N5)`. We then consider the second pair of nodes: {{{ c4N2 c4N5 ---------------- --------------- s4Kf = s4Kr s4Kg = s4Kr }}} Since the implementation binding occurrences are simply added to the register substitution instead of compared, these two nodes are considered to be equivalent. This is clearly wrong. I'll need to revisit this in the future but in the meantime I'm going to revert. implementation fails to take into account that logic registers may live beyond the -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14754#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler