This is an archive of the discontinued LLVM Phabricator instance.

[InstSimplify] fold select of vector constants that include undef elements
ClosedPublic

Authored by spatel on Jan 17 2020, 1:48 PM.

Details

Summary

As mentioned in D72643, we'd like to be able to assert that any select of equivalent constants has been removed before we're deep into InstCombine.

But there's a loophole in that assertion for vectors with undef elements that don't match exactly.

This patch should close that gap. If we have undefs, we can't safely propagate those unless both constants elements for that lane are undef.

Diff Detail

Event Timeline

spatel created this revision.Jan 17 2020, 1:48 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 17 2020, 1:48 PM
nikic added inline comments.Jan 18 2020, 8:58 AM
llvm/lib/Analysis/InstructionSimplify.cpp
4044

I'm having a bit of a hard time convincing myself that this is always correct. In particular, the relationship between isElementWiseEqual(), which is based on ConstantExpr::getICmp() and this code, which is based on simple identity comparison, is not entirely clear. If the vector includes complex constant expressions, and ConstantExpr::getICmp() manages to fold that code while the identity comparison fails, this would trigger an assertion failure here. Or is there an invariant that this cannot happen?

spatel marked an inline comment as done.Jan 19 2020, 11:29 AM
spatel added inline comments.
llvm/lib/Analysis/InstructionSimplify.cpp
4044

I've tried to concoct an example of this:

@g = global i32 0

define <3 x i32> @sel_constant_expression(<3 x i1> %cond) {
  %r = select <3 x i1> %cond, <3 x i32> <i32 ptrtoint (i32* @g to i32), i32 0, i32 1>, <3 x i32> <i32 bitcast (<2 x i16> bitcast (i32 ptrtoint (i32* @g to i32) to <2 x i16>) to i32), i32 0, i32 undef>
  ret <3 x i32> %r
}

...but the 2nd ConstantExpr get constant folded into the reduced form of the 1st (the bitcasts go away). So we can either leave this as-is, or we could bail out on ConstantExpr to be safe(r)? I can't imagine that this will ever make a difference in any real-world code.

nikic added inline comments.Jan 19 2020, 11:40 AM
llvm/lib/Analysis/InstructionSimplify.cpp
4044

I wasn't able to come up with an example either.

I do wonder though if this code shouldn't just forgo isElementWiseEqual() entirely and just cover all four cases in this if/else chain instead? I.e. equality, undef op1, undef op2, else abort the transform. Going through isElementWiseEqual() doesn't really seem to make this code simpler.

spatel updated this revision to Diff 239063.Jan 20 2020, 3:57 AM
spatel marked 2 inline comments as done.

Patch updated:
Reduce code - don't bother with isElementWiseEqual(). If elements don't match, break and carry on with other simplifications.

llvm/lib/Analysis/InstructionSimplify.cpp
4044

Good point. We have to walk through the vector elements anyway, so we can save time and space by doing it all in one place.

nikic accepted this revision.Jan 20 2020, 4:03 AM

LGTM

This revision is now accepted and ready to land.Jan 20 2020, 4:03 AM
This revision was automatically updated to reflect the committed changes.