diff options
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp | 21 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/autohvx/isel-concat-multiple.ll | 35 |
3 files changed, 59 insertions, 15 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 3465d7ec947..b70e01b59ec 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -2077,7 +2077,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::VECTOR_SHUFFLE, ByteV, Legal); setOperationAction(ISD::VECTOR_SHUFFLE, ByteW, Legal); - setOperationAction(ISD::CONCAT_VECTORS, ByteW, Legal); setOperationAction(ISD::AND, ByteV, Legal); setOperationAction(ISD::OR, ByteV, Legal); setOperationAction(ISD::XOR, ByteV, Legal); @@ -2097,6 +2096,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::MULHS, T, Custom); setOperationAction(ISD::MULHU, T, Custom); setOperationAction(ISD::BUILD_VECTOR, T, Custom); + // Make concat-vectors custom to handle concats of more than 2 vectors. + setOperationAction(ISD::CONCAT_VECTORS, T, Custom); setOperationAction(ISD::INSERT_SUBVECTOR, T, Custom); setOperationAction(ISD::INSERT_VECTOR_ELT, T, Custom); setOperationAction(ISD::EXTRACT_SUBVECTOR, T, Custom); @@ -2134,9 +2135,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, for (MVT T : LegalV) { if (T == ByteV) continue; - // Promote all shuffles and concats to operate on vectors of bytes. + // Promote all shuffles to operate on vectors of bytes. setPromoteTo(ISD::VECTOR_SHUFFLE, T, ByteV); - setPromoteTo(ISD::CONCAT_VECTORS, T, ByteV); setPromoteTo(ISD::AND, T, ByteV); setPromoteTo(ISD::OR, T, ByteV); setPromoteTo(ISD::XOR, T, ByteV); @@ -2146,7 +2146,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, // Custom-lower BUILD_VECTOR for vector pairs. The standard (target- // independent) handling of it would convert it to a load, which is // not always the optimal choice. - setOperationAction(ISD::BUILD_VECTOR, T, Custom); + setOperationAction(ISD::BUILD_VECTOR, T, Custom); + // Make concat-vectors custom to handle concats of more than 2 vectors. + setOperationAction(ISD::CONCAT_VECTORS, T, Custom); // Custom-lower these operations for pairs. Expand them into a concat // of the corresponding operations on individual vectors. @@ -2173,9 +2175,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SHL, T, Custom); setOperationAction(ISD::SRL, T, Custom); - // Promote all shuffles and concats to operate on vectors of bytes. + // Promote all shuffles to operate on vectors of bytes. setPromoteTo(ISD::VECTOR_SHUFFLE, T, ByteW); - setPromoteTo(ISD::CONCAT_VECTORS, T, ByteW); } MVT BoolV = MVT::getVectorVT(MVT::i1, T.getVectorNumElements()); @@ -3063,6 +3064,8 @@ HexagonTargetLowering::LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const { MVT VecTy = ty(Op); const SDLoc &dl(Op); + if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true)) + return LowerHvxConcatVectors(Op, DAG); if (VecTy.getSizeInBits() == 64) { assert(Op.getNumOperands() == 2); @@ -3072,9 +3075,6 @@ HexagonTargetLowering::LowerCONCAT_VECTORS(SDValue Op, MVT ElemTy = VecTy.getVectorElementType(); if (ElemTy == MVT::i1) { - if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy, true)) - return LowerHvxConcatVectors(Op, DAG); - assert(VecTy == MVT::v2i1 || VecTy == MVT::v4i1 || VecTy == MVT::v8i1); MVT OpTy = ty(Op.getOperand(0)); // Scale is how many times the operands need to be contracted to match diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp index 291e3858012..7e9ef9dc85b 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -791,15 +791,24 @@ HexagonTargetLowering::LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) SDValue HexagonTargetLowering::LowerHvxConcatVectors(SDValue Op, SelectionDAG &DAG) const { - // This should only be called for vectors of i1. The "scalar" vector - // concatenation does not need special lowering (assuming that only - // two vectors are concatenated at a time). + // Vector concatenation of two integer (non-bool) vectors does not need + // special lowering. Custom-lower concats of bool vectors and expand + // concats of more than 2 vectors. MVT VecTy = ty(Op); - assert(VecTy.getVectorElementType() == MVT::i1); - const SDLoc &dl(Op); - unsigned HwLen = Subtarget.getVectorLength(); unsigned NumOp = Op.getNumOperands(); + if (VecTy.getVectorElementType() != MVT::i1) { + if (NumOp == 2) + return Op; + // Expand the other cases into a build-vector. + SmallVector<SDValue,8> Elems; + for (SDValue V : Op.getNode()->ops()) + DAG.ExtractVectorElements(V, Elems); + return DAG.getBuildVector(VecTy, dl, Elems); + } + + assert(VecTy.getVectorElementType() == MVT::i1); + unsigned HwLen = Subtarget.getVectorLength(); assert(isPowerOf2_32(NumOp) && HwLen % NumOp == 0); SDValue Op0 = Op.getOperand(0); diff --git a/llvm/test/CodeGen/Hexagon/autohvx/isel-concat-multiple.ll b/llvm/test/CodeGen/Hexagon/autohvx/isel-concat-multiple.ll new file mode 100644 index 00000000000..3cc73750164 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/autohvx/isel-concat-multiple.ll @@ -0,0 +1,35 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; This code generates a concat_vectors with more than 2 inputs. Make sure +; that this compiles successfully. +; CHECK: vlsr + +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 void @fred() #0 { +b0: + %v1 = load i32, i32* undef, align 4 + %v2 = mul nsw i32 %v1, -15137 + %v3 = add nsw i32 0, %v2 + %v4 = sub nsw i32 0, %v3 + %v5 = load i32, i32* undef, align 4 + %v6 = insertelement <2 x i32> undef, i32 %v5, i32 1 + %v7 = add nsw <2 x i32> undef, %v6 + %v8 = extractelement <2 x i32> %v7, i32 0 + %v9 = insertelement <4 x i32> undef, i32 %v4, i32 2 + %v10 = insertelement <4 x i32> %v9, i32 undef, i32 3 + %v11 = add <4 x i32> %v10, <i32 131072, i32 131072, i32 131072, i32 131072> + %v12 = sub <4 x i32> %v11, zeroinitializer + %v13 = shufflevector <4 x i32> %v12, <4 x i32> undef, <8 x i32> <i32 undef, i32 0, i32 undef, i32 1, i32 undef, i32 2, i32 undef, i32 3> + %v14 = shufflevector <8 x i32> undef, <8 x i32> %v13, <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15> + %v15 = lshr <8 x i32> %v14, <i32 18, i32 18, i32 18, i32 18, i32 18, i32 18, i32 18, i32 18> + %v16 = and <8 x i32> %v15, <i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023, i32 1023> + %v17 = extractelement <8 x i32> %v16, i32 5 + %v18 = getelementptr inbounds i8, i8* null, i32 %v17 + %v19 = load i8, i8* %v18, align 1 + store i8 %v19, i8* undef, align 1 + unreachable +} + +attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx-length64b,+hvxv60" } |