This is an archive of the discontinued LLVM Phabricator instance.

[DAG] Fold neg(bvsplat(neg(x)) -> bvsplat(x)
ClosedPublic

Authored by dmgreen on Jun 5 2021, 11:49 AM.

Details

Summary

This add as a fold of sub(0, buildvector_splat(sub(0, x))) -> buildvector_splat(x). This is something that can come up in the lowering of right shifts under AArch64, where we generate a shift left of a negated number.

Diff Detail

Event Timeline

dmgreen created this revision.Jun 5 2021, 11:49 AM
dmgreen requested review of this revision.Jun 5 2021, 11:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 5 2021, 11:49 AM

Funnily enough I was wondering about this pattern the other day as a followup to D98778...

Should we always be folding unaryop(splat(x)) -> splat(unaryop(x)) if the unaryop is legal/custom on the scalar type? And then maybe extend that to binop(splat(x),splat(y)) -> splat(binop(x,y)) as well?

Matt added a subscriber: Matt.Jun 7 2021, 8:17 AM

Funnily enough I was wondering about this pattern the other day as a followup to D98778...

Should we always be folding unaryop(splat(x)) -> splat(unaryop(x)) if the unaryop is legal/custom on the scalar type? And then maybe extend that to binop(splat(x),splat(y)) -> splat(binop(x,y)) as well?

Maybe. Not sure. I always find it difficult to see when optimizations like that would be universally beneficial over a wide range of very different architectures, considering how different they can be. I can see that it would make this more general, but it seems easy to think of cases where it would make things worse.

For this case I think it would need to work with the truncated type, not the scalar element type. For a v8i16 the scalar element type would not be legal under AArch64. If it was using the element type it would only handle half of the tests changed here.

sdesmalen added inline comments.Jun 8 2021, 4:25 AM
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
3313

Can SelectionDAG::getSplatValue() be used here? If so, then this doesn't need to be limited to BUILD_VECTOR, as it seems this fold would work equally well for scalable vectors (which use SPLAT_VECTOR).

dmgreen added inline comments.Jun 21 2021, 12:12 AM
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
3313

Thanks for taking a look. Yeah, seems to work OK. I'll make it so.

dmgreen updated this revision to Diff 353282.Jun 21 2021, 12:14 AM

Use getSplatValue.

RKSimon accepted this revision.Jun 23 2021, 7:02 AM

LGTM - cheers

This revision is now accepted and ready to land.Jun 23 2021, 7:02 AM
sdesmalen added inline comments.Jun 24 2021, 4:43 AM
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
3312

nit: s/bvsplat/splat/g

llvm/test/CodeGen/AArch64/neon-shift-neg.ll
254

It seems odd to have a scalable-vector test in neon-shift-neg.ll ? (I actually can't find this test in latest HEAD, am I looking at the right diff?)

dmgreen added inline comments.Jun 25 2021, 11:30 AM
llvm/test/CodeGen/AArch64/neon-shift-neg.ll
254

Yeah.. The same pattern of negated shifts does not apply for SVE (which makes it a little less useful). I've added a more direct test in 77ae9b364a9d9b99501163761313cefbb345cea7.

This revision was landed with ongoing or failed builds.Jun 25 2021, 11:53 AM
This revision was automatically updated to reflect the committed changes.