diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp index e63cb50a0fb8..65bc2e3577cc 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -1925,6 +1925,17 @@ HexagonTargetLowering::WidenHvxTruncate(SDValue Op, SelectionDAG &DAG) const { const SDLoc &dl(Op); unsigned HwWidth = 8*Subtarget.getVectorLength(); + SDValue Op0 = Op.getOperand(0); + MVT ResTy = ty(Op); + MVT OpTy = ty(Op0); + if (!Subtarget.isHVXElementType(OpTy) || !Subtarget.isHVXElementType(ResTy)) + return SDValue(); + + // .-res, op-> Scalar Illegal HVX + // Scalar ok extract(widen) - + // Illegal - widen widen + // HVX - - ok + auto getFactor = [HwWidth](MVT Ty) { unsigned Width = Ty.getSizeInBits(); assert(HwWidth % Width == 0); @@ -1936,15 +1947,6 @@ HexagonTargetLowering::WidenHvxTruncate(SDValue Op, SelectionDAG &DAG) const { return MVT::getVectorVT(Ty.getVectorElementType(), WideLen); }; - SDValue Op0 = Op.getOperand(0); - MVT ResTy = ty(Op); - MVT OpTy = ty(Op0); - - // .-res, op-> Scalar Illegal HVX - // Scalar ok extract(widen) - - // Illegal - widen widen - // HVX - - ok - if (Subtarget.isHVXVectorType(OpTy)) return DAG.getNode(HexagonISD::VPACKL, dl, getWideTy(ResTy), Op0); @@ -2053,8 +2055,8 @@ HexagonTargetLowering::LowerHvxOperationWrapper(SDNode *N, switch (Opc) { case ISD::TRUNCATE: { assert(shouldWidenToHvx(ty(Op.getOperand(0)), DAG) && "Not widening?"); - SDValue T = WidenHvxTruncate(Op, DAG); - Results.push_back(T); + if (SDValue T = WidenHvxTruncate(Op, DAG)) + Results.push_back(T); break; } case ISD::STORE: { @@ -2089,8 +2091,8 @@ HexagonTargetLowering::ReplaceHvxNodeResults(SDNode *N, switch (Opc) { case ISD::TRUNCATE: { assert(shouldWidenToHvx(ty(Op), DAG) && "Not widening?"); - SDValue T = WidenHvxTruncate(Op, DAG); - Results.push_back(T); + if (SDValue T = WidenHvxTruncate(Op, DAG)) + Results.push_back(T); break; } case ISD::BITCAST: diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.h b/llvm/lib/Target/Hexagon/HexagonSubtarget.h index c47b95c5ad2a..5b71784bac26 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.h +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.h @@ -275,6 +275,17 @@ public: return makeArrayRef(Types); } + bool isHVXElementType(MVT Ty, bool IncludeBool = false) const { + if (!useHVXOps()) + return false; + if (Ty.isVector()) + Ty = Ty.getVectorElementType(); + if (IncludeBool && Ty == MVT::i1) + return true; + ArrayRef ElemTypes = getHVXElementTypes(); + return llvm::find(ElemTypes, Ty) != ElemTypes.end(); + } + bool isHVXVectorType(MVT VecTy, bool IncludeBool = false) const { if (!VecTy.isVector() || !useHVXOps() || VecTy.isScalableVector()) return false; @@ -298,7 +309,7 @@ public: unsigned VecWidth = VecTy.getSizeInBits(); if (VecWidth != 8*HwLen && VecWidth != 16*HwLen) return false; - return llvm::any_of(ElemTypes, [ElemTy] (MVT T) { return ElemTy == T; }); + return llvm::find(ElemTypes, ElemTy) != ElemTypes.end(); } unsigned getTypeAlignment(MVT Ty) const { diff --git a/llvm/test/CodeGen/Hexagon/autohvx/isel-widen-truncate-illegal-elem.ll b/llvm/test/CodeGen/Hexagon/autohvx/isel-widen-truncate-illegal-elem.ll new file mode 100644 index 000000000000..3f55d22308c3 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/autohvx/isel-widen-truncate-illegal-elem.ll @@ -0,0 +1,34 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; Check that this does not crash. +; CHECK: vmem + +target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048" +target triple = "hexagon" + +define dso_local void @f0() local_unnamed_addr #0 { +b0: + %v0 = load i32, i32* undef, align 4 + %v1 = select i1 undef, i32 0, i32 1073741823 + %v2 = shl i32 %v1, 0 + %v3 = sext i32 %v0 to i64 + %v4 = sext i32 %v2 to i64 + %v5 = mul nsw i64 %v4, %v3 + %v6 = lshr i64 %v5, 32 + %v7 = trunc i64 %v6 to i32 + %v8 = sext i32 %v7 to i64 + %v9 = insertelement <32 x i64> undef, i64 %v8, i32 0 + %v10 = shufflevector <32 x i64> %v9, <32 x i64> undef, <32 x i32> zeroinitializer + %v11 = getelementptr i32, i32* null, i32 32 + %v12 = bitcast i32* %v11 to <32 x i32>* + %v13 = load <32 x i32>, <32 x i32>* %v12, align 4 + %v14 = shl <32 x i32> %v13, zeroinitializer + %v15 = sext <32 x i32> %v14 to <32 x i64> + %v16 = mul nsw <32 x i64> %v10, %v15 + %v17 = lshr <32 x i64> %v16, + %v18 = trunc <32 x i64> %v17 to <32 x i32> + store <32 x i32> %v18, <32 x i32>* %v12, align 4 + ret void +} + +attributes #0 = { "target-features"="+hvx-length128b,+hvxv67,+v67,-long-calls" }