This is an archive of the discontinued LLVM Phabricator instance.

[InstSimplify] add nuw %x, -1 -> -1 fold.
ClosedPublic

Authored by lebedev.ri on Jun 7 2018, 2:46 PM.

Details

Summary

%ret = add nuw i8 %x, C
From langref:

nuw and nsw stand for “No Unsigned Wrap” and “No Signed Wrap”,
respectively. If the nuw and/or nsw keywords are present,
the result value of the add is a poison value if unsigned
and/or signed overflow, respectively, occurs.

So if C is -1, %x can only be 0, and the result is always -1.

I'm not sure we want to use KnownBits/LVI here, because there is
exactly one possible value (all bits set, -1), so some other pass
should take care of replacing the known-all-ones with constant -1.

The test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll change *is* confusing.
What happening is, before this: (omitting nuw for simplicity)

  1. First, InstCombine D47428/rL334127 folds shl i32 1, %NBits) to shl nuw i32 -1, %NBits
  2. Then, InstSimplify D47883/rL334222 folds shl nuw i32 -1, %NBits to -1,
  3. -1 is inverted to 0.

But now:

  1. *This* InstSimplify fold %ret = add nuw i32 %setbit, -1 -> -1 happens first, before InstCombine D47428/rL334127 fold could happen.

Thus we now end up with the opposite constant,
and it is all good: https://rise4fun.com/Alive/OA9

https://rise4fun.com/Alive/sldC
Was mentioned in D47428 review.
Follow-up for D47883.

Diff Detail

Repository
rL LLVM

Event Timeline

lebedev.ri created this revision.Jun 7 2018, 2:46 PM
lebedev.ri edited the summary of this revision. (Show Details)Jun 7 2018, 2:58 PM
lebedev.ri edited the summary of this revision. (Show Details)Jun 7 2018, 3:02 PM
spatel added inline comments.Jun 8 2018, 7:59 AM
test/Transforms/InstSimplify/constantfold-add-nuw-allones-to-allones.ll
68 ↗(On Diff #150408)

That's an interesting one. I think I conservatively returned a new, fully defined vector constant in all cases when I was enhancing the pattern matchers to account for undef elements.

But this looks correct - add with an undef operand returns undef, so we can propagate the existing constant vector value.

spatel accepted this revision.Jun 8 2018, 8:17 AM

LGTM.

lib/Analysis/InstructionSimplify.cpp
530 ↗(On Diff #150408)

Possible cosmetic cleanup since we're here:
isNSW -> IsNSW
isNUW -> IsNUW

569–572 ↗(On Diff #150408)

Better to put this above the previous fold, so wrapping-based folds are next to each other?

This revision is now accepted and ready to land.Jun 8 2018, 8:17 AM

LGTM.

Thank you for the review!

This revision was automatically updated to reflect the committed changes.