This is an archive of the discontinued LLVM Phabricator instance.

[SelectionDAG] Add computeOverflowForSignedMul / computeOverflowForUnsignedMul overflow handlers
ClosedPublic

Authored by elhewaty on Sep 2 2023, 3:00 PM.

Details

Summary

Support signed multiplication
Support unsigned multiplication

Diff Detail

Event Timeline

elhewaty created this revision.Sep 2 2023, 3:00 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 2 2023, 3:00 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
elhewaty requested review of this revision.Sep 2 2023, 3:00 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 2 2023, 3:00 PM

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

This comment was removed by elhewaty.
This comment was removed by elhewaty.
elhewaty added a comment.EditedSep 3 2023, 12:41 PM

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.

I already did this.

Please can you update the diff?

elhewaty updated this revision to Diff 555683.Sep 4 2023, 1:35 AM
RKSimon added inline comments.Sep 4 2023, 3:48 AM
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

I will update the patch and upload it now

As I am a complete beginner with LLVM how can write tests? Is there any tutorial or example?

elhewaty updated this revision to Diff 555708.Sep 4 2023, 4:58 AM
RKSimon added inline comments.Sep 4 2023, 8:01 AM
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
4058

leading zeros -> sign bits.

4060

leading zeros -> sign bits.

elhewaty updated this revision to Diff 555755.Sep 4 2023, 8:12 AM
elhewaty marked 4 inline comments as done.

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

elhewaty marked 2 inline comments as done.Sep 4 2023, 8:22 AM

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.

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);
  }
elhewaty updated this revision to Diff 555953.EditedSep 5 2023, 4:23 PM
elhewaty marked an inline comment as done.

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)

elhewaty updated this revision to Diff 555998.Sep 6 2023, 3:30 AM
RKSimon retitled this revision from [SelectionDAG] Generalise SelectionDAG::computeOverflowKind to support other opcodes to [SelectionDAG] Add computeOverflowForSignedMul / computeOverflowForUnsignedMul overflow handlers.Sep 6 2023, 4:46 AM
RKSimon set the repository for this revision to rG LLVM Github Monorepo.
RKSimon accepted this revision.Sep 6 2023, 11:01 AM

LGTM cheers - if you send me your full name / email address I'll commit it for you

This revision is now accepted and ready to land.Sep 6 2023, 11:01 AM

Mohamed Atef <mohamedatef1698@gmail.com >

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.

Thanks @elhewaty - also please can you submit any future patches as github PRs?

Ok, I will.