This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Teach visitICmpInst to not break integer absolute value idioms
ClosedPublic

Authored by craig.topper on Nov 7 2017, 3:29 PM.

Details

Summary

This patch adds an early out to visitICmpInst if we are looking at a compare as part of an integer absolute value idiom. Similar is already done for min/max.

In the particular case I observed in a benchmark we had an absolute value of a load from an indexed global. We simplified the compare using foldCmpLoadFromIndexedGlobal into a magic bit vector, a shift, and an and. But the load result was still used for the select and the negate part of the absolute valute idiom. So we overcomplicated the code and lost the ability to recognize it as an absolute value.

I've chosen a simpler case for the test here.

Diff Detail

Repository
rL LLVM

Event Timeline

craig.topper created this revision.Nov 7 2017, 3:29 PM

Add full context

spatel edited edge metadata.Nov 10 2017, 6:39 AM

Should we recognize (and canonicalize) this abs() pattern:

define i64 @abs5(i64 %x) {
  %signbit = ashr i64 %x, 63      ; smear the sign bit
  %add = add i64 %x, %signbit     ; add 0 or -1
  %abs = xor i64 %add, %signbit   ; x < 0 ? -x : x
  ret i64 %abs
}

(note: I mentioned this pattern to the group looking at matching vector idioms earlier this year - not sure what happened to that effort).

Independent of that, how about calling ValueTracking's matchSelectPattern()? Then, we could check all of min/max/abs in one shot without repeating the logic here.

Use matchSelectPattern instead. Use user_back instead of user_begin since it does that same thing without the explicit dereference. Also updated the equivalent place in visitFCmp.

spatel accepted this revision.Nov 11 2017, 11:55 AM

LGTM.

This revision is now accepted and ready to land.Nov 11 2017, 11:55 AM
This revision was automatically updated to reflect the committed changes.

Should we recognize (and canonicalize) this abs() pattern:

define i64 @abs5(i64 %x) {
  %signbit = ashr i64 %x, 63      ; smear the sign bit
  %add = add i64 %x, %signbit     ; add 0 or -1
  %abs = xor i64 %add, %signbit   ; x < 0 ? -x : x
  ret i64 %abs
}

(note: I mentioned this pattern to the group looking at matching vector idioms earlier this year - not sure what happened to that effort).

Independent of that, how about calling ValueTracking's matchSelectPattern()? Then, we could check all of min/max/abs in one shot without repeating the logic here.

I also had the same question, thanks for help.