This is an archive of the discontinued LLVM Phabricator instance.

[InstSimplify] [NFC] Add tests for peeking through unsigned FP casts for sign compares (PR36682)
ClosedPublic

Authored by lebedev.ri on Mar 13 2018, 4:58 AM.

Details

Summary

This pattern came up in PR36682 / D44390
https://bugs.llvm.org/show_bug.cgi?id=36682
https://reviews.llvm.org/D44390
https://godbolt.org/g/oKvT5H

Looking at the IR pattern in question, as per alive-nj, for all the type combinations i checked
(input: i16, i32, i64; intermediate: half/i16, float/i32, double/i64)
for the following icmp comparisons the uitofp+bitcast+icmp can be evaluated to a boolean:

  • slt 0
  • sgt -1

I did not check vectors, but i'm guessing it's the same there.

Thus all these cases are in the testcase (along with the vector variant with additional undef element in the middle).
There are no negative patterns here (unless alive-nj lied/is broken), all of these should be optimized.

Diff Detail

Repository
rL LLVM

Event Timeline

lebedev.ri created this revision.Mar 13 2018, 4:58 AM

Added a comment to the test

spatel added inline comments.Mar 13 2018, 1:57 PM
test/Transforms/InstCombine/cast-unsigned-icmp-cmp-0.ll
8–11 ↗(On Diff #138157)

If the result of the fold is a constant, then the test (and the transform) can go in InstSimplify rather than InstCombine.
Also, as with my earlier comment, I appreciate the thorough testing, but I don't think we need 30+ tests of this fold. Some variation between data widths and vectors should give us enough coverage. There should be at least one vector test *without* undef in the zero constant because that shows a different result currently.

lebedev.ri added inline comments.Mar 13 2018, 2:01 PM
test/Transforms/InstCombine/cast-unsigned-icmp-cmp-0.ll
8–11 ↗(On Diff #138157)

Ok, got it, will update patches accordingly.

lebedev.ri marked 2 inline comments as done.
lebedev.ri retitled this revision from [InstCombine] [NFC] Add tests for peeking through unsigned FP casts for sign compares (PR36682) to [InstSimplify] [NFC] Add tests for peeking through unsigned FP casts for sign compares (PR36682).

Reduced amount of test patterns while improving test coverage.

spatel accepted this revision.Mar 14 2018, 9:40 AM

Thanks - that's better coverage. LGTM.

test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
8–9 ↗(On Diff #138380)

The wording is confusing. I'd make this:
; FIXME: All of these can be simplified to a constant true or false value.

This revision is now accepted and ready to land.Mar 14 2018, 9:40 AM
This revision was automatically updated to reflect the committed changes.
spatel added inline comments.Mar 14 2018, 10:38 AM
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
2–5

Sorry - I didn't catch this before. Why are we doing anything with -instcombine here? We should only be running -instsimplify on this file.

lebedev.ri added inline comments.Mar 14 2018, 10:42 AM
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
2–5

You commented on the explanation note :)
)I moved it here from the next diff before commit, should have done that earlier)

lebedev.ri added inline comments.Mar 14 2018, 10:47 AM
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
2–5

Uhm, yeah, i was thinking of something else, that instcombine transform would not be valid anyway:

$ ~/src/alive-nj/run.py /tmp/slt.txt 
----------                                                                      
Name: slt
  %f   = uitofp i32 %i to float
  %b   = bitcast float %f to i32
  %cmp = icmp slt i32 %b, 0
=>
  %cmp = icmp slt i32 %i, 0

ERROR: Mismatch in values for i1 %cmp                                           

Example:
  i32 %i = 0x80000000 (2147483648, -2147483648)
float %f = 1*(2**31)
  i32 %b = 0x0f800000 (260046848)
source: 0x0 (0)
target: 0x1 (1, -1)

$ ~/src/alive-nj/run.py /tmp/sgt.txt
----------                                                                      
Name: sgt
  %f   = uitofp i32 %i to float
  %b   = bitcast float %f to i32
  %cmp = icmp sgt i32 %b, -1
=>
  %cmp = icmp sgt i32 %i, -1

ERROR: Mismatch in values for i1 %cmp                                           

Example:
  i32 %i = 0x80000000 (2147483648, -2147483648)
float %f = 1*(2**31)
  i32 %b = 0x0f800000 (260046848)
source: 0x1 (1, -1)
target: 0x0 (0)

Sorry, let me remove that pass..

spatel added inline comments.Mar 14 2018, 10:50 AM
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
2–5

I'm confused. We're going to add code to -instsimplify, so these tests should be only for that pass. Why is -instcombine in the RUN line?

lebedev.ri added inline comments.Mar 14 2018, 10:56 AM
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
2–5
; NOTE: we run instcombine first,
; to make sure that it does *NOT* drop uitofp+bitcast here.

In other words, i *thought* that running instcombine first would make sure that
a combine to drop uitofp+bitcast from that case won't be added to instcombine.
If it would be added, then we wouldn't be able to simplify to a boolean here.

But such a fold would be invalid, so there is zero point in running instcombine
in this case, thus i will now drop that pass from the runline.

lebedev.ri added inline comments.Mar 14 2018, 11:02 AM
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
2–5

rL327541, sorry for the noise :(