This is an archive of the discontinued LLVM Phabricator instance.

[DAGCombine] (add/uaddo X, Carry) -> (addcarry X, 0, Carry)
ClosedPublic

Authored by deadalnix on May 5 2017, 3:18 PM.

Event Timeline

deadalnix created this revision.May 5 2017, 3:18 PM
deadalnix updated this revision to Diff 98231.May 8 2017, 4:32 PM

Rebase on changes from D32916 .

RKSimon added inline comments.May 19 2017, 6:50 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

As was discussed on D32916, the carry is a boolean that will respect TargetLowering::BooleanContent so we can't just accept any extension - it has to match the bool type.

test/CodeGen/X86/add-of-carry.ll
16

This is annoying....

deadalnix added inline comments.May 19 2017, 9:29 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

This just follow the chain to see if there is a carry generating ops at the end. This isn't generating anything, so I'm not sure what the problem is.

test/CodeGen/X86/add-of-carry.ll
16

I have a patch making this better. However, it has to be noted that this code is very unrepresentative from code in the field, as it essentially does a + b + carry(a, b) . This is fine to test this as it exercise edge cases, but if the tradeof is between that specific sample vs any actual sample code extracted from existing software (which I'm doing with this lagre int optimization serie) I'd rather go for the one that is actually used.

spatel added inline comments.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

In this case, we're taking a boolean carry value and using it as an operand for a new ADDCARRY node that has the same boolean content requirement, so I think this part is ok.

Given that it's not clear from reading the code, please add a comment to explain the logic.

cc'ing @efriedma in case he sees a hole in that reasoning.

1987

Shouldn't this be: "If this is *not* a use of a carry bit, return." ?

2047

Just looking at that transform formula, it's not clear to me why it makes sense. We're turning a simple op into a more complicated op and creating a new constant operand.

Is it because there will always be a trunc/extend/mask op sitting between the carry and the add? Should we check or assert that?

In the first test case, we're going to eventually fold the addcarry with 0 operand with a uaddo. Would it make sense to have that fold directly?

I don't have a sense of how these folds work together, so if we do need this more general fold, we should have a comment to explain why it is generally good.

efriedma added inline comments.May 25 2017, 12:28 PM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

"X + (sext Carry)" clearly produces a different result from "X + (zext carry)"; I can't see how it makes sense to ignore the difference.

spatel added inline comments.May 25 2017, 1:04 PM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

Ah, right. So yes, Simon's observation was correct. We need to match whatever this node is to the boolean content type.

So I think that's more reason to make specific folds for the actual patterns that are causing problems for this codegen.

deadalnix added inline comments.May 26 2017, 12:37 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

It has to match the bool type and this one is correct. But if the bool type isn't 1/0 the end result is different. We need to avoid matching SEXT and ANY_EXT here and validate that the flag is of the form 0/1 ot that a (and X, 1) is present along the way.

1987

Yes, you are correct. Fixing.

2047

In practice this is better. When taking the carry as an argument, it is necessary to materialize it, which takes a register and an instruction to copy the carry from the flag register to a general purpose register. On the other hand, when passing the carry down as carry, there are usually some predicated instruction that can be used.

In addition, there are various combine you can do on top of that form, for instance if X is (add A, B) you end up with (addcarry A, B, Carry) which is preferable.

deadalnix updated this revision to Diff 100370.May 26 2017, 1:00 AM

Do not match sext and any_ext as this is invalid.

efriedma added inline comments.May 26 2017, 11:16 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1985

and validate that the flag is of the form 0/1 ot that a (and X, 1) is present along the way.

I don't see any code in the current version to do this?

Check the kind of bool being generated as carry.

RKSimon added inline comments.May 30 2017, 3:44 AM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
1981
// First, peel away TRUNCATE/ZERO_EXTEND/AND nodes due to legalization.
2048

use SDValue not auto

2137

use SDValue not auto

RKSimon accepted this revision.Jun 1 2017, 2:29 AM

LGTM

This revision is now accepted and ready to land.Jun 1 2017, 2:29 AM
This revision was automatically updated to reflect the committed changes.