This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Combine: (G_*MULO x, 0) -> 0 + no carry out
ClosedPublic

Authored by paquette on Jan 31 2022, 10:55 AM.

Details

Summary

Similar to the following combine in DAGCombiner::visitMULO:

// fold (mulo x, 0) -> 0 + no carry out
if (isNullOrNullSplat(N1))
return CombineTo(N, DAG.getConstant(0, DL, VT),
                    DAG.getConstant(0, DL, CarryVT));

This fixes some generally poor codegen for *mulo:

https://godbolt.org/z/eTxYsvz8f

Diff Detail

Event Timeline

paquette created this revision.Jan 31 2022, 10:55 AM
paquette requested review of this revision.Jan 31 2022, 10:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 31 2022, 10:55 AM
Herald added a subscriber: wdng. · View Herald Transcript
arsenm added inline comments.Jan 31 2022, 11:30 AM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
4598–4600

This query won't work correctly for vectors

paquette updated this revision to Diff 404652.Jan 31 2022, 11:54 AM

Check both G_BUILD_VECTOR and G_CONSTANT for vector types.

arsenm added inline comments.Jan 31 2022, 6:39 PM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
4600–4613

This condition is way too complicated and common to put here like this. We probably should have a predicate like isConstantUnsupported in the artifact combiner somewhere

foad added inline comments.Feb 1 2022, 2:22 AM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
4616

How does this work? Don't you need to build a single instruction that has two results (just like G_*MULO)?

paquette added inline comments.Feb 1 2022, 11:06 AM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
4600–4613

I tried to clean it up a bit in a follow up (D118655) but maybe the artifact combiner is a better place to handle it.

4616

I don't think it matters; although G_*MULO instructions produce two results, those results are just regular vregs. As long as they are still defined, the uses should work out.

So, we should be able to replace this with two instructions if we know what the results are going to be. In the case of

%mul, %o = G_*MULO %x, <zero>

We know that the value of %mul and %o must both be 0. So replacing them both with appropriately-sized 0s ought to be safe.

arsenm accepted this revision.Feb 1 2022, 6:22 PM
This revision is now accepted and ready to land.Feb 1 2022, 6:22 PM
This revision was landed with ongoing or failed builds.Feb 3 2022, 2:24 PM
This revision was automatically updated to reflect the committed changes.
foad added inline comments.Feb 4 2022, 12:19 AM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
4615

Can't you copy from the RHS of the mul here? And hence there should be no need to check legality for this constant?

4616

Oh yeah, sorry. I was forgetting that (unlike sdag) it is just writing to two vregs.