This is an archive of the discontinued LLVM Phabricator instance.

[ValueTracking] Allow select patterns to work on FP vectors
ClosedPublic

Authored by tlively on Sep 20 2018, 2:25 PM.

Details

Summary

This CL allows constant vectors of floats to be recognized as non-NaN
and non-zero in select patterns. This change makes
matchSelectPattern more powerful generally, but was motivated
specifically because I wanted fminnan and fmaxnan to be created for
vector versions of the scalar patterns they are created for.

Tested with check-all on all targets. A testcase in the WebAssembly
backend that tests the non-nan codepath is in an upcoming CL.

Diff Detail

Repository
rL LLVM

Event Timeline

tlively created this revision.Sep 20 2018, 2:25 PM

I'm somewhat sure this kind of change needs it's own tests, outside of $backend.

lebedev.ri retitled this revision from Allow select patterns to work on vectors in more places to [ValueTracking] Allow select patterns to work on vectors in more places.Sep 20 2018, 2:42 PM

I'm somewhat sure this kind of change needs it's own tests, outside of $backend.

I agree, but I couldn't figure out a way to test the non-NaN case in the style of the other ValueTracking tests. The backend has the advantage of being able to observe the ISel DAG in tests, but the ValueTracking tests cannot do so. I'm not aware of any instruction simplifications that depend on the isKnownNonNaN. That's not to say they don't exist, but I haven't been able to find one so far.

You can always write an unit-test, too.

tlively updated this revision to Diff 166564.Sep 21 2018, 2:55 PM
  • Add a unit test for recognizing fmin on vectors. It fails if either isKnownNonNaN or isKnownNonZero does not work for vectors.
  1. What happens when only some of the elements in a vector are NaN?
  2. What happens we have -0.0 in a vector?
tlively updated this revision to Diff 166780.Sep 24 2018, 4:06 PM
  • Add tests checking that isKnownNonNaN and isKnownNonZero also return false correctly.
tlively planned changes to this revision.Sep 24 2018, 4:15 PM

Needs fixes.

tlively updated this revision to Diff 166784.Sep 24 2018, 4:40 PM
  • Test cases where functions should return false
  • Fix functions
aheejin added inline comments.Sep 24 2018, 6:08 PM
lib/Analysis/ValueTracking.cpp
4427 ↗(On Diff #166784)
unittests/Analysis/ValueTrackingTest.cpp
115 ↗(On Diff #166784)

Could you add some comments for the tests about what each test is testing?

tlively added inline comments.Sep 24 2018, 7:04 PM
lib/Analysis/ValueTracking.cpp
4427 ↗(On Diff #166784)

Not quite. Constant::isNaN and Constant::isZeroValue can detect whether *all* or *not all* of the vector elements are NaN or zero. Here we want to detect if *any* or *not any* of the elements are NaN or zero.

xbolva00 added inline comments.
lib/Analysis/ValueTracking.cpp
4427 ↗(On Diff #166784)

Can we extract this code to a helper function somewhere to Constant or so..?

aheejin added inline comments.Sep 25 2018, 1:48 PM
lib/Analysis/ValueTracking.cpp
4427 ↗(On Diff #166784)

Why is the definition of non-NaN different from !isNaN()?

tlively added inline comments.Sep 25 2018, 2:25 PM
lib/Analysis/ValueTracking.cpp
4427 ↗(On Diff #166784)

For the same "any" vs "all" reason. Known-non-nan means no lanes are NaN, which is different from !isNaN(), which means means not all lanes are NaN (but some of them might be).

tlively added inline comments.Sep 25 2018, 2:47 PM
lib/Analysis/ValueTracking.cpp
4427 ↗(On Diff #166784)

@xbolva00 We could extract this code to Constant, but it doesn't really fit in there. There are no other methods of Constant that say whether each element of the constant do *not* have a particular property, which is what these functions are doing. I played around with instead adding methods to Constant for detecting whether any lane has a particular property, which is the negation of what we want. That refactoring subtly changed the way undef lanes are handled in select patterns, breaking some X86 tests I do not yet understand. I'm therefore inclined to say that the refactoring seems to be overall not worth the effort.

Do we need to handle integer vectors too?

unittests/Analysis/ValueTrackingTest.cpp
102 ↗(On Diff #166784)

Why can't this be determined? (1-2 line comment will be good too)

115 ↗(On Diff #166784)

Nit: can we move these tests so they go after the scalar tests? Currently these are between SimpleFMin and SimpleFMax.

tlively added inline comments.Sep 25 2018, 5:44 PM
unittests/Analysis/ValueTrackingTest.cpp
102 ↗(On Diff #166784)

The 0x7ff8000000000000 value is a NaN, so if the second lane behaves like fminnum while the other lanes behave like fminnan. Will add a comment.

tlively updated this revision to Diff 167037.Sep 25 2018, 6:22 PM
tlively marked 3 inline comments as done.
  • Address comments on tests
aheejin added inline comments.Sep 26 2018, 2:23 PM
unittests/Analysis/ValueTrackingTest.cpp
163 ↗(On Diff #167037)

How is the third argument Ordered determined?

177 ↗(On Diff #167037)

fminnum and fminnan are SelectionDAG terms, so I guess it would be better to describe in terms of SPNB_RETURNS_NAN and SPNB_RETURNS_OTHER here.

193 ↗(On Diff #167037)

Can we have a few more test cases? I understand here you omitted very basic ones and put only a bit tricky cases that arises from the fact we are dealing with vectors, but having basic ones wouldn't hurt and help understanding. Such as, 1. ordered comparison that results in SPNB_RETURNS_OTHER 2. unordered comparison in which the right hand side is all NaNs

tlively updated this revision to Diff 167351.Sep 27 2018, 10:43 AM
tlively marked 2 inline comments as done.
  • Add test case, tweak wording
tlively added inline comments.Sep 27 2018, 10:44 AM
unittests/Analysis/ValueTrackingTest.cpp
163 ↗(On Diff #167037)

By the comparison operator. For example, here ule is unordered.

193 ↗(On Diff #167037)

I added a test for ordered comparison returning other, but having a vector of all NaNs currently results in SPF_UNKNOWN, SPNB_NA, because this is actually something that can be constant folded, rather than being a min or max. I also tried testing with undefs in vector lanes but the same thing happened. I'm not sure if failing to pattern match in the presence of undefs was an intentional decision, so I'm inclined not to change it.

aheejin added inline comments.Sep 27 2018, 4:18 PM
unittests/Analysis/ValueTrackingTest.cpp
163 ↗(On Diff #167037)

I thought so first, but other existing test cases don’t seem to follow that rule. So I was wondering if it means something else.

tlively added inline comments.Sep 27 2018, 5:01 PM
unittests/Analysis/ValueTrackingTest.cpp
163 ↗(On Diff #167037)

No, but it does default to false for integer min/max and patterns that are not min/max, regardless of the comparison mode.

aheejin accepted this revision.Sep 28 2018, 2:00 PM

If this CL only handles floating point vectors and not integer vectors, I don't think that's a job of this CL to implement the integer part as well, but maybe it's better to add a line of comment that's marked as TODO saying currently in case of vectors only floating points are supported, or something. Otherwise LGTM.

This revision is now accepted and ready to land.Sep 28 2018, 2:00 PM

Oh, and maybe it's better to fix the title too: "floating point vectors"

tlively retitled this revision from [ValueTracking] Allow select patterns to work on vectors in more places to [ValueTracking] Allow select patterns to work on FP vectors.Sep 28 2018, 2:20 PM

If this CL only handles floating point vectors and not integer vectors, I don't think that's a job of this CL to implement the integer part as well, but maybe it's better to add a line of comment that's marked as TODO saying currently in case of vectors only floating points are supported, or something. Otherwise LGTM.

Looking at the code again, I think integer vectors should already be handled ok, so no need for a TODO.

This revision was automatically updated to reflect the committed changes.