This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Simplify cttz/ctlz + icmp ugt/ult into mask check
ClosedPublic

Authored by nikic on Jan 5 2019, 8:12 AM.

Details

Summary

Followup to D55745, this time handling comparisons with ugt and ult predicates (which are the canonical forms for non-equality predicates).

Based on the results, for ctlz we have the nice property that the mask check can always be represented as a ult/ugt comparison instead. I'm wondering if I should just emit it directly in that form and drop the single use check?

Diff Detail

Event Timeline

nikic created this revision.Jan 5 2019, 8:12 AM
lebedev.ri added inline comments.
lib/Transforms/InstCombine/InstCombineCompares.cpp
2769–2770

I wonder if it would be less ugly to split this into foldICmpIntrinsicWithConstant() and foldICmpEQIntrinsicWithConstant()?

2786–2789

Can we instead do this check later on in the code, when we know it is needed?

test/Transforms/InstCombine/cmp-intrinsic.ll
336–452
  1. Why cram everything into one test file? Why not split into ctlz.ll + cttz.ll + ...
  2. These are cttz tests. Using %lz is *very* confusing. Please fix this.
RKSimon added a subscriber: RKSimon.Jan 5 2019, 8:46 AM

vector tests?

nikic updated this revision to Diff 180373.Jan 5 2019, 10:17 AM

Split up functions for eq and non-eq icmps. Handle ctlz separately from cttz by going directly to the form using only a comparison. Rebase over improved tests with multiuse and vector variants.

Hm, why does this modify the existing instruction, and manually adds it to worklist,
instead of simply creating a new instruction? This is rather unusual for instcombine i think.

lib/Transforms/InstCombine/InstCombineCompares.cpp
2769–2770

Please do mark fixed comments as such.

nikic marked 3 inline comments as done.Jan 5 2019, 11:07 AM

Hm, why does this modify the existing instruction, and manually adds it to worklist,
instead of simply creating a new instruction? This is rather unusual for instcombine i think.

I assumed that this was to avoid creating a new instruction when we can reuse an existing one. If this is just an anachronism, I can switch the existing code to create new nodes in a separate NFC commit and then adjust it here as well.

Hm, why does this modify the existing instruction, and manually adds it to worklist,
instead of simply creating a new instruction? This is rather unusual for instcombine i think.

I assumed that this was to avoid creating a new instruction when we can reuse an existing one.
If this is just an anachronism, I can switch the existing code to create new nodes in a separate NFC commit and then adjust it here as well.

Unless the current approach was specifically requested during previous reviews (then a comment is needed),
IMHO yes please do change this.

nikic updated this revision to Diff 180378.Jan 5 2019, 12:15 PM

Create new compare instructions instead of modifying existing ones and manually managing worklist.

I'll also update the existing code for intrinsic icmps to this style, if it's accepted in this form.

RKSimon added inline comments.
lib/Transforms/InstCombine/InstCombineCompares.cpp
2617

(style) Remove unnecessary braces

2836

In case of "silly" numbers from fuzzers etc. better to use C.ult(BitWidth) etc.and move C.getLimitedValue() calls inside the ifs.

nikic updated this revision to Diff 182338.Jan 17 2019, 10:28 AM

Remove unnecessary braces. Use getLimitedValue() only after range checks.

No more comments from me @spatel ?

spatel accepted this revision.Jan 17 2019, 3:42 PM

LGTM - see inline comment for minor improvement.

lib/Transforms/InstCombine/InstCombineCompares.cpp
2856

It would be nice to have a code comment that shows the general transform formula and/or an example of how this works based on the regression tests. Seeing those makes it clear, but it's not obvious to me just looking at the code.

This revision is now accepted and ready to land.Jan 17 2019, 3:42 PM
This revision was automatically updated to reflect the committed changes.