This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Avoid moving ops that do restrict undef across shuffles.
ClosedPublic

Authored by fhahn on Nov 11 2019, 9:55 AM.

Details

Summary

I think we have to be a bit more careful when it comes to moving
ops across shuffles, if the op does restrict undef. For example, without
this patch, we would move 'and %v, <0, 0, -1, -1>' over a
'shufflevector %a, undef, <undef, undef, 1, 2>'. As a result, the first
2 lanes of the result are undef after the combine, but they really
should be 0, unless I am missing something.

For ops that do fold to undef on undef operands, the current behavior
should be fine. I've add conservative check OpDoesRestrictUndef, maybe
there's a better existing utility?

Diff Detail

Event Timeline

fhahn created this revision.Nov 11 2019, 9:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 11 2019, 9:55 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
fhahn updated this revision to Diff 228726.Nov 11 2019, 9:56 AM

clang-format

lebedev.ri added inline comments.Nov 11 2019, 10:17 AM
llvm/test/Transforms/InstCombine/vec_shuffle.ll
1010–1016

Hmm yes, i'd agree this is a miscompile..

RKSimon added inline comments.Nov 11 2019, 10:23 AM
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
1513

@spatel Do we have an existing helper for something like this? I know you added getKnownUndefForVectorBinop to the DAG

spatel added inline comments.Nov 11 2019, 12:08 PM
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
1513

I don't think there's a twin of that for IR. Unfortunately, we have bits and pieces of the puzzle in both places...

1552

What if we extend this check instead:

if (I >= SrcVecNumElts || ShMask[I] < 0) {

Currently, we're transferring an undef element from the original shuffle to the newly created shuffle, but that's not safe in general. It is safe, however, if the binop would constant fold to undef given an undef operand.

(Sorry this code got so complicated...)

llvm/test/Transforms/InstCombine/vec_shuffle.ll
1010–1016

This test is not committed to trunk? Add that along with similar patterns for other binop opcodes like the add/sub/shl noted in this patch? That way we'll know if this or my alternate suggestion is behaving as intended.

fhahn marked an inline comment as done.Nov 11 2019, 12:38 PM
fhahn added inline comments.
llvm/test/Transforms/InstCombine/vec_shuffle.ll
1010–1016

I did not commit the test yet, but the diff here just shows the difference in output. I'll check with more positive and negative scenarios

fhahn updated this revision to Diff 229033.Nov 13 2019, 1:58 AM

Update to use code that uses ConstantExpr to check if things fold to undef again.

fhahn marked 2 inline comments as done.Nov 13 2019, 1:58 AM
fhahn added inline comments.
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
1552

That's indeed a better place. I've updated the code to use the existing checks here.

fhahn marked an inline comment as done.

The FIXMEs are addressed by D70169

spatel accepted this revision.Nov 13 2019, 4:53 AM

LGTM - thanks!

This revision is now accepted and ready to land.Nov 13 2019, 4:53 AM
This revision was automatically updated to reflect the committed changes.