This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Simplify cttz/ctlz + icmp eq/ne into mask check
ClosedPublic

Authored by nikic on Dec 16 2018, 11:28 AM.

Details

Summary

Related to https://bugs.llvm.org/show_bug.cgi?id=28668.

Checking whether a number has a certain number of trailing / leading zeros means checking whether it is of the form 0001XXXX or XXXX1000, which can be done with an and+icmp.

This is the first step, handling only eq/ne predicates, as that's what the existing code does. I'd like to extend this to handle all predicate types in the next step, which would resolve https://github.com/rust-lang/rust/issues/43024.

Diff Detail

Event Timeline

nikic created this revision.Dec 16 2018, 11:28 AM
spatel added inline comments.Dec 17 2018, 1:39 PM
lib/Transforms/InstCombine/InstCombineCompares.cpp
2796

We have to check hasOneUse() on the intrinsic, or we'll end up with extra instructions for an example like this:

define i1 @ctlz_eq_other_i32(i32 %x, i32* %p) {
  %lz = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
  store i32 %lz, i32* %p
  %cmp = icmp eq i32 %lz, 24
  ret i1 %cmp
}

In cases where the 'and' gets removed, you don't need the one-use restriction, but I'm not sure if it's worth trying to differentiate those from the general case.

nikic updated this revision to Diff 178735.Dec 18 2018, 11:01 AM

Add single use check and tests.

nikic marked 2 inline comments as done.Dec 18 2018, 11:03 AM
nikic added inline comments.
lib/Transforms/InstCombine/InstCombineCompares.cpp
2796

Thanks, I've added the hasOneUse() check and a couple tests. And yeah, I don't think it's worth handling those cases separately.

spatel accepted this revision.Dec 18 2018, 11:17 AM

LGTM

This revision is now accepted and ready to land.Dec 18 2018, 11:17 AM
This revision was automatically updated to reflect the committed changes.
nikic marked an inline comment as done.