This pattern is no very useful per se, but it exposes optimization for toehr patterns that wouldn't kick in otherwize. It's very common and worth optimizing for.
Details
Diff Detail
- Build Status
Buildable 6061 Build 6061: arc lint + arc unit
Event Timeline
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2171 | This comment really isn't any use to explain what is happening here - it needs a much better explanation. AFAICT you are saying that if (A+B) overflows then the carry can only occur in the second operand, else if (A+B) doesn't overflow it might occur in the third (carry) operand after the additional add? Can carries ever occur in both? e.g. Is addcarry/uaddo supposed to accept for i1/i2 types? |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2171 | That is the idea. If A + B overflows, then Y + [0 or 1] cannot overflow. As a result, you can combine the two carries into one by doing A + B + [0 or 1]. This holds true even for types like i1, however, addcarry are generated by the legalization code, so you shouldn't get i1 in there anyway. This transform a diamond pattern into the carry chain into a linear carry chain, and then other existing optimizations can kick in. |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2177 | I like the ascii art! I'm still not very familiar with the carry ops, so I would've kept the formulas from the previous rev in here too. This is complicated enough that I think it's justified to have both. But I have a question about this node: (addcarry 0, 0, *) |
You should probably also mention the PR number on the commit message.
Does this trigger often, btw?
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2190 | Shouldn't we allow both (addcarry *, 0, Z) and (addcarry 0, *, Z)? |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2190 | Should take care of the final addcarry, yes. But it's still missing the one above (*+0+Z), no? |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2177 | So i played a bit with it, and as it turns out, it makes some things worse, other better. I still think this is useful, we just need to add a few patterns to get things back to normal after the fact, like promoting uaddo into addcarry when one of the parameter actually comes from a carry. |
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2190 | Constants are canonicalized on the RHS so it's fine. |
Doing some refactoring to help the introduction of further diamond pattern simplification.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
2187 | Sounds like a good idea. i don't think we generate such a code ever, but better safe than sorry. |
This comment really isn't any use to explain what is happening here - it needs a much better explanation.
AFAICT you are saying that if (A+B) overflows then the carry can only occur in the second operand, else if (A+B) doesn't overflow it might occur in the third (carry) operand after the additional add? Can carries ever occur in both? e.g. Is addcarry/uaddo supposed to accept for i1/i2 types?