-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[RISCV][VLOPT] Skip EMUL if it is unknown before entering EMULAndEEWAreEqual #139670
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?
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Piyou Chen (BeMg) ChangesFix #139288 Full diff: https://github.com/llvm/llvm-project/pull/139670.diff 2 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
index 9ed2ba274bc53..88876201ae21b 100644
--- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
@@ -1383,6 +1383,11 @@ RISCVVLOptimizer::checkUsers(const MachineInstr &MI) const {
// If the operand is used as a scalar operand, then the EEW must be
// compatible. Otherwise, the EMUL *and* EEW must be compatible.
bool IsVectorOpUsedAsScalarOp = isVectorOpUsedAsScalarOp(UserOp);
+
+ if (!IsVectorOpUsedAsScalarOp &&
+ (!ConsumerInfo->EMUL || !ProducerInfo->EMUL))
+ return std::nullopt;
+
if ((IsVectorOpUsedAsScalarOp &&
!OperandInfo::EEWAreEqual(*ConsumerInfo, *ProducerInfo)) ||
(!IsVectorOpUsedAsScalarOp &&
diff --git a/llvm/test/CodeGen/RISCV/rvv/139288-VLOPT-crash.ll b/llvm/test/CodeGen/RISCV/rvv/139288-VLOPT-crash.ll
new file mode 100644
index 0000000000000..1e2f0173505c3
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/139288-VLOPT-crash.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=riscv64 -mattr=+v < %s | FileCheck %s
+
+define i32 @pps_is_equal(<vscale x 16 x i1> %0, <vscale x 16 x i1> %1) #0 {
+; CHECK-LABEL: pps_is_equal:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetivli zero, 1, e32, m8, ta, ma
+; CHECK-NEXT: vmclr.m v8
+; CHECK-NEXT: vmv.s.x v16, zero
+; CHECK-NEXT: vmor.mm v0, v8, v8
+; CHECK-NEXT: vmv.v.i v8, 0
+; CHECK-NEXT: vredmax.vs v8, v8, v16, v0.t
+; CHECK-NEXT: vmv.x.s a0, v8
+; CHECK-NEXT: ret
+entry:
+ %2 = tail call <vscale x 16 x i1> @llvm.vp.or.nxv16i1(<vscale x 16 x i1> zeroinitializer, <vscale x 16 x i1> zeroinitializer, <vscale x 16 x i1> %0, i32 1)
+ %3 = tail call i32 @llvm.vp.reduce.smax.nxv16i32(i32 0, <vscale x 16 x i32> zeroinitializer, <vscale x 16 x i1> %2, i32 1)
+ ret i32 %3
+}
+
+declare <vscale x 16 x i1> @llvm.vp.or.nxv16i1(<vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, i32) #1
+declare i32 @llvm.vp.reduce.smax.nxv16i32(i32, <vscale x 16 x i32>, <vscale x 16 x i1>, i32) #1
|
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.
Would it be better if we just handle the nullopt EMUL case in EMULAndEEWAreEqual
? Does it work if we just replace it with
static bool EMULAndEEWAreEqual(const OperandInfo &A, const OperandInfo &B) {
return A.Log2EEW == B.Log2EEW && A.EMUL == B.EMUL;
}
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.
Nit, can you move this into vl-opt.ll and replace the VP intrinsics with RISC-V intrinsics? Just in case the VP intrinsics lowering ever changes
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 update the testcase inside the vl-opt.mir.
Yes, It work. |
Fix #139288