-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[RISCV] Use vleff's AVL when output VL doesn't dominate in RISCVVLOptimizer #156618
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
Conversation
…imizer If an instruction's demanded VL is a virtual register defined by a vleff instruction, it might not dominate and fail to have its VL reduced. In leiu of the output VL, we can try and use the AVL passed to the vleff itself since it will be at least greater than or equal the original VL. I tried to create an LLVM IR test for this in but didn't have any luck because the scheduler kept on moving the instruction past the vleff, so it always dominated. So I've just included some mir tests instead.
wangpc-pp
left a comment
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.
LGTM.
preames
left a comment
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.
LGTM
|
As a follow up, you could consider the same kind of logic as ensureDominates in RISCVVectorPeephole, or maybe rematerialization. |
| const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg()); | ||
| if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) && | ||
| !MDT->dominates(VLMI, &MI)) | ||
| CommonVL = VLMI->getOperand(4); |
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.
Is this the correct operand number for a masked fault only first load?
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.
No, fixed in 712d2fc
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.
Good catch.
|
@llvm/pr-subscribers-backend-risc-v Author: Luke Lau (lukel97) ChangesIf an instruction's demanded VL is a virtual register defined by a vleff instruction, it might not dominate and fail to have its VL reduced. In leiu of the output VL, we can try and use the AVL passed to the vleff itself since it will be at least greater than or equal the original VL. I tried to create an LLVM IR test for this in but didn't have any luck because the scheduler kept on moving the instruction past the vleff, so it always dominated. So I've just included some mir tests instead. Full diff: https://github.com/llvm/llvm-project/pull/156618.diff 2 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
index 9b70eb6c25b12..baf6aaac62779 100644
--- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
@@ -1464,6 +1464,15 @@ bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) const {
assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
"Expected VL to be an Imm or virtual Reg");
+ // If the VL is defined by a vleff that doesn't dominate MI, try using the
+ // vleff's AVL. It will be greater than or equal to the output VL.
+ if (CommonVL->isReg()) {
+ const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
+ if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) &&
+ !MDT->dominates(VLMI, &MI))
+ CommonVL = VLMI->getOperand(RISCVII::getVLOpNum(VLMI->getDesc()));
+ }
+
if (!RISCV::isVLKnownLE(*CommonVL, VLOp)) {
LLVM_DEBUG(dbgs() << " Abort due to CommonVL not <= VLOp.\n");
return false;
diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
index 60398cdf1db66..0acdca91ee84c 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt.mir
@@ -603,4 +603,61 @@ body: |
$x10 = COPY %9
PseudoRET implicit $x10
...
-
+---
+name: vleff_imm
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: vleff_imm
+ ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+ %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+ %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+ PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
+---
+name: vleff_reg_dominates
+body: |
+ bb.0:
+ liveins: $x8
+ ; CHECK-LABEL: name: vleff_reg_dominates
+ ; CHECK: liveins: $x8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
+ ; CHECK-NEXT: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+ %avl:gprnox0 = COPY $x8
+ %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+ %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+ PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
+---
+name: vleff_reg_doesnt_dominate
+body: |
+ bb.0:
+ liveins: $x8
+ ; CHECK-LABEL: name: vleff_reg_doesnt_dominate
+ ; CHECK: liveins: $x8
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: %avl:gprnox0 = COPY $x8
+ ; CHECK-NEXT: %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+ %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+ %avl:gprnox0 = COPY $x8
+ %y:vr, %vl:gprnox0 = PseudoVLE8FF_V_M1 $noreg, $noreg, %avl, 3 /* e8 */, 3 /* ta, ma */
+ PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
+---
+name: vleff_mask_imm
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: vleff_mask_imm
+ ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: %y:vrnov0, %vl:gprnox0 = PseudoVLE8FF_V_M1_MASK $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+ ; CHECK-NEXT: PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+ %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 3 /* ta, ma */
+ %y:vrnov0, %vl:gprnox0 = PseudoVLE8FF_V_M1_MASK $noreg, $noreg, $noreg, 1, 3 /* e8 */, 3 /* ta, ma */
+ PseudoVSE8_V_M1 %x, $noreg, %vl, 3 /* e8 */
+...
|
Is this in reference to #156639? |
Yep, wrong PR. |
topperc
left a comment
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.
LGTM
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/23648 Here is the relevant piece of the build log for the reference |
If an instruction's demanded VL is a virtual register defined by a vleff instruction, it might not dominate and fail to have its VL reduced.
In leiu of the output VL, we can try and use the AVL passed to the vleff itself since it will be at least greater than or equal the original VL.
I tried to create an LLVM IR test for this in but didn't have any luck because the scheduler kept on moving the instruction past the vleff, so it always dominated. So I've just included some mir tests instead.