The combiner transforms (shl X, 1) into (add X, X).
Details
Diff Detail
- Repository
- rL LLVM
- Build Status
Buildable 37440 Build 37439: arc lint + arc unit
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 | 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 | ||
---|---|---|
6033 | I suppose add v v implies that c can only be bitwidth-1 |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
6111 | Hm, this function already handles non-shifts. |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
6111 | The whole function is about reconstructing shifts from something else. |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
6111 | duh? |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
6136 | 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 | ||
---|---|---|
6136 | 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. |
Is there any easy way that we can avoid creating nodes like this? Its purpose seems purely to be matched again later.