From: Krzysztof Parzyszek Date: Tue, 1 Aug 2017 13:12:53 +0000 (+0000) Subject: [Hexagon] Convert HVX vector constants of i1 to i8 X-Git-Tag: android-x86-7.1-r4~12760 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c6a42e96ed1447a1baaaa481d99a52baaa489a6e;p=android-x86%2Fexternal-llvm.git [Hexagon] Convert HVX vector constants of i1 to i8 Certain operations require vector of i1 values. However, for Hexagon architecture compatibility, they need to be represented as vector of i8. Patch by Suyog Sarda. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309677 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index 364973b088b..906501c6ff1 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1364,10 +1364,44 @@ HexagonTargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const { return SDValue(); } +static Constant *convert_i1_to_i8(const Constant *ConstVal) { + SmallVector NewConst; + const ConstantVector *CV = dyn_cast(ConstVal); + if (!CV) + return nullptr; + + LLVMContext &Ctx = ConstVal->getContext(); + IRBuilder<> IRB(Ctx); + unsigned NumVectorElements = CV->getNumOperands(); + assert(isPowerOf2_32(NumVectorElements) && + "conversion only supported for pow2 VectorSize!"); + + for (unsigned i = 0; i < NumVectorElements / 8; ++i) { + uint8_t x = 0; + for (unsigned j = 0; j < 8; ++j) { + uint8_t y = CV->getOperand(i * 8 + j)->getUniqueInteger().getZExtValue(); + x |= y << (7 - j); + } + assert((x == 0 || x == 255) && "Either all 0's or all 1's expected!"); + NewConst.push_back(IRB.getInt8(x)); + } + return ConstantVector::get(NewConst); +} + SDValue HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { EVT ValTy = Op.getValueType(); ConstantPoolSDNode *CPN = cast(Op); + Constant *CVal = nullptr; + bool isVTi1Type = false; + if (const Constant *ConstVal = dyn_cast(CPN->getConstVal())) { + Type *CValTy = ConstVal->getType(); + if (CValTy->isVectorTy() && + CValTy->getVectorElementType()->isIntegerTy(1)) { + CVal = convert_i1_to_i8(ConstVal); + isVTi1Type = (CVal != nullptr); + } + } unsigned Align = CPN->getAlignment(); bool IsPositionIndependent = isPositionIndependent(); unsigned char TF = IsPositionIndependent ? HexagonII::MO_PCREL : 0; @@ -1377,6 +1411,8 @@ HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { if (CPN->isMachineConstantPoolEntry()) T = DAG.getTargetConstantPool(CPN->getMachineCPVal(), ValTy, Align, Offset, TF); + else if (isVTi1Type) + T = DAG.getTargetConstantPool(CVal, ValTy, Align, Offset, TF); else T = DAG.getTargetConstantPool(CPN->getConstVal(), ValTy, Align, Offset, TF); diff --git a/test/CodeGen/Hexagon/convert_const_i1_to_i8.ll b/test/CodeGen/Hexagon/convert_const_i1_to_i8.ll new file mode 100644 index 00000000000..35c12f1d88b --- /dev/null +++ b/test/CodeGen/Hexagon/convert_const_i1_to_i8.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; CHECK-NOT: .space {{[0-9][0-9][0-9][0-9]}} +; CHECK: q{{[0-3]}} = vand(v{{[0-9]*}},r{{[0-9]*}}) + +define void @convert_const_i1_to_i8() #0 { +entry: + %v0 = load <32 x i32>, <32 x i32>* undef, align 128 + %v1 = tail call <32 x i32> @llvm.hexagon.V6.vrdelta.128B(<32 x i32> %v0, <32 x i32> undef) + %v2 = tail call <32 x i32> @llvm.hexagon.V6.vmux.128B(<1024 x i1> , <32 x i32> undef, <32 x i32> %v1) + store <32 x i32> %v2, <32 x i32>* null, align 128 + ret void +} + +declare <32 x i32> @llvm.hexagon.V6.vrdelta.128B(<32 x i32>, <32 x i32>) +declare <32 x i32> @llvm.hexagon.V6.vmux.128B(<1024 x i1>, <32 x i32>, <32 x i32>) + +attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx-double" }