This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] fold freeze of partial undef/poison vector constants
ClosedPublic

Authored by spatel on Apr 18 2022, 2:45 PM.

Details

Summary

We can always replace the undef elements in a vector constant with regular constants to get rid of the freeze:
https://alive2.llvm.org/ce/z/nfRb4F

The select diffs show that we might do better by adjusting the logic for a frozen select condition, but I think those are still improvements.

Diff Detail

Event Timeline

spatel created this revision.Apr 18 2022, 2:45 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 18 2022, 2:45 PM
spatel requested review of this revision.Apr 18 2022, 2:45 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 18 2022, 2:45 PM
spatel updated this revision to Diff 423476.Apr 18 2022, 2:49 PM

It should not change the outcome, but there was an unintended change of the 'getTrue' call in the last revision.

Given that we are replacing freeze constant with constant, and selecting the constant based on all the users,
can we instead go over all the users, and perform replacement for each one separately, always picking the best choice?

Given that we are replacing freeze constant with constant, and selecting the constant based on all the users,
can we instead go over all the users, and perform replacement for each one separately, always picking the best choice?

Yes, we could use getBinOpIdentity or getSafeVectorConstantForBinop or something like that. But I think it would be bigger/independent of this change, and I haven't seen a need for it yet. Add a TODO?

nikic added a comment.Apr 18 2022, 3:18 PM

For vector constants with some undef elements, wouldn't we be better off picking an existing (non-undef) vector element? That would be especially profitable if we can produce a splat vector constant.

Given that we are replacing freeze constant with constant, and selecting the constant based on all the users,
can we instead go over all the users, and perform replacement for each one separately, always picking the best choice?

Unless I'm misunderstanding what you're suggesting here, this is not legal: The value has to be chosen to be the same for all users.

For vector constants with some undef elements, wouldn't we be better off picking an existing (non-undef) vector element? That would be especially profitable if we can produce a splat vector constant.

Given that we are replacing freeze constant with constant, and selecting the constant based on all the users,
can we instead go over all the users, and perform replacement for each one separately, always picking the best choice?

Unless I'm misunderstanding what you're suggesting here, this is not legal: The value has to be chosen to be the same for all users.

Agree - looking back to D84948, this was discussed. The initial revision (this link is intended to show it):
https://reviews.llvm.org/D84948?vs=on&id=281923#toc
...added match of one-use freeze at various user sites; that would not work for multi-use.

So we could try harder for the one-use case by using binop identity or similar, but we need to end up with a common value for multi-use. Zero is the easy choice, but it looks like the current implementation could do better...for example, if all of the multiple users are "or" ops, we would generate a "-1".

spatel updated this revision to Diff 423600.Apr 19 2022, 5:56 AM

Patch updated:

  1. Added an explanatory comment for the position of this fold.
  2. Added TODO comment for enhancement.
  3. Added an assert for "BestValue" (suggested in D84948, but didn't make it in).

These all apply to the existing code, so that could be an NFC pre-commit if preferred.

nikic added a comment.Apr 19 2022, 6:17 AM

What about

For vector constants with some undef elements, wouldn't we be better off picking an existing (non-undef) vector element? That would be especially profitable if we can produce a splat vector constant.

?

I still think that would make more sense for the vector case.

What about

For vector constants with some undef elements, wouldn't we be better off picking an existing (non-undef) vector element? That would be especially profitable if we can produce a splat vector constant.

?

I still think that would make more sense for the vector case.

Sorry, I didn't see that comment initially. It's complicated to decide what qualifies as "best" constant for a vector. Yes, a splat is generally good, but a zero can be better if it allows a follow-on transform like narrowing. I don't have any evidence to support one way or the other yet.

The motivation for this patch is largely theoretical at this point - I was looking at making the transform from https://github.com/llvm/llvm-project/issues/47012 safe via freeze and saw that it would cause vector test regressions because there was no support for reducing vector constants at all.

nlopes accepted this revision.Apr 26 2022, 6:10 AM

LGTM. It's better than keeping freeze around. If we get concrete examples later of non-ideal "best" constants we can improve.

This revision is now accepted and ready to land.Apr 26 2022, 6:10 AM
This revision was landed with ongoing or failed builds.Apr 26 2022, 11:16 AM
This revision was automatically updated to reflect the committed changes.