The Hexagon backend had these recognized in selection patterns. Make the combiner get them instead. One case was already covered, but it failed when the XOR operands were switched.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
The subtract version was noted in PR36036:
https://bugs.llvm.org/show_bug.cgi?id=36036
And as commented there, we're now canonicalizing in IR to the form with select:
D40984
And there were more IR improvements for abs() here:
D47041
D47076
D47631
...so can we add the IR canonicalization for the subtract version (solve PR36036) and be done with this? Ie, can we already remove the DAG combine for the half-implemented 'add' version because we're confident that IR is now always going to be in the canonical 'select' form? Is there some place in the DAG that creates abs() in a non-canonical form?
While I remember ValueTracking matches SPF_ABS/SPF_NABS selection style patterns - but SelectionDAGBuilder::visitSelect still doesn't support SPF_ABS/SPF_NABS which prevents it being used
There are functions in test/CodeGen/Hexagon/abs.ll that will fail without the changes in visitXOR (the "add" pattern).
I see what you mean... Adding the sub variant to instcombine, not dagcombine, and deleting all abs from dagcombine. Yes, that should work.
Great - I'll add that (simple translation of D40984) if you're not already doing it.
I think nobody is ever quite sure when the IR improvements allow us to remove DAG folds, so we end up with largely dead code in the backend.
But Simon raises a point that has come up before - we should be producing ABS nodes in SelectionDAGBuilder similar to how we already produce MIN/MAX. We'll want to do that before deleting any DAGCombiner code.
Is is possible to end up with the abs patterns after simplifying/legalizing an existing DAG, without having them exposed in the IR earlier on?
I can't rule it out completely, but that seems very unlikely given that we have a generic ABS node. Some set of smaller DAG transforms would have to unknowingly produce the shift+xor+add/sub instructions independently without realizing it has created the larger ABS node?
Yes, that's what I meant. I've seen a similar kind of behavior before (different operations though). I can try to create a testcase that shows that. Is this simply something that we assume could happen and have to live with?
No, if it's likely, then we should have a DAGCombine for it. We want the IR canonicalization regardless of that though, so I'll work on the InstCombine patch.
Here's the instcombine patch:
rL334137
If we want to keep going with a DAG patch, we'll need codegen tests. A basic x86 example is shown in PR36036.
A more involved case with multiple uses of the intermediate values would thwart the IR transform, so that would be a good test for either this patch or the value tracking + SelectionDAGBuilder suggestion.
Codegen tests already exist: test/CodeGen/Hexagon/abs.ll. That testcase used to rely on Hexagon-specific selection patterns, which this patch removes.
Added a check for reversed order of add operands.
Added a test with multiple uses of the sign bit copy, and with the order of add's operands reversed.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
5655 | I actually removed them for clarity (I forgot about the "sub" case)... | |
lib/Target/ARM/ARMInstrNEON.td | ||
5399 ↗ | (On Diff #150353) | test/CodeGen/ARM/neon_vabs.ll failed without those. I think the patterns above it will no longer be triggered actually, but I didn't want to remove them. |
lib/Target/ARM/ARMInstrNEON.td | ||
---|---|---|
5399 ↗ | (On Diff #150353) | The new patterns look fine; please delete the old patterns. |
Removed unnecessary patterns from ARMInstrNEON.td, changed the SUB pattern to recognize XOR operands in reversed order.
lib/Target/ARM/ARMInstrNEON.td | ||
---|---|---|
5400 ↗ | (On Diff #150941) | This should say VABDL, not VABD. I'll fix it before commit. |
Brackets for clarity : (OpSizeInBits - 1)