This is an archive of the discontinued LLVM Phabricator instance.

[MLIR][SPIRV] Add a canonicalization pattern for UModOp
ClosedPublic

Authored by nbpatel on Jun 6 2023, 10:48 PM.

Details

Summary

Add a transformation for a pattern like

%6 = "spirv.Constant"() <{value = 32 : i32}> : () -> i32
%7 = "spirv.UMod"(%5, %6) : (i32, i32) -> i32
%8 = "spirv.Constant"() <{value = 4 : i32}> : () -> i32
%9 = "spirv.UMod"(%7, %8) : (i32, i32) -> i32

to transform to

%6 = "spirv.Constant"() <{value = 32 : i32}> : () -> i32
%7 = "spirv.UMod"(%5, %6) : (i32, i32) -> i32
%8 = "spirv.Constant"() <{value = 4 : i32}> : () -> i32
%9= "spirv.UMod"(%5, %8) : (i32, i32) -> i32

Diff Detail

Event Timeline

nbpatel created this revision.Jun 6 2023, 10:48 PM
Herald added a reviewer: kuhar. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
nbpatel requested review of this revision.Jun 6 2023, 10:48 PM
nbpatel edited the summary of this revision. (Show Details)Jun 6 2023, 10:50 PM
nbpatel updated this revision to Diff 529199.Jun 7 2023, 12:23 AM
nbpatel edited the summary of this revision. (Show Details)Jun 7 2023, 12:43 AM
kuhar added a comment.Jun 7 2023, 8:10 AM

Thanks for coming up with this canon pattern, @nbpatel. I left some suggestions but overall this looks like a useful pattern to me. I have two high-level questions:

  1. Have you tried defining it in DDR instead (SPIRVCanonicalization.td)? The implementation may be simpler and more concise there.
  1. Do you see pattern show up a lot in your IR? What do you think about adding it on the level of the Arith dialect instead/in addition?
mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp
128

nit: transformation works only if --> the transformation is only applied when?
'works only if' could be interpreted as the transformation being broken or incomplete

130–132

nit: drop this repeated header

134–135

Could you update pattern to the same style as the other patterns in this file? EG:

struct CombineChainedAccessChain final
    : OpRewritePattern<spirv::AccessChainOp> {
  using OpRewritePattern::OpRewritePattern;

This is to maintain consistency.

139–140

We can combine these two:

auto prevUMod = umodOp.getOperand(0).getDefiningOp<spirv::UModOp>();
145–146

Match with m_Constant instead

147

same here

152–153
  1. Member cast functions are deprecated, use free functions instead: https://mlir.llvm.org/deprecation/
  2. Could the value be a vector type?
162–164

Use rewriter.replaceOpWithNewOp

mlir/test/Dialect/SPIRV/Transforms/canonicalize.mlir
483–484

Can we also check that the expected values were indeed returned? Also in the previous testcase

487–488

I think it would help to have 2 more tests:

  1. For when the transformation does not apply because of the divisors not being multiples
  2. Check that the pattern handles vectors of integers.
nbpatel updated this revision to Diff 529334.Jun 7 2023, 9:17 AM
nbpatel marked 7 inline comments as done.

Address PR feedback.

Yes, we do see a lot of such code in our IR and we would want to clean it up a bit for easier readability and debug.

I haven't tried it with vector

nbpatel marked 2 inline comments as done.Jun 7 2023, 9:17 AM

@kuhar do we need to handle vectors in this PR? can it be an incremental PR?
I am not sure how complex/simple the change will be for handling vectors

kuhar added a comment.Jun 7 2023, 12:31 PM

Thanks for all the fixes.

@kuhar do we need to handle vectors in this PR? can it be an incremental PR?
I am not sure how complex/simple the change will be for handling vectors

In the previous iteration the code would crash on vectors because of casts. Now I think it will bail out:

IntegerAttr prevValue, currValue;
if (!matchPattern(prevUMod.getOperand(1), m_Constant(&prevValue)) ||
    !matchPattern(umodOp.getOperand(1), m_Constant(&currValue)))
  return failure();

Supporting vectors should be easy, so I think it makes sense to handle it in this PR. You can find examples of similar canon patterns in ArithOps.cpp. If you decide not to do that, this deserves a testcase and a TODO at the very least.

mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp
139

nit: don't define multiple variables in the same statement

155–158

This should require only one new UMod op, no? In the example on top of the function only the second one is changed.

nbpatel updated this revision to Diff 529420.Jun 7 2023, 1:37 PM

Made requested changes and added a TODO.

kuhar added inline comments.Jun 7 2023, 1:40 PM
mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp
130

Can you open a github issue, tag it with [mlir][spirv] and add the link inside TODO(link). This makes keeping track of unresolved issues much easier.

kuhar accepted this revision.Jun 7 2023, 1:45 PM

Have you also seen something something like:
a = umod x, C1
b = umod a, C2
where C1 < C2?

I wonder if we should also support that and fold to b ==> a. This is separate but I'm curious if it shows up in your code.

For this PR, LGTM modulo the last comment. @antiagainst, could you also take a look?

This revision is now accepted and ready to land.Jun 7 2023, 1:45 PM

Thanks @kuhar for reviewing and accepting the change. Can you also please help in merging it since I dont have permission to do so?

nbpatel updated this revision to Diff 529428.Jun 7 2023, 1:53 PM

added the link for TODO

kuhar added inline comments.Jun 7 2023, 1:56 PM
mlir/lib/Dialect/SPIRV/IR/SPIRVCanonicalization.cpp
130

No , haven't seen this pattern show up. But it would be a good add.

Have you also seen something something like:
a = umod x, C1
b = umod a, C2
where C1 < C2?

I wonder if we should also support that and fold to b ==> a. This is separate but I'm curious if it shows up in your code.

For this PR, LGTM modulo the last comment. @antiagainst, could you also take a look?

kuhar added a comment.Jun 7 2023, 2:02 PM

Thanks @kuhar for reviewing and accepting the change. Can you also please help in merging it since I dont have permission to do so?

Yeah I will do that once @antiagainst gives it a thumbs up.

nbpatel updated this revision to Diff 529433.Jun 7 2023, 2:04 PM
antiagainst accepted this revision.Jun 7 2023, 8:41 PM

Name: Nishant Patel
Email: nishant.b.patel@intel.com

Information for merging.

This revision was landed with ongoing or failed builds.Jun 8 2023, 7:34 AM
This revision was automatically updated to reflect the committed changes.