The combiner transforms (shl X, 1) into (add X, X).
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Pattern look good to me, but i recall having disscussion in https://reviews.llvm.org/D64275#inline-576684
Granted, that is InstCombine, but what happens here if we create instruction but then fail to fold?
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6019 ↗ | (On Diff #217639) | Is there any easy way that we can avoid creating nodes like this? Its purpose seems purely to be matched again later. |
The node created this way end up added to PruningList by WorklistInserter are are removed when poping the next element from the worklist in clearAddedDanglingWorklistEntries.
@RKSimon Let me try that. This will require to refactor MatchRotate quite a bit, but it may be possible.
I looked at the problem that @spatel ran into. It is not applicable to DAGCombiner, because the DAG is processed only once rather than in a loop as long as it is modified. I wouldn't be possible to change it to work like InstCombine does as there are a ton of A -> B -> A type of tranforms. That being said, it's not a good reason to add more, so it's worth looking into improving this if possible.
Precommit tests pls.
Please add commutative test - or is commutative.
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6026 ↗ | (On Diff #217916) | I suppose add v v implies that c can only be bitwidth-1 |
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6120 ↗ | (On Diff #218088) | Hm, this function already handles non-shifts. |
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6120 ↗ | (On Diff #218088) | The whole function is about reconstructing shifts from something else. |
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6120 ↗ | (On Diff #218088) | duh? |
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6145 ↗ | (On Diff #218088) | Err, this is actually exactly what i'm saying :) // Value and Type of the shift.
SDValue OppShiftLHS = OppShift.getOperand(0);
EVT ShiftedVT = OppShiftLHS.getValueType();
// Amount of the existing shift.
ConstantSDNode *OppShiftCst = isConstOrConstSplat(OppShift.getOperand(1));
// (add v v) -> (shl v 1)
if (OppShift.getOpcode() == ISD::SRL && OppShiftCst &&
ExtractFrom.getOpcode() == ISD::ADD &&
ExtractFrom.getOperand(0) == ExtractFrom.getOperand(1) &&
ExtractFrom.getOperand(0) == OppShiftLHS &&
OppShiftCst->getAPIntValue() == ShiftedVT.getScalarSizeInBits() - 1)
return DAG.getNode(ISD::SHL, DL, ShiftedVT, OppShiftLHS,
DAG.getShiftAmountConstant(1, ShiftedVT, DL));is the simplest solution here, or the code that is located later in the function |
| lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
|---|---|---|
| 6145 ↗ | (On Diff #218088) | The code is written in a style where it bail when something is wrong. As a result it either need to be rewritten, or new patterns need to be added early on. Sorry for not understanding what you were hinting at before. |