Opened 5 years ago

Closed 4 years ago

#3404 closed bug (fixed)

Strictness analysis bug with Double

Reported by: lpsmith Owned by:
Priority: normal Milestone: 7.0.1
Component: Compiler Version: 6.10.4
Keywords: Cc: michal.terepeta@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

This program will overflow the stack, even when compiled -O to turn on strictness analysis:

main = print (sum [1..1e7] :: Double)

Change History (3)

comment:1 Changed 5 years ago by dons

sum is defined as foldl (+). For some atomic types (Int, Integer) we generate specialized versions, but not for Double currently.

This is an example of the broader syndrome of irregular specializations in the base library. Other tickets:

#2251
#2270
#2271

Notably it is solved by #915 or by doing regular RULES/SPECIALIZE for all atomic numeric types, for base functions on Num a => a ...

Another solution is to use uvector (stream fusion again).

import Data.Array.Vector

main = print (sumU (enumFromToFracU 1 1e7) :: Double)


$wfold :: Double#               -> Double#    -> Double#

$wfold =
  \ (ww_s15b :: Double#) (ww1_s15f :: Double#) ->
    case >## ww1_s15f 1.00000005e7 of wild_aWD {
      False ->
        $wfold
          (+## ww_s15b ww1_s15f) (+## ww1_s15f 1.0);
      True -> ww_s15b

comment:2 Changed 5 years ago by igloo

  • Difficulty set to Unknown
  • Milestone set to 6.14.1

comment:3 Changed 4 years ago by michalt

  • Cc michal.terepeta@… added
  • Resolution set to fixed
  • Status changed from new to closed
  • Type of failure set to None/Unknown

Works fine with both

The Glorious Glasgow Haskell Compilation System, version 6.12.3
The Glorious Glasgow Haskell Compilation System, version 7.1.20101008

And looking at the Core it's clear that the accumulator is strict:

$wsum' :: [Double]
               -> Double#
               -> Double#

$wsum' =
  \ (w_s11u :: [Double]) (ww_s11x :: Double#) ->
    case w_s11u of _ {
      [] -> ww_s11x;
      : x_aoc xs_aod ->
        case x_aoc of _ { D# y_a10A ->
        $wsum' xs_aod (+## ww_s11x y_a10A)
        }
    }
Note: See TracTickets for help on using tickets.