-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
[IR] [lang] Support SHR operator: ti.bit_shr(x, y) #1871
Conversation
assert shr(test_num, i) == 2**(n - i) | ||
for i in range(n): | ||
offset = 0x100000000 if i > 0 else 0 | ||
assert shr(neg_test_num, i) == (neg_test_num + offset) >> i |
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 test will fail on backends other than LLVM due to unimplemented op.
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 includes(but not limited to...) cc, metal and opengl.
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.
Nice catch... I believe on these backends SHR is not implemented (but SAR is). How about this: let's demote bit_shr
into a series of three operations
UnaryOpStmt
bit_cast
into unsignedBinaryOpStmt
bit_sar
UnaryOpStmt
bit_cast
into signed
in this pass
void visit(BinaryOpStmt *stmt) override { |
So that backend developers don't need to worry about SAR. This is a very late pass in the compilation process - we still need SAR in the IR for certain domain-specific optimizations.
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.
So that backend developers don't need to worry about SAR. This is a very late pass in the compilation process - we still need SAR in the IR for certain domain-specific optimizations.
Good idea! I'll later add uint support to OpenGL so that SHR works.
EDIT: So bit_sar
should act as SHR when operand is uint to make this method work?
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.
@archibate That's what I'd also like to discuss. I did some experiments, in the LLVM backend, bit_sar
is implemented using CreateAShr
which simply copies the MSB without considering the type. While on other backends, bit_sar
is expressed with >>
which will behave differently according to unsigned/signed information. I think we need to decide which kind of SAR operation we truly want, either a pure one copying the MSB or a one that is more similar to the >>
in C.
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.
Thanks for all the discussions. My two cents:
- In the frontend
>>
always translates toBinaryOpType::bit_sar
andti.bit_shr
always translates toBinaryOpType::bit_shr
. - In
demote_operations.cpp
we convertbit_shr
on signed integers into three sub-operations as discussed above. Then we only havebit_sar
for the backend. - In the backend, since we only have
bit_sar
, its behavior is determined by the type of its operands.
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.
@yuanming-hu Thanks for the clarification.
The point(or problem) I'd like to discuss is the behavior of bit_sar
which bit_shr
will eventually rely on. As I wrote in the above comment, in the LLVM backend, bit_sar
is implemented with a CreateAShr
which directly maps to a sar
instruction and simply copies the MSB, that is, it will ignore the type information so casting signed to unsigned will not work since the low-level bits are not changed by type casts. In other backends (at least Metal), bit_sar
is implemented using the operator >>
, which will consider the type information, that is, it will map to a zext
and sar
when working on unsigned integers. This is creating different behaviors across backends. We should first decide what kind of behavior we want for bit_sar
before we move on.
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.
Let's follow the Metal behavior bit_sar
in backends. And provide bit_shr
using demote_operations
as described above.
The LLVM backend should do some branches to match the behavior of Metal, e.g.:
// on bit_sar
if (dtype == unsigned) {
CreateAShr();
} else {
CreateLShr();
}
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.
Perhaps one source of confusion is that LLVM doesn't distinguish signed/unsigned integers (so does hardware such x64). So SHR
always shifts everything and SAR
copies the MSB in LLVM.
In Taichi, on unsigned integers bit_shr=bit_sar
and they both map to SHR
in LLVM. On signed integers, bit_shr
maps to SHR
in LLVM and bit_sar
maps to SAR
in LLVM.
Codecov Report
@@ Coverage Diff @@
## master #1871 +/- ##
==========================================
+ Coverage 43.15% 43.80% +0.65%
==========================================
Files 44 45 +1
Lines 6271 6171 -100
Branches 1084 1097 +13
==========================================
- Hits 2706 2703 -3
+ Misses 3395 3299 -96
+ Partials 170 169 -1
Continue to review full report at Codecov.
|
I've rerun the workflow for 0ff726d and it's passed. |
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.
Hi, thanks a lot for your great work. Most of your code is nice and clean. I only have two advice and wrote them above. : )
Co-authored-by: Jiafeng Liu <jiafengliu@zju.edu.cn>
Co-authored-by: Jiafeng Liu <jiafengliu@zju.edu.cn>
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.
Great! Thanks very much for your great work. I learnt a lot from your code and discussion. I think we can merge this pr now!
Related issue = #
Since
>>
is already used by SAR, SHR is implemented as a function instead of a binary op.[Click here for the format server]