Fixing #11444 - OK-for-speculation check rejects valid program?
Ömer Sinan Ağacan
omeragacan at gmail.com
Tue Jan 19 15:00:53 UTC 2016
I found one of the problems with #11444, but I don't know how to fix it. The
problem is that the desugarer is generating this function:
ptrEq [InlPrag=NOINLINE] :: forall a_a1wc. a_a1wc -> a_a1wc -> Bool
[LclIdX, Str=DmdType]
ptrEq =
\ (@ a_a1Ts) (x_a1we :: a_a1Ts) (y_a1wf :: a_a1Ts) ->
case x_a1we of x_X1wq { __DEFAULT ->
case y_a1wf of y_X1ws { __DEFAULT ->
==
@ Int
GHC.Classes.$fEqInt
(case reallyUnsafePtrEquality# @ a_a1Ts x_X1wq y_X1ws
of wild_00 { __DEFAULT ->
GHC.Types.I# wild_00
})
(GHC.Types.I# 1#)
}
}
Which is lint-safe. Then, the optimizer is transforming this into:
ptrEq [InlPrag=NOINLINE] :: forall a_a1wc. a_a1wc -> a_a1wc -> Bool
[LclIdX,
Arity=2,
Str=DmdType,
Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 71 0}]
ptrEq =
\ (@ a_a1Ts) (x_a1we :: a_a1Ts) (y_a1wf :: a_a1Ts) ->
case x_a1we of x_X1wq { __DEFAULT ->
case y_a1wf of y_X1ws { __DEFAULT ->
eqInt
(I# (reallyUnsafePtrEquality# @ a_a1Ts x_X1wq y_X1ws)) (I# 1#)
}
}
The problem with this, according to the linter, is the argument of I# is not
OK-for-speculation (the expression `reallyUnsafePtrEquality# @ a_a1Ts x_X1wq
y_X1ws`). The reason is because arguments of `reallyUnsafePtrEquality#` are not
OK-for-speculation, because their types are polymorphic, and variables with
polymorphic types are not OK for speculation.
However, I think this expression should be OK-for-speculation, because it can't
fail, the primop is not out-of-line etc. I think all the requirements for being
OK for speculation hold here.
So my questions are:
- Does that look like a correct optimization transformation? (it looked OK to
me, but wanted to make sure)
- Am I right that this expression should be OK for speculation?
- What's a good way to make this code lint-safe?
Thanks..
More information about the ghc-devs
mailing list