diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 4c479ac41be12..dca8aaaf66422 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -155,7 +155,84 @@ static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT, } #include "HexagonGenCallingConv.inc" +unsigned HexagonTargetLowering::getVectorTypeBreakdownForCallingConv( + LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, + unsigned &NumIntermediates, MVT &RegisterVT) const { + + RegisterVT = MVT::v8i8; + IntermediateVT = MVT::v8i1; + // Split vectors of type vXi1 into (X/8) vectors of type v8i1, + // where X is divisible by 8. + if (!Subtarget.useHVXOps()) { + switch (VT.getSimpleVT().SimpleTy) { + case MVT::v16i1: + NumIntermediates = 2; + return 2; + case MVT::v32i1: + NumIntermediates = 4; + return 4; + case MVT::v64i1: + NumIntermediates = 8; + return 8; + case MVT::v128i1: + NumIntermediates = 16; + return 16; + default: + break; + } + } + // Split v128i1 vectors into 2 v64i1 vectors in HVX 64-byte mode. + if (VT == MVT::v128i1 && Subtarget.useHVX64BOps()) { + RegisterVT = MVT::v64i8; + IntermediateVT = MVT::v64i1; + NumIntermediates = 2; + return 2; + } + return TargetLowering::getVectorTypeBreakdownForCallingConv( + Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT); +} +std::pair +HexagonTargetLowering::handleMaskRegisterForCallingConv( + unsigned NumElts, CallingConv::ID CC, const HexagonSubtarget &Subtarget, + EVT VT) const { + + unsigned NumIntermediates = 1; + ElementCount EC = VT.getVectorElementCount(); + // For vectors of type vXi1, where X is divisible by 8, + // use Double registers when HVX is not enabled. + if (VT.getVectorNumElements() >= 16 && !Subtarget.useHVXOps() && + isPowerOf2_32(EC.getKnownMinValue())) { + while (EC.getKnownMinValue() > 8) { + EC = EC.divideCoefficientBy(2); + + NumIntermediates <<= 1; + } + return {MVT::v8i8, NumIntermediates}; + } + // Split v128i1 vectors into 2 v64i1 vectors in HVX 64-byte mode. + if (VT == MVT::v128i1 && Subtarget.useHVX64BOps()) { + return {MVT::v64i8, 2}; + } + return {MVT::INVALID_SIMPLE_VALUE_TYPE, 0}; +} + +MVT HexagonTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context, + CallingConv::ID CC, + EVT VT) const { + if (VT.isVector()) { + if (VT.getVectorElementType() == MVT::i1) { + unsigned NumElts = VT.getVectorNumElements(); + MVT RegisterVT; + unsigned NumRegisters; + std::tie(RegisterVT, NumRegisters) = + handleMaskRegisterForCallingConv(NumElts, CC, Subtarget, VT); + if (RegisterVT != MVT::INVALID_SIMPLE_VALUE_TYPE) + return RegisterVT; + } + } + return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT); +} SDValue HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index 4df88b3a8abd7..8270498b70061 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -183,6 +183,10 @@ class HexagonTargetLowering : public TargetLowering { SelectionDAG &DAG) const override; const char *getTargetNodeName(unsigned Opcode) const override; + std::pair + handleMaskRegisterForCallingConv(unsigned NumElts, CallingConv::ID CC, + const HexagonSubtarget &Subtarget, + EVT VT) const; SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const; @@ -263,6 +267,14 @@ class HexagonTargetLowering : public TargetLowering { Register getRegisterByName(const char* RegName, LLT VT, const MachineFunction &MF) const override; + unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, + CallingConv::ID CC, EVT VT, + EVT &IntermediateVT, + unsigned &NumIntermediates, + MVT &RegisterVT) const override; + + MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, + EVT VT) const override; /// If a physical register, this returns the register that receives the /// exception address on entry to an EH pad. Register diff --git a/llvm/test/CodeGen/Hexagon/calloperand-v128i1.ll b/llvm/test/CodeGen/Hexagon/calloperand-v128i1.ll index ddac8c1cd8279..9d323b455449e 100644 --- a/llvm/test/CodeGen/Hexagon/calloperand-v128i1.ll +++ b/llvm/test/CodeGen/Hexagon/calloperand-v128i1.ll @@ -1,10 +1,20 @@ -;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s -o - | FileCheck %s +;RUN: llc -mtriple=hexagon < %s -o - | FileCheck %s --check-prefix=CHECK +;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length64b < %s -o - | FileCheck %s --check-prefixes=CHECK-64,CHECK-64-128 +;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s -o - | FileCheck %s --check-prefixes=CHECK-128,CHECK-64-128 ; CHECK-LABEL: compare_vectors -; CHECK: [[REG1:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.b,v{{[0-9]+}}.b) -; CHECK: [[REG2:(r[0-9]+)]] = #-1 -; CHECK: v0 = vand([[REG1]],[[REG2]]) - +; CHECK: [[REG8:(r[0-9]+):[0-9]]] = CONST64(#72340172838076673) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) +; CHECK-128: [[REG1:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.b,v{{[0-9]+}}.b) +; CHECK-128: [[REG2:(r[0-9]+)]] = #-1 +; CHECK-128: v0 = vand([[REG1]],[[REG2]]) +; CHECK-64: [[REG5:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.b,v{{[0-9]+}}.b) +; CHECK-64: [[REG6:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.b,v{{[0-9]+}}.b) +; CHECK-64: [[REG7:(r[0-9]+)]] = #-1 +; CHECK-64: v0 = vand([[REG5]],[[REG7]]) +; CHECK-64: v1 = vand([[REG6]],[[REG7]]) define void @compare_vectors(<128 x i8> %a, <128 x i8> %b) { entry: %result = icmp eq <128 x i8> %a, %b @@ -13,11 +23,13 @@ entry: } ; CHECK-LABEL: f.1: -; CHECK: [[REG3:(q[0-9]+)]] = vand(v0,r{{[0-9]+}}) -; CHECK: [[REG4:(v[0-9]+)]] = vand([[REG3]],r{{[0-9]+}}) -; CHECK: r{{[0-9]+}} = vextract([[REG4]],r{{[0-9]+}}) +; CHECK: [[REG9:(r[0-9]+)]] = and([[REG9]],##16843009) +; CHECK: [[REG10:(r[0-9]+)]] = and([[REG10]],##16843009) +; CHECK-64-128: [[REG3:(q[0-9]+)]] = vand(v0,r{{[0-9]+}}) +; CHECK-64-128: [[REG4:(v[0-9]+)]] = vand([[REG3]],r{{[0-9]+}}) +; CHECK-64-128: r{{[0-9]+}} = vextract([[REG4]],r{{[0-9]+}}) -define i32 @f.1(<128 x i1> %vec) { +define i32 @f.1(<128 x i1> %vec){ %element = extractelement <128 x i1> %vec, i32 6 %is_true = icmp eq i1 %element, true br i1 %is_true, label %if_true, label %if_false diff --git a/llvm/test/CodeGen/Hexagon/calloperand-v16i1.ll b/llvm/test/CodeGen/Hexagon/calloperand-v16i1.ll index bbb2697246df1..6cf1a3fca70b7 100644 --- a/llvm/test/CodeGen/Hexagon/calloperand-v16i1.ll +++ b/llvm/test/CodeGen/Hexagon/calloperand-v16i1.ll @@ -1,10 +1,15 @@ -;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length64b < %s -o - | FileCheck %s --check-prefix=CHECK -;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s -o - | FileCheck %s --check-prefix=CHECK +;RUN: llc -mtriple=hexagon < %s -o - | FileCheck %s --check-prefix=CHECK +;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length64b < %s -o - | FileCheck %s --check-prefix=CHECK-HVX +;RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s -o - | FileCheck %s --check-prefix=CHECK-HVX ; CHECK-LABEL: compare_vectors -; CHECK: [[REG1:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.w,v{{[0-9]+}}.w) -; CHECK: [[REG2:(r[0-9]+)]] = #-1 -; CHECK: v0 = vand([[REG1]],[[REG2]]) +; CHECK: [[REG5:(r[0-9]+):[0-9]]] = CONST64(#72340172838076673) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG5]]) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG5]]) + +; CHECK-HVX: [[REG1:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.w,v{{[0-9]+}}.w) +; CHECK-HVX: [[REG2:(r[0-9]+)]] = #-1 +; CHECK-HVX: v0 = vand([[REG1]],[[REG2]]) define void @compare_vectors(<16 x i32> %a, <16 x i32> %b) { entry: @@ -14,9 +19,11 @@ entry: } ; CHECK-LABEL: f.1: -; CHECK: [[REG3:(q[0-9]+)]] = vand(v0,r{{[0-9]+}}) -; CHECK: [[REG4:(v[0-9]+)]] = vand([[REG3]],r{{[0-9]+}}) -; CHECK: r{{[0-9]+}} = vextract([[REG4]],r{{[0-9]+}}) +; CHECK: [[REG3:(r[0-9]+)]] = and([[REG3]],##16843009) +; CHECK: [[REG4:(r[0-9]+)]] = and([[REG4]],##16843009) +; CHECK-HVX: [[REG3:(q[0-9]+)]] = vand(v0,r{{[0-9]+}}) +; CHECK-HVX: [[REG4:(v[0-9]+)]] = vand([[REG3]],r{{[0-9]+}}) +; CHECK-HVX: r{{[0-9]+}} = vextract([[REG4]],r{{[0-9]+}}) define i32 @f.1(<16 x i1> %vec) { %element = extractelement <16 x i1> %vec, i32 6 diff --git a/llvm/test/CodeGen/Hexagon/calloperand-v32i1.ll b/llvm/test/CodeGen/Hexagon/calloperand-v32i1.ll index a73478728d910..c43ad70b94100 100644 --- a/llvm/test/CodeGen/Hexagon/calloperand-v32i1.ll +++ b/llvm/test/CodeGen/Hexagon/calloperand-v32i1.ll @@ -1,7 +1,11 @@ +; RUN: llc -mtriple=hexagon < %s -o - | FileCheck %s --check-prefix=CHECK ; RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length64b < %s -o - | FileCheck %s --check-prefix=CHECK-64 ; RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s -o - | FileCheck %s --check-prefix=CHECK-128 ; CHECK-LABEL: compare_vectors +; CHECK: [[REG8:(r[0-9]+):[0-9]]] = CONST64(#72340172838076673) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) ; CHECK-64: [[REG1:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.h,v{{[0-9]+}}.h) ; CHECK-64: [[REG2:(r[0-9]+)]] = #-1 ; CHECK-64: v0 = vand([[REG1]],[[REG2]]) @@ -21,6 +25,8 @@ entry: } ; CHECK-LABEL: f.1: +; CHECK: [[REG9:(r[0-9]+)]] = and([[REG9]],##16843009) +; CHECK: [[REG10:(r[0-9]+)]] = and([[REG10]],##16843009) ; CHECK-64: [[REG3:(q[0-9]+)]] = vand(v0,r{{[0-9]+}}) ; CHECK-64: [[REG4:(v[0-9]+)]] = vand([[REG3]],r{{[0-9]+}}) ; CHECK-64: r{{[0-9]+}} = vextract([[REG4]],r{{[0-9]+}}) diff --git a/llvm/test/CodeGen/Hexagon/calloperand-v64i1.ll b/llvm/test/CodeGen/Hexagon/calloperand-v64i1.ll index 7cc562085a7e6..90a2da14f1971 100644 --- a/llvm/test/CodeGen/Hexagon/calloperand-v64i1.ll +++ b/llvm/test/CodeGen/Hexagon/calloperand-v64i1.ll @@ -1,7 +1,12 @@ +; RUN: llc -mtriple=hexagon < %s -o - | FileCheck %s --check-prefix=CHECK ; RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length64b < %s -o - | FileCheck %s --check-prefix=CHECK-64 ; RUN: llc -mtriple=hexagon -mattr=+hvxv79,+hvx-length128b < %s -o - | FileCheck %s --check-prefix=CHECK-128 ; CHECK-LABEL: compare_vectors +; CHECK: [[REG8:(r[0-9]+):[0-9]]] = CONST64(#72340172838076673) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) +; CHECK: r{{[0-9]+}}:{{[0-9]+}} = and(r{{[0-9]+}}:{{[0-9]+}},[[REG8]]) ; CHECK-64: [[REG1:(q[0-9]+)]] = vcmp.eq(v{{[0-9]+}}.b,v{{[0-9]+}}.b) ; CHECK-64: [[REG2:(r[0-9]+)]] = #-1 ; CHECK-64: v0 = vand([[REG1]],[[REG2]]) @@ -21,6 +26,8 @@ entry: } ; CHECK-LABEL: f.1: +; CHECK: [[REG9:(r[0-9]+)]] = and([[REG9]],##16843009) +; CHECK: [[REG10:(r[0-9]+)]] = and([[REG10]],##16843009) ; CHECK-64: [[REG3:(q[0-9]+)]] = vand(v0,r{{[0-9]+}}) ; CHECK-64: [[REG4:(v[0-9]+)]] = vand([[REG3]],r{{[0-9]+}}) ; CHECK-64: r{{[0-9]+}} = vextract([[REG4]],r{{[0-9]+}})