Skip to content

Commit

Permalink
[RISCV] Fix missing scalable->fixed-length vector conversion
Browse files Browse the repository at this point in the history
Returning the scalable-vector container type would present problems when
the fixed-length INSERT_VECTOR_ELT was used by later operations.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D98776
  • Loading branch information
frasercrmck committed Mar 19, 2021
1 parent 7a154c3 commit 550292e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
8 changes: 6 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -2379,8 +2379,12 @@ SDValue RISCVTargetLowering::lowerINSERT_VECTOR_ELT(SDValue Op,
SDValue ValInVec;

if (IsLegalInsert) {
if (isNullConstant(Idx))
return DAG.getNode(RISCVISD::VMV_S_XF_VL, DL, ContainerVT, Vec, Val, VL);
if (isNullConstant(Idx)) {
Vec = DAG.getNode(RISCVISD::VMV_S_XF_VL, DL, ContainerVT, Vec, Val, VL);
if (!VecVT.isFixedLengthVector())
return Vec;
return convertFromScalableVector(VecVT, Vec, DAG, Subtarget);
}
ValInVec = DAG.getNode(RISCVISD::VMV_S_XF_VL, DL, ContainerVT,
DAG.getUNDEF(ContainerVT), Val, VL);
} else {
Expand Down
36 changes: 34 additions & 2 deletions llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert.ll
Expand Up @@ -178,7 +178,7 @@ define void @insertelt_v8i64_0(<8 x i64>* %x) {
; RV32-NEXT: vle64.v v28, (a0)
; RV32-NEXT: addi a1, zero, -1
; RV32-NEXT: vmv.s.x v28, a1
; RV32-NEXT: vs4r.v v28, (a0)
; RV32-NEXT: vse64.v v28, (a0)
; RV32-NEXT: ret
;
; RV64-LABEL: insertelt_v8i64_0:
Expand Down Expand Up @@ -235,7 +235,7 @@ define void @insertelt_c6_v8i64_0(<8 x i64>* %x) {
; RV32-NEXT: vle64.v v28, (a0)
; RV32-NEXT: addi a1, zero, 6
; RV32-NEXT: vmv.s.x v28, a1
; RV32-NEXT: vs4r.v v28, (a0)
; RV32-NEXT: vse64.v v28, (a0)
; RV32-NEXT: ret
;
; RV64-LABEL: insertelt_c6_v8i64_0:
Expand Down Expand Up @@ -284,3 +284,35 @@ define void @insertelt_c6_v8i64(<8 x i64>* %x, i32 %idx) {
store <8 x i64> %b, <8 x i64>* %x
ret void
}

; Test that using a insertelement at element 0 by a later operation doesn't
; crash the compiler.
define void @insertelt_c6_v8i64_0_add(<8 x i64>* %x, <8 x i64>* %y) {
; RV32-LABEL: insertelt_c6_v8i64_0_add:
; RV32: # %bb.0:
; RV32-NEXT: vsetivli a2, 8, e64,m4,ta,mu
; RV32-NEXT: vle64.v v28, (a0)
; RV32-NEXT: vle64.v v8, (a1)
; RV32-NEXT: addi a1, zero, 6
; RV32-NEXT: vmv.s.x v28, a1
; RV32-NEXT: vadd.vv v28, v28, v8
; RV32-NEXT: vse64.v v28, (a0)
; RV32-NEXT: ret
;
; RV64-LABEL: insertelt_c6_v8i64_0_add:
; RV64: # %bb.0:
; RV64-NEXT: vsetivli a2, 8, e64,m4,ta,mu
; RV64-NEXT: vle64.v v28, (a0)
; RV64-NEXT: vle64.v v8, (a1)
; RV64-NEXT: addi a1, zero, 6
; RV64-NEXT: vmv.s.x v28, a1
; RV64-NEXT: vadd.vv v28, v28, v8
; RV64-NEXT: vse64.v v28, (a0)
; RV64-NEXT: ret
%a = load <8 x i64>, <8 x i64>* %x
%b = insertelement <8 x i64> %a, i64 6, i32 0
%c = load <8 x i64>, <8 x i64>* %y
%d = add <8 x i64> %b, %c
store <8 x i64> %d, <8 x i64>* %x
ret void
}

0 comments on commit 550292e

Please sign in to comment.