#5658: Strict bindings are wrongly floated out of case alternatives.
---------------------------------+------------------------------------------
    Reporter:  benl              |       Owner:               
        Type:  bug               |      Status:  new          
    Priority:  normal            |   Component:  Compiler     
     Version:  7.2.1             |    Keywords:               
    Testcase:                    |   Blockedby:               
          Os:  Unknown/Multiple  |    Blocking:               
Architecture:  Unknown/Multiple  |     Failure:  Runtime crash
---------------------------------+------------------------------------------
 With this program:
 {{{
 {-# LANGUAGE MagicHash, BangPatterns #-}
 module Broken where
 import qualified Data.Vector            as V
 import qualified Data.Vector.Unboxed    as U

 broken :: V.Vector (U.Vector Double) -> Int -> Int -> IO Double
 broken !arrs !ix !len
  = case ix >= len of
          True   -> error "sorry"
          False  -> return ((arrs `V.unsafeIndex` ix) `U.unsafeIndex` ix)
 }}}

 Note that both indexing operations are within the 'False' branch, and the
 test is intended to check that the indexing is indeed safe.

 Sadly, the simplifier floats the inner indexing operation outside the
 bounds check:

 {{{
 broken1
 broken1 =
   \ arrs_s185 ix_s18a len_s18j eta_s18o ->
     let { Vector ipv_s18e _ ipv2_s18d ~ _ <- arrs_s185 } in
     let { I# ipv3_s18f ~ _     <- ix_s18a } in
     let { __DEFAULT ~ sat_s18D <- +# ipv_s18e ipv3_s18f } in
     let { (# x_s18p #) ~ _     <- indexArray# ipv2_s18d sat_s18D } in
 *** NO! ***
     let { I# ipv4_s18m ~ _     <- len_s18j } in
     case >=# ipv3_s18f ipv4_s18m of _ {
       False ->
         let {
           sat_s18G
           sat_s18G =
             let { Vector rb_s18v _ rb2_s18u ~ _ <- x_s18p `cast` ... } in
             let { __DEFAULT ~ sat_s18J <- +# rb_s18v ipv3_s18f } in
             let { __DEFAULT ~ sat_s18K
             <- indexDoubleArray# rb2_s18u sat_s18J
             } in
             D# sat_s18K } in
         (# eta_s18o, sat_s18G #);
       True -> broken2 `cast` ...
     }
 }}}

 If it was a lazy binding it would have been ok to float it, but it's not.
 This issue is probably causing other problems in GHC, maybe #5085. This is
 broken in the head as well as 7.2.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5658>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to