Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#10288 closed bug (fixed)

-flate-dmd-anal triggers "Entered absent arg"

Reported by: yongqli Owned by: simonpj
Priority: highest Milestone: 7.10.2
Component: Compiler Version: 7.10.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime crash Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

If I compile my program with -flate-dmd-anal, it crashes at run-time with Oops! Entered absent arg w_sJ66e M V1 Double

Change History (13)

comment:1 Changed 3 years ago by rwbarton

Status: newinfoneeded

Could you attach your program (preferably after minimizing it as much as possible)?

comment:2 Changed 3 years ago by simonpj

Yes indeed! You should never get "Entered absent arg", so there's an outright bug there. But we can't fix it unless we can reproduce it.

Simon

comment:3 Changed 3 years ago by yongqli

See Main.hs here: https://gist.github.com/yongqli/5dc94aeaeda2e24c6637

You need the following packages: linear, lens, vector, vector-th-unbox, strict

Running with ghc Main.hs -O2 -flate-dmd-anal -fforce-recomp; ./Main will give

Main: Oops! Entered absent arg w_sGY6 MVN V1 Double

It takes about 3 days's worth of work to produce a test case like this. Is there a better option than deleting a piece of code and then recompiling? I essentially have to "unwrite" my whole program. Is there a fuzzer-like tool that could conceivably be used?

comment:4 Changed 3 years ago by simonpj

Good news. I think this is fixed. At least I can't reproduce your crash with HEAD.

I think that one of these two fixes has solved it:

Both are merged to the 7.10 branch and so will appear in 7.10.2.

It would be good if you were able to test that the 7.10 branch is indeed fixed in your case. I will try to do the same.

Simon

PS: for "entered absent arg w_sJ66e" bugs, compile with "-ddump-simpl" and grep for that string. That will show exactly which thunk in which function is being entered, and might save time compared to delete/recompile.

comment:5 Changed 3 years ago by simonpj

Oh VERY interesting! I have reproduced the problem with 7.10, and it is YET ANOTHER bug in the demand analyser. Here is the offending code

dmdAnal' sigs dmd (App fun (Coercion co))
  = (fun_ty, App fun' (Coercion co))
  where
    (fun_ty, fun') = dmdAnal sigs dmd fun

The incoming demand dmd is not modified before passing it on to fun.

But that is wrong wrong wrong. That gets the demands from the function out of step, so the wrong demand goes to the wrong argument. It's a miracle that this has not been causing chaos for ages. Horror. Coercions are value arguments and so they must be treated as such.

I think the solution is simply to delete these lines so that coercion arguments are handled uniformly; but I want to tread carefully.

Thank you for extracting this example. More anon.

comment:6 Changed 3 years ago by thoughtpolice

Milestone: 7.10.2

comment:7 Changed 3 years ago by thoughtpolice

Status: infoneedednew

comment:8 Changed 3 years ago by thoughtpolice

Owner: set to simonpj

comment:9 Changed 3 years ago by Simon Peyton Jones <simonpj@…>

In d5773a4939b1feea51ec0db6624c9462751e948a/ghc:

Teach DmdAnal that coercions are value arguments!

The demand analyser was treating coercion args like type args,
which meant that the arguments in a strictness signature got
out of step with the arguments of a call.  Result chaos and
disaster.  Trac #10288 showed it up.

It's hard to get this bug to show up in practice because
 - functions abstracted over coercions are usually abstracted
   over *boxed* coercions
 - we don't currently unbox a boxed-coercion arg because it's
   GADT (I see how to fix this too)

But after floating, optimisation, and so on, Trac #10288 did
get a function abstracted over an unboxed coercion, and then
the -flate-dmd-anal pass went wrong.

I don't think I can come up with a test case, but I don't think
it matters too much.

Still to come
 - Fix a second bug, namely that coercion variables are wrongly
   marked as absent because DmdAnal doesn't check the the free
   variables of casts. I think this never bites in practice
   (see the follow-up commit)

 - Make GADT products work with strictness analysis

comment:10 Changed 3 years ago by Simon Peyton Jones <simonpj@…>

In 5c7e4db5ce84395eb0d727eb3b0f505a00191164/ghc:

Wibble to DmdAnal

This fixes a typo in d5773a4939b1feea51ec0db6624c9462751e948a
    Teach DmdAnal that coercions are value arguments!
    (Trac #10288)

Sorry about that; I'm not sure how it slipped through.

comment:11 Changed 3 years ago by simonpj

Priority: normalhighest
Status: newmerge

yongqli, your test case nailed it -- thank you! It was so helpful to be able to reproduce it, and it's not an easy case to make happen, so I might well have failed to find it, or assumed it was already fixed, without your help.

Austin: please merge the above two to 7.10.

I'm not adding a regression test because it's hard to provoke; and the fix (which consisted only of deleting code) is pretty robust.

Simon

comment:12 Changed 3 years ago by thoughtpolice

Resolution: fixed
Status: mergeclosed

Merged to ghc-7.10 (via 354f5063bac6a91d06f5e37777d594b3140dc668).

comment:13 Changed 3 years ago by bgamari

Note that the commit to the ghc-7.10 branch has a typo. I've opened Phab:D881 to fix this.

Note: See TracTickets for help on using tickets.