Index: llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp =================================================================== --- llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -508,25 +508,42 @@ Words.assign(Values.begin(), Values.end()); } + auto isSplat = [](ArrayRef Values, SDValue &SplatV) { + assert(Values.size() > 0); + bool IsUndef = true; + for (SDValue Value : Values) { + if (Value.isUndef()) + continue; + IsUndef = false; + if (!SplatV.getNode()) + SplatV = Value; + else if (SplatV != Value) + return false; + } + if (IsUndef) + SplatV = Values[0]; + return true; + }; + unsigned NumWords = Words.size(); - bool IsSplat = true, IsUndef = true; SDValue SplatV; - for (unsigned i = 0; i != NumWords && IsSplat; ++i) { - if (isUndef(Words[i])) - continue; - IsUndef = false; - if (!SplatV.getNode()) - SplatV = Words[i]; - else if (SplatV != Words[i]) - IsSplat = false; - } - if (IsUndef) + bool IsSplat = isSplat(Words, SplatV); + if (IsSplat && isUndef(SplatV)) return DAG.getUNDEF(VecTy); if (IsSplat) { assert(SplatV.getNode()); auto *IdxN = dyn_cast(SplatV.getNode()); - if (IdxN && IdxN->isNullValue()) - return getZero(dl, VecTy, DAG); + if (IdxN) { + if (IdxN->isNullValue()) + return getZero(dl, VecTy, DAG); + } + if (VecTy.getVectorElementType() != MVT::i32) { + SDValue SplatValue; + if (isSplat(Values, SplatValue)) { + SDValue Ext = DAG.getAnyExtOrTrunc(SplatValue, dl, MVT::i32); + return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext); + } + } MVT WordTy = MVT::getVectorVT(MVT::i32, HwLen/4); SDValue S = DAG.getNode(ISD::SPLAT_VECTOR, dl, WordTy, SplatV); return DAG.getBitcast(VecTy, S); Index: llvm/test/CodeGen/Hexagon/hvx-vsplat.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/Hexagon/hvx-vsplat.ll @@ -0,0 +1,34 @@ +; RUN: llc -march=hexagon -O3 < %s | FileCheck %s + +; target triple = "hexagon" + +; CHECK-LABEL: f0 +; CHECK: v{{[0-9]+}}.b = vsplat(r{{[0-9]+}}) +define <128 x i8> @f0(i8* %a) #0 { + %1 = load i8, i8* %a, align 1 + %2 = insertelement <128 x i8> undef, i8 %1, i32 0 + %3 = shufflevector <128 x i8> %2, <128 x i8> %2, <128 x i32> zeroinitializer + ret <128 x i8> %3 +} + +; CHECK-LABEL: f1 +; CHECK: v{{[0-9]+}}.h = vsplat(r{{[0-9]+}}) +define <64 x i16> @f1(i16* %a) #0 { + %1 = load i16, i16* %a, align 2 + %2 = insertelement <64 x i16> undef, i16 %1, i32 0 + %3 = shufflevector <64 x i16> %2, <64 x i16> %2, <64 x i32> zeroinitializer + ret <64 x i16> %3 +} + +; CHECK-LABEL: f4 +; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}}) +define <64 x i16> @f4(i16* %a) #0 { + %1 = load i16, i16* %a, align 4 + %2 = add i16 %1, 1 + %3 = insertelement <64 x i16> undef, i16 %1, i32 0 + %4 = insertelement <64 x i16> %3, i16 %2, i32 1 + %5 = shufflevector <64 x i16> %4, <64 x i16> %4, <64 x i32> + ret <64 x i16> %5 +} + +attributes #0 = { nounwind "target-cpu"="hexagonv65" "target-features"="+hvxv65,+hvx-length128b" }