-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[DAGCombiner] Use generalized pattern matcher in foldBoolSelectToLogic #79101
Conversation
@llvm/pr-subscribers-llvm-selectiondag @llvm/pr-subscribers-backend-risc-v Author: Liao Chunyu (ChunyuLiao) ChangesCombine: td: Full diff: https://github.com/llvm/llvm-project/pull/79101.diff 3 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 76e8d21b818b259..cd8ced502e8bf3b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -15621,6 +15621,32 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
}
break;
}
+ case RISCVISD::VMAND_VL: {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ if (isNullOrNullSplat(N0))
+ return N0;
+ else if (isNullOrNullSplat(N1))
+ return N1;
+ else if (isOneOrOneSplat(N0))
+ return N1;
+ else if (isOneOrOneSplat(N1))
+ return N0;
+ break;
+ }
+ case RISCVISD::VMOR_VL: {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ if (isNullOrNullSplat(N1))
+ return N0;
+ else if (isNullOrNullSplat(N0))
+ return N1;
+ else if (isOneOrOneSplat(N0))
+ return N0;
+ else if (isOneOrOneSplat(N1))
+ return N1;
+ break;
+ }
case ISD::SRA:
if (SDValue V = performSRACombine(N, DAG, Subtarget))
return V;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
index 6e7be2647e8f838..1f0a7d2e4fd752e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
@@ -2736,6 +2736,11 @@ foreach mti = AllMasks in {
VLOpFrag)),
(!cast<Instruction>("PseudoVMANDN_MM_" # mti.LMul.MX)
VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
+ def : Pat<(mti.Mask (riscv_vmor_vl (riscv_vmand_vl VR:$rs1, VR:$rs2, VLOpFrag),
+ (riscv_vmnot_vl VR:$rs2, VLOpFrag),
+ VLOpFrag)),
+ (!cast<Instruction>("PseudoVMORN_MM_" # mti.LMul.MX)
+ VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>;
def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1,
(riscv_vmnot_vl VR:$rs2, VLOpFrag),
VLOpFrag)),
diff --git a/llvm/test/CodeGen/RISCV/rvv/vselect-vp.ll b/llvm/test/CodeGen/RISCV/rvv/vselect-vp.ll
index 9e7df5eab8dda98..72749368cc07e28 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vselect-vp.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vselect-vp.ll
@@ -745,3 +745,23 @@ define <vscale x 16 x double> @select_nxv16f64(<vscale x 16 x i1> %a, <vscale x
%v = call <vscale x 16 x double> @llvm.vp.select.nxv16f64(<vscale x 16 x i1> %a, <vscale x 16 x double> %b, <vscale x 16 x double> %c, i32 %evl)
ret <vscale x 16 x double> %v
}
+
+define <vscale x 2 x i1> @select_zero(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) {
+; CHECK-LABEL: select_zero:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
+; CHECK-NEXT: vmand.mm v0, v8, v0
+; CHECK-NEXT: ret
+ %a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> zeroinitializer, i32 %evl)
+ ret <vscale x 2 x i1> %a
+}
+
+define <vscale x 2 x i1> @select_one(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) {
+; CHECK-LABEL: select_one:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma
+; CHECK-NEXT: vmorn.mm v0, v8, v0
+; CHECK-NEXT: ret
+ %a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer), i32 %evl)
+ ret <vscale x 2 x i1> %a
+}
|
Isn't this a missed optimization on vp.select? Can we fix it there? |
7a0b85b
to
4bc96cb
Compare
; CHECK-NEXT: vsetvli zero, a0, e8, mf4, ta, ma | ||
; CHECK-NEXT: vmor.mm v0, v0, v8 | ||
; CHECK-NEXT: ret | ||
%a = call <vscale x 2 x i1> @llvm.vp.select.nxv2i1(<vscale x 2 x i1> %x, <vscale x 2 x i1> shufflevector (<vscale x 2 x i1> insertelement (<vscale x 2 x i1> undef, i1 true, i32 0), <vscale x 2 x i1> undef, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x i1> %y, i32 %evl) |
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.
number on the left I'm not sure it's generic
- If it's not a generic case then the example can be removed
- If it is generic, then it can be optimized again
} | ||
} | ||
return SDValue(); | ||
} |
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 it possible to make this target agnostic and do this in DAGCombiner.cpp?
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 agree that would be better.
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.
Or in InstCombine? I remember that we have plan to extend InstCombine to handle VP intrinsics: https://llvm.org/docs/Proposals/VectorPredication.html#lift-instsimplify-instcombine-dagcombiner-to-vp
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.
Or in InstCombine? I remember that we have plan to extend InstCombine to handle VP intrinsics: https://llvm.org/docs/Proposals/VectorPredication.html#lift-instsimplify-instcombine-dagcombiner-to-vp
We can't do it in InstCombine. Select blocks poison propagation, but and/or does not.
SelectionDAG is kind of bad about handling poison correctly. It already does this transform for ISD::VSELECT so doing it for VP_SELECT isn't any worse.
4bc96cb
to
4d2fa25
Compare
@@ -12138,6 +12144,13 @@ SDValue DAGCombiner::foldVSelectOfConstants(SDNode *N) { | |||
return SDValue(); | |||
} | |||
|
|||
SDValue DAGCombiner::visitVP_SELECT(SDNode *N) { | |||
if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DAG)) |
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.
Shouldn't this be VPMatchContext
?
define <vscale x 2 x i1> @select_zero(<vscale x 2 x i1> %x, <vscale x 2 x i1> %y, <vscale x 2 x i1> %m, i32 zeroext %evl) { | ||
; CHECK-LABEL: select_zero: | ||
; CHECK: # %bb.0: | ||
; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, ma |
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 doesn't seem to be applying the VL
4d2fa25
to
32568eb
Compare
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
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
support vp.select TODO: Possibly other functions could be supported, eg: SimplifySelect()
32568eb
to
6c0a7a8
Compare
Hi all, This patch is a follow-up of #79101. It migrates logic from `visitVSELECT` to `visitVP_SELECT` to simplify `vp.select`. With this patch we can do the following combinations: ``` vp.select undef, T, F --> T (if T is a constant), F otherwise vp.select <condition>, undef, F --> F vp.select <condition>, T, undef --> T vp.select false, T, F --> F vp.select <condition>, T, T --> T ``` I'm a total newbie to llvm and I'm sure there's room for improvements in this patch. Please let me know if you have any advice. Thank you in advance!
support vp.select
TODO: Possibly other functions could be supported, eg: SimplifySelect()