type inferencing failure on (* float t) SBCL 2.0.9

Bug #1914094 reported by Andrew Berkley
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Undecided
Unassigned

Bug Description

(declaim (ftype (function (fixnum) (values fixnum)) blarg))

(defun blarg (n)
  (declare (type fixnum n))
  n)

(defun does-not-warn-on-compilation (x)
  (blarg (* 3f0 x)))

(defun does-warn-on-compilation (x)
  (declare (type fixnum x))
  (blarg (* 3f0 x)))

The result of the multiply should be (or float (complex float)) which does not intersect fixnum. Instead we get type number (I think) because we end up with generic numeric-contagion?

Revision history for this message
Andrew Berkley (ajberkley) wrote :

While fixing this I found what looks like a bug in https://github.com/sbcl/sbcl/commit/eb3307177a80c124f233d21ca9087fea63c39019#diff-716727851812af3d6d0a0b227549af70c133e6080bd085d52fa939a25f5b4515

at line 373 of early-type.lisp, (specifier-type 'real) should be (specifier-type 'float)

Revision history for this message
Andrew Berkley (ajberkley) wrote :

Here is a proposed solution https://github.com/ajberkley/sbcl/commit/5464c1729b49c06708e91b21abc2452fe60cdddf

It includes the fix to the problem I listed above.

I don't understand the reason I need the type-union in numeric-contagion as :complexp nil should be an OK specification for a numeric-type, but it messes up some type derivation while compiling the examples above.

I will look further into it.

Revision history for this message
Andrew Berkley (ajberkley) wrote :
Revision history for this message
Andrew Berkley (ajberkley) wrote :

Sorry for the spam. I removed some of the code indentation changes

https://github.com/ajberkley/sbcl/commit/59b88de767e07b5bb870a6d3ee42b198edc4b996

Revision history for this message
Stas Boukarev (stassats) wrote :

(let ((x 813.0d0))
    (values
     (decf x)
     x))

fails to compile after this.

Revision history for this message
Stas Boukarev (stassats) wrote :

And (lambda (x y) (atan x y))

Revision history for this message
Andrew Berkley (ajberkley) wrote :

I'll look into it!

Revision history for this message
Andrew Berkley (ajberkley) wrote :

The atan case looks fixable, though ugly. There are several other cases where numeric-contagion is assumed to return a numeric-type, not a union type, though it explicitly says it can return a union type. I need to understand how and why the code chooses to represent types in certain ways to make progress which will take some time.

I added a patch to handle the decf case here https://github.com/ajberkley/sbcl/commit/2bec2009920685254aad0af1bc36551ac6399839

It is triggered also with the simpler:

(let ((x 813.0d0))
   (decf x))

The problem was maybe-infer-iteration-var-type which assumes that numeric-contagion always returns a numeric-type and not a union of numeric types. Similar to the atan case. If the comment on numeric-contagion is correct, then fixing this is good. I will need to think through whether we would want to do better than just failing in this case (assuming that in a later pass of the constraint phase the types will be tighter and we will succeed?).

Revision history for this message
Andrew Berkley (ajberkley) wrote :

And similarly a patch to handle atan (and others): https://github.com/ajberkley/sbcl/commit/67e675483898636773cd2c512cf28d5064361a07

I'm not particularly happy with my knowledge of the whole type / type derivation system here and what promises may or may not be broken. But, since stassats patch to return a union-type on :complexp nil is in the main branch probably best to get these in.

Revision history for this message
Andrew Berkley (ajberkley) wrote :
Revision history for this message
Stas Boukarev (stassats) wrote :

Can you format it into a single patch?

Revision history for this message
Andrew Berkley (ajberkley) wrote :

Done, and made a pull request to github.com/sbcl/sbcl

Revision history for this message
Stas Boukarev (stassats) wrote :

SBCL isn't developed through github, so pull requests don't do much.

Revision history for this message
Andrew Berkley (ajberkley) wrote :
Stas Boukarev (stassats)
Changed in sbcl:
status: New → Fix Committed
Revision history for this message
Andrew Berkley (ajberkley) wrote :

Attaching a minor one line tightening fix to this change.

Revision history for this message
Stas Boukarev (stassats) wrote :

Do you have a test case for it?

Revision history for this message
Andrew Berkley (ajberkley) wrote :

I can't find one--- it may be that it never occurs. It's just a consistency change to make sure the code does the same thing for union types as it would for non-union types.

Revision history for this message
Stas Boukarev (stassats) wrote :

Ok.

Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.