-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[GISel] Funnel shift combiner port from SelectionDAG ISel to GlobalISel #135132
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
733135e
2fc366c
ddf3bd1
59ab794
3e6e0ac
96b04fe
c929993
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,3 +105,53 @@ define i16 @test_shl_i48_2(i48 %x, i48 %y) { | |
%trunc = trunc i48 %shl to i16 | ||
ret i16 %trunc | ||
} | ||
|
||
define i16 @test_fshl_i32(i32 %x, i32 %_, i32 %y) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you create two commits for this PR: the first one contains only the new test functions you added (e.g. test_fshl_i32 here) but with CHECK lines showing the unoptimized assembly code. And the second commit being your changes, in which the CHECK lines are updated with optimized code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Woops! I apologize, I can't believe I forgot this.
I have pushed two commits following this style, although I'm probably going to have to do it again once I introduce vector tests, provide better names for the combiner and tests, and (hopefully) figure out what's causing the AArch64 fshr test to not trigger the combiner (I have a comment in another review thread in this PR noting that it's likely due to the OR instruction not matching if its operands are flipped which is strange since they should commute). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (not this patch) next time, you could make the first commit the pre-commit test, followed by your actual patch, such that you don't have to comment & un-comment like you did here. |
||
; RV32-LABEL: test_fshl_i32: | ||
; RV32: # %bb.0: | ||
; RV32-NEXT: not a3, a2 | ||
; RV32-NEXT: sll a0, a0, a2 | ||
; RV32-NEXT: srli a1, a1, 1 | ||
; RV32-NEXT: srl a1, a1, a3 | ||
; RV32-NEXT: or a0, a0, a1 | ||
; RV32-NEXT: ret | ||
; | ||
; RV64-LABEL: test_fshl_i32: | ||
; RV64: # %bb.0: | ||
; RV64-NEXT: not a3, a2 | ||
; RV64-NEXT: sllw a0, a0, a2 | ||
; RV64-NEXT: srliw a1, a1, 1 | ||
; RV64-NEXT: srlw a1, a1, a3 | ||
; RV64-NEXT: or a0, a0, a1 | ||
; RV64-NEXT: ret | ||
%fshl = call i32 @llvm.fshl.i32(i32 %x, i32 %_, i32 %y) | ||
%shl = shl i32 %x, %y | ||
%or = or i32 %fshl, %shl | ||
%trunc = trunc i32 %or to i16 | ||
ret i16 %trunc | ||
} | ||
|
||
define i16 @test_fshr_i32(i32 %_, i32 %x, i32 %y) { | ||
; RV32-LABEL: test_fshr_i32: | ||
; RV32: # %bb.0: | ||
; RV32-NEXT: not a3, a2 | ||
; RV32-NEXT: slli a0, a0, 1 | ||
; RV32-NEXT: sll a0, a0, a3 | ||
; RV32-NEXT: srl a1, a1, a2 | ||
; RV32-NEXT: or a0, a0, a1 | ||
; RV32-NEXT: ret | ||
; | ||
; RV64-LABEL: test_fshr_i32: | ||
; RV64: # %bb.0: | ||
; RV64-NEXT: not a3, a2 | ||
; RV64-NEXT: slli a0, a0, 1 | ||
; RV64-NEXT: sllw a0, a0, a3 | ||
; RV64-NEXT: srlw a1, a1, a2 | ||
; RV64-NEXT: or a0, a0, a1 | ||
; RV64-NEXT: ret | ||
%fshr = call i32 @llvm.fshr.i32(i32 %_, i32 %x, i32 %y) | ||
%lshr = lshr i32 %x, %y | ||
%or = or i32 %fshr, %lshr | ||
%trunc = trunc i32 %or to i16 | ||
ret i16 %trunc | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Vector version of tests? Also negative multi-use tests. Ideally would share the existing DAG combine tests here instead of creating new copies There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The issue I ran into has to do with the i48 type leading to a lot of code being generated to emulate
Is this referring to the fact that I'm truncating or something else? I apologize, I'm still getting a hang to contributing here (and thanks for reviewing my patch!)
Is there a common vector size that many contributors use for vector versions of tests? I'll make sure to implement that :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's going to be true in either case. As long as it actually compiles, it's not a problem and gives a point of reference for whenever the code improves for illegal types.
I mean where the intermediate instructions have unrelated uses and need to be emitted anyway
No, whatever is relevant for the target (you also wouldn't need to think too hard about that if reusing the original test, which I hope covers some vectors) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There aren't any vector tests here, but I'll gladly add some myself!
Before I go forward and introduce i48 funnel shift calls to the original tests (in order to also test for multi-use i.e. if it correctly ensures the intermediate instructions are still emitted), I want to further clarify what I meant. The following is a test that uses an i32 fshl and another test that uses an i48 fshl. The difference in generated code (via
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I don't think you have to test i48, which is an illegal type for RISC-V. Because the majority of the instructions you saw in i48's case are generated by the legalizer, which is unrelated to your patch here. So for the purpose of testing your pattern, it'll be more clear and succinct to only include legal types (i.e. i32 and i64)
I think this related to a check that is potentially missing from your pattern now: ideally, the pattern would replace three instructions
into just one:
But if
But as you might already notice, this "new" sequence of 3 instructions is nowhere better than the original sequence, which also have 3 instructions (in most architectures, G_FSHR will not be faster than G_OR). So in the case of Finally, a negative test is a test that makes sure your optimization does not trigger under certain conditions. In your case, it would be an input sequence with G_FSHR or G_LSHR that have more than one users, and the CHECK lines should pledge that they won't be optimized. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I apologize for my two week delay, I got severely sick in that time - I'm alright now though :) I have changed the combiner to check for I have left two of the original tests untouched and in their i48 form because they both include FIXME messages for the code that's generated. |
Uh oh!
There was an error while loading. Please reload this page.