This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Fold icmp eq/ne (and %x, signbit), 0 -> %x s>=/s< 0 earlier
ClosedPublic

Authored by huihuiz on Jun 7 2019, 2:12 PM.

Details

Summary

To generate simplified IR, make sure fold

(X & signbit) ==/!= 0) -> X s>=/s< 0;

is scheduled before fold

((X << Y) & C) == 0 -> (X & (C >> Y)) == 0.

https://rise4fun.com/Alive/fbdh

Diff Detail

Repository
rL LLVM

Event Timeline

huihuiz created this revision.Jun 7 2019, 2:12 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 7 2019, 2:12 PM

This fix D63025
Split from D62818

huihuiz updated this revision to Diff 204435.Jun 12 2019, 11:45 PM
lebedev.ri retitled this revision from [InstCombine] Fix fold order for icmp pred (and (sh X, Y), C), 0. to [InstCombine] Fold icmp eq/ne (and %x, signbit), 0 -> %x s>=/s< 0 earlier.Jun 16 2019, 4:27 PM
lebedev.ri edited the summary of this revision. (Show Details)

Yep, first fold looks good, some nits.

lib/Transforms/InstCombine/InstCombineCompares.cpp
1643–1644 ↗(On Diff #204435)

Move after the newly added code, this restriction does not apply for the pattern in question.

1654 ↗(On Diff #204435)

X u< 8

1654–1662 ↗(On Diff #204435)

I'm sorry that i keep nagging, but this is a second, not unrelated, but separate fold.
Please put it into a separate review :)

test/Transforms/InstCombine/shl-and-signbit-icmpeq-zero.ll
125 ↗(On Diff #204435)

It didn't though (:

142 ↗(On Diff #204435)

Similarly, should fold.

160 ↗(On Diff #204435)

Here too

huihuiz updated this revision to Diff 205388.Jun 18 2019, 10:26 AM
huihuiz marked 4 inline comments as done.
huihuiz added inline comments.Jun 18 2019, 10:26 AM
lib/Transforms/InstCombine/InstCombineCompares.cpp
1643–1644 ↗(On Diff #204435)

The restriction "And operation having only one use" was introduced in r134379 (resolving PR10267).

When And operation has more than one use, applying the following folds will transform an equality compare into an inequality compare, without cutting done any extra instructions. Inequalities are generally more expensive.

This restriction should apply to fold "(X & signbit) ==/!= 0) --> X s>=/s< 0"and "((X & ~C) ==/!= 0) C+1 is power of 2 --> X u</u>= C+1".

test/Transforms/InstCombine/shl-and-signbit-icmpeq-zero.ll
125 ↗(On Diff #204435)

Actually fold happened even without this reordering.
look for the generate ll

**%shl = shl i32 %x, %y**
%xor = xor i32 %shl, %z
store i32 %xor, i32* %p, align 4
**%r = icmp sgt i32 %shl, -1**

we are trying to schedule (X & signbit) ==/!= 0) -> X s>=/s< 0; before ((X << Y) & C) == 0 -> (X & (C >> Y)) == 0.
The second fold has restriction on "shift having only one use", which failed for this case.

So fold happened even without reorder, extra use of shift doesn't restrict on the first fold

142 ↗(On Diff #204435)

Should still comply with restriction on "And operation having only one use", as explained in r134379.

160 ↗(On Diff #204435)

Similar as above. And operation has extra use, should comply with the restriction.

lebedev.ri added inline comments.Jun 18 2019, 10:39 AM
lib/Transforms/InstCombine/InstCombineCompares.cpp
1643–1644 ↗(On Diff #204435)

Aha, thank you for digging that up.

The restriction "And operation having only one use" was introduced in r134379 (resolving PR10267).
When And operation has more than one use, applying the following folds will transform an equality compare into an inequality compare, without cutting done any extra instructions. Inequalities are generally more expensive.

All that (including rL134379) reads wrong to me.
There is no such cost-model in middle-end,
here in instcombine we only care about not increasing instruction count.
If something is worse for backend/target, then the opposite fold should be done in backend.

Not having this one-use restriction does not result in increasing
instruction count, and decreases "the dependency chain" of the icmp,
since it no longer depends on and, i.e. the restriction is incorrect/harmful.

But i suppose lifting it up first requires a backend fix, so let's leave it for now :/

lebedev.ri accepted this revision.Jun 18 2019, 10:53 AM

I think this looks good now, thank you for working on this!
Can you please link the patch into which you split the second fold from here?

lib/Transforms/InstCombine/InstCombineCompares.cpp
1025–1033 ↗(On Diff #204435)

Can you please link the patch to which you split this out?

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
1647 ↗(On Diff #205388)

Please add a comment about the reason (PR10267) this fold is restricted to one-use and.

This revision is now accepted and ready to land.Jun 18 2019, 10:53 AM

Hmm, here too, an undo fold seems to be missing https://godbolt.org/z/T9NwwJ

huihuiz updated this revision to Diff 205630.Jun 19 2019, 10:18 AM
huihuiz marked an inline comment as done.

this differential update address inline comment - adding comment for restriction this fold to single-use 'and' (PR10267)

This revision was automatically updated to reflect the committed changes.