diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -306,11 +306,14 @@ return Match(Cst); // FIXME: Add support for vector UNDEF cases? + // FIXME: Support SPLAT_VECTOR on fixed vectors. Should it call Match once + // or NumElements times? + EVT VT = Op.getValueType(); if (ISD::BUILD_VECTOR != Op.getOpcode() && - ISD::SPLAT_VECTOR != Op.getOpcode()) + !(ISD::SPLAT_VECTOR == Op.getOpcode() && VT.isScalableVector())) return false; - EVT SVT = Op.getValueType().getScalarType(); + EVT SVT = VT.getScalarType(); for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) { if (AllowUndefs && Op.getOperand(i).isUndef()) { if (!Match(nullptr)) diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-int-div.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-int-div.ll --- a/llvm/test/CodeGen/AArch64/sve-fixed-length-int-div.ll +++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-int-div.ll @@ -968,4 +968,20 @@ ret void } +; This used to crash because isUnaryPredicate and BuildUDIV don't know how +; a SPLAT_VECTOR of fixed vector type should be handled. +define void @udiv_constantsplat_v8i32(<8 x i32>* %a) #0 { +; CHECK-LABEL: udiv_constantsplat_v8i32: +; CHECK: ptrue [[PG:p[0-9]+]].s, vl[[#min(div(VBYTES,4),8)]] +; CHECK-NEXT: ld1w { [[OP1:z[0-9]+]].s }, [[PG]]/z, [x0] +; CHECK-NEXT: mov [[OP2:z[0-9]+]].s, #95 +; CHECK-NEXT: udiv [[RES:z[0-9]+]].s, [[PG]]/m, [[OP1]].s, [[OP2]].s +; CHECK-NEXT: st1w { [[RES]].s }, [[PG]], [x0] +; CHECK-NEXT: ret + %op1 = load <8 x i32>, <8 x i32>* %a + %res = udiv <8 x i32> %op1, + store <8 x i32> %res, <8 x i32>* %a + ret void +} + attributes #0 = { "target-features"="+sve" }