This patch allows for expansion of ADDCARRY and SUBCARRY when the target does not support it.
Details
- Reviewers
RKSimon efriedma - Commits
- rZORG084f2b201b00: [SelectionDAG] Expand ADD/SUBCARRY
rZORG3e2cef471286: [SelectionDAG] Expand ADD/SUBCARRY
rG084f2b201b00: [SelectionDAG] Expand ADD/SUBCARRY
rG3e2cef471286: [SelectionDAG] Expand ADD/SUBCARRY
rG95b7abdcc5be: [SelectionDAG] Expand ADD/SUBCARRY
rL360303: [SelectionDAG] Expand ADD/SUBCARRY
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3300 | Are you sure this is right? The comment is correct, but there's only an overflow if the carry is set and the result is zero. |
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3300 | My bad, you're right. Updated. |
LGTM
Please run some basic sanity tests before you merge to make sure this works correctly at runtime. The code looks right, but I don't really trust that. :) If you want to test something simpler than smul.fix, might make sense to just temporarily hack legalization for addition to use this codepath, or something like that, so you can easily understand what you're actually testing.
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3300 | Looks okay now. |
Good thing I checked! I did as you suggested by forcing 32bit x86 to take this path and found a bunch of type mismatches. After fixing that, everything looks good for expected results. Will submit tomorrow morning if there aren't any more comments then.
llvm/test/CodeGen/SPARC/addcarry.ll | ||
---|---|---|
3 | SPARC is probably not a great example, because it can support ADDCARRY fine, only nobody implemented it yet (just the deprecated ADDC/ADDE). RISCV would be a better test-case, because it actually doesn't have an overflow flag at all. |
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3292 | Looking at this again, it isn't quite right. In general, on targets where getBooleanContents does not return ZeroOrOneBooleanContent, you need to getZeroExtendInReg to convert a carry bit to 1/0. |
llvm/test/CodeGen/SPARC/addcarry.ll | ||
---|---|---|
3 | So I'm having trouble figuring out how to properly test this since RISCV also doesn't seem to support the MUL_LOHI ISDs and I don't know other ways to invoke usage of ISD::ADDCARRY other than through expandMUL_LOHI. Do you think it would be fine if I also added an intrinsic like llvm.addcarry for explicitly expanding to ISD::ADDCARRY so I could test this directly? |
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3292 | I think you need both the getZExtOrTrunc to fix the type, and the getZeroExtendInReg to fix the value. (getZeroExtendInReg just produces an ISD::AND.) |
llvm/test/CodeGen/SPARC/addcarry.ll | ||
---|---|---|
3 | Try "llc -mtriple=riscv32 -mattr=+m"? |
llvm/test/CodeGen/SPARC/addcarry.ll | ||
---|---|---|
3 | This works well. Didn't know about this beforehand. Thanks. |
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3293 | The VT argument for getZeroExtendInReg is the mask, so should be MVT::i1. The way it's written, the getZeroExtendInReg does nothing. |
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3293 | Updated |
LGTM with a minor comment.
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | ||
---|---|---|
3312 | Shouldn't matter in practice, but the second type passed to getBoolExtOrTrunc is supposed to be the type of the operation ("VT"). |
Looking at this again, it isn't quite right. In general, on targets where getBooleanContents does not return ZeroOrOneBooleanContent, you need to getZeroExtendInReg to convert a carry bit to 1/0.