Support signed multiplication
Support unsigned multiplication
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Now the tricky bit - hooking this into DAGCombiner and adding suitable testing.
visitMULO already has some specific case overflow detection code, so we can start by replacing it with a willNotOverflowMul test, similar to what visitADDO/visitSUBO do.
Make sure you create your diff with context: git diff HEAD~1 -U999999 > mypatch.patch
I used git blame on SelectionDAG.cpp and DAGCombiner.cpp and found that tests are in llvm/test/CodeGen/X86/xaluo.ll does this mean that I should modify xaluo.ll and xmulo.ll? am I even on the right track?
Why after the modification and before adding tests make check-llvm-codegen fails in or-with-overflow.ll and vec_smulo.ll
I discovered I should modify xmulo.ll, vec_smulo.ll and xaluo.ll.
@RKSimon I noticed that people add tests before code changes, why?
Can you help me with the tests? I really worked hard to understand how to write one, but no results.
I'd recommend starting with removing the existing code at the bottom of visitMULO that handles SMULO/UMULO -> MUL conversion and replacing it with a willNotOverflowMul check.
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
5442 | This i1 fold needs adding back? |
regarding test coverage - its ok to add tests in the patch to show the new coverage, once the patch is close to being accepted a reviewer might ask that the tests be pushed first so that the patch shows the codegen improvement.
Alternatively you can create a parent-child relationship between patches, but since LLVM is moving to github PRs this month I'd possibly recommend you just create a stacked PR instead
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | ||
---|---|---|
4055 | remove this and put it in its own patch with test coverage | |
4093 | remove this and put it in its own patch with test coverage | |
4103 | remove this and put it in its own patch with test coverage |
As I am a complete beginner with LLVM how can write tests? Is there any tutorial or example?
As I am a complete beginner with LLVM how can write tests? Is there any tutorial or example?
In this case the best reference tests are probably in combine-mulo.ll and xmulo.ll in the llvm-project/llvm/test/CodeGen/X86/ folder
I think you're only missing test coverage for the computeOverflowForSignedMul "SignBits == BitWidth + 1" knownbits cases.
You could investigate how InstCombine handles these cases - look inside llvm-project\llvm\test\Transforms\InstCombine for smul.overflow tests - you could try disabling the "SignBits == BitWidth + 1" handling in ValueTracking.cpp and then see which tests change/fail with ninja check-llvm-transforms-instcombine - you might then be able to convert some of those to combine-mulo.ll / xmulo.ll
What about the test coverage for the rest of the functions?
You could investigate how InstCombine handles these cases - look inside llvm-project\llvm\test\Transforms\InstCombine for smul.overflow tests - you could try disabling the "SignBits == BitWidth + 1" handling in ValueTracking.cpp and then see which tests change/fail with ninja check-llvm-transforms-instcombine - you might then be able to convert some of those to combine-mulo.ll / xmulo.ll
I think I will try this now
@RKSimon Hi I don't fully understand the testing infrastructure. I think I need some help.
for the following test:
%t = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 -256, i16 -128) %val = extractvalue {i16, i1} %t, 0 %obit = extractvalue {i16, i1} %t, 1 ret i1 %obit
This should be handled with "SignBits == BitWidth + 1", right?
how should I write this?
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
5441 | Isn't this a wrong formatting it becomes this every time I use git clang-format |
I've found an InstCombine patch which should handle the new smulo case and committed to the DAG codegen tests - please can you rebase on e086e0aeef6b and run ninja check-llvm-codegen-x86
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | ||
---|---|---|
5441 | It doesn't that pretty, you could refactor it slightly: if (IsSigned && VT.getScalarSizeInBits() == 1) { SDValue And = DAG.getNode(ISD::AND, DL, VT, N0, N1); SDValue Cmp = DAG.getSetCC(DL, CarryVT, And, DAG.getConstant(0, DL, VT), ISD::SETNE); return CombineTo(N, And, Cmp); } |
In fact, I found these tests in with_overflow.ll the first test. and I added it but I don't know why the code failed. even after rebasing the tests fail. and the tests pass if I remove the conditions.
I am sorry for bothering you, I know this is too much.
Maybe I should abandon the patch.
You're almost there - if you run ninja check-llvm-codegen you should only see 1 failure:
Failed Tests (1): LLVM :: CodeGen/X86/combine-mulo.ll
You can then regenerate that test file with the llvm-project\llvm\utils\update_llc_test_checks.py script:
cd llvm/test/CodeGen/X86 <pathto>\update_llc_test_checks.py --llc-binary=<pathto>\llc combine-mulo.ll
(replacing the pathto bits)
Thanks @elhewaty - are you intending to add the additional sub overflow tests and handling as well?
Yes, But I am working on the InstCombine patch as you know.
I don't mind working on as many patches as possible. I want to understand LLVM internals.
But I have some personal problems these days, but I can still work. If you don't mind I can work on
bugs at my own pace assign me to a bug and I will work on it.
This i1 fold needs adding back?