-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR][CIRGen][builtin] handle __lzcnt
#1382
base: main
Are you sure you want to change the base?
Conversation
Have you considered updating the existing |
@@ -1714,6 +1714,30 @@ def BitPopcountOp | |||
}]; | |||
} | |||
|
|||
def BitLzcntOp : CIR_BitOp<"bit.lzcnt", AnyTypeOf<[UInt16, UInt32, UInt64]>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can share a tablegen class with BitPopcountOp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why BitPopcount
? Do you mean BitClzOp
? The reason is their different poison bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was actually curious if you could reuse the CIR_BitOp
if you make it a bit more generic.
0e571e7
to
17557ab
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
The new LzcntOp doesn't inherent BitOp. So, I can avoid touching original code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still unclear about why we don't just update cir.bit.clz
for __lzcnt
. AFAIK, we may have two problems in doing so:
- The result type of
cir.bit.clz
is fixed to be!s32i
. Have you tried update the TableGen definition ofcir.bit.clz
so you could relax this constraint? cir.bit.clz
would invoke undefined behaviors if the operand is 0. To overcome this, we could add aUnitAttr
to the parameters ofcir.bit.clz
that indicates whether the operation should poison an input value of 0. Have you tried this?
Are there any other concerns I'm missing here?
Compute the number of leading 0-bits in the input. | ||
|
||
The input integer must be an unsigned integer. The `cir.bit.lzcnt` operation | ||
returns the number of consecutive 0-bits at the most significant bit | ||
position in the input. | ||
|
||
If the input value is 0, the return value is the size of the input value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some more description about the differences between the cir.bit.clz
operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, that'd be great
+1 on all comments from @Lancern |
@Lancern @bcardosolopes Thanks for your review. I'm going to make some changes. First, changing the return type of |
2d8eca3
to
0fbbce2
Compare
I have reworked the patch. Creating a base class for |
I also noticed that MLIR LLVMIR doesn't require |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another round of review! Some comments inline.
|
||
let assemblyFormat = [{ | ||
`(` $input `:` type($input) `)` `:` type($result) attr-dict | ||
}]; | ||
} | ||
|
||
class CIR_CountZerosBitOp<string mnemonic, TypeConstraint inputTy> | ||
: CIR_BitOp<mnemonic, inputTy> { | ||
let arguments = (ins inputTy:$input, I1Attr:$is_zero_poison); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not use I1Attr
; use UnitAttr
instead. Then use optional groups in the assembly format for is_zero_poison
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use I1Attr
here to be consist with MLIR
I1Attr:$is_zero_poison); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe CIR always uses UnitAttr
for representing boolean flags.
0fbbce2
to
445b348
Compare
Traditional clang implementation:
clangir/clang/lib/CodeGen/CGBuiltin.cpp
Lines 3618 to 3632 in a1ab6bf
The problem here is that
__builtin_clz
allows undefined result, while__lzcnt
doesn't. As a result, I have to create a new CIR for__lzcnt
. Since the return type of those two builtin differs, I decided to change return type of currentCIR_BitOp
to allow newCIR_LzcntOp
to inherit from it.I would like to hear your suggestions. C.c. @Lancern