From b3c925f25c45c76bc0e28ce7e11e5429bad9c6a0 Mon Sep 17 00:00:00 2001 From: pavani karveti Date: Mon, 21 Apr 2025 01:14:10 -0700 Subject: [PATCH] [Hexagon] Handle Call Operand vxi1 in Hexagon without HVX Enabled This commit updates the Hexagon backend to handle vxi1 call operands Without HVX enabled. It ensures compatibility for vector types of sizes 4, 8, 16, 32, 64, and 128 x i1 when HVX is not enabled. Change-Id: Iddecb58b7e2884cc7b3b35569c0768e203979e95 --- .../Target/Hexagon/HexagonISelLowering.cpp | 75 +++++++++++++++++++ llvm/lib/Target/Hexagon/HexagonISelLowering.h | 11 +++ .../CodeGen/Hexagon/calloperand-v128i1.ll | 30 +++++--- .../test/CodeGen/Hexagon/calloperand-v16i1.ll | 23 ++++-- .../test/CodeGen/Hexagon/calloperand-v32i1.ll | 6 ++ .../test/CodeGen/Hexagon/calloperand-v64i1.ll | 7 ++ 6 files changed, 135 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 4c479ac41be12..687b45526e904 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -156,6 +156,81 @@ 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 { + + bool isBoolVector = VT.getVectorElementType() == MVT::i1; + bool isPowerOf2 = VT.isPow2VectorType(); + unsigned NumElts = VT.getVectorNumElements(); + + // Split vectors of type vXi1 into (X/8) vectors of type v8i1, + // where X is divisible by 8. + if (isBoolVector && !Subtarget.useHVXOps() && isPowerOf2 && NumElts >= 8) { + RegisterVT = MVT::v8i8; + IntermediateVT = MVT::v8i1; + NumIntermediates = NumElts / 8; + return NumIntermediates; + } + + // In HVX 64-byte mode, vectors of type vXi1 are split into (X / 64) vectors + // of type v64i1, provided that X is divisible by 64. + if (isBoolVector && Subtarget.useHVX64BOps() && isPowerOf2 && NumElts >= 64) { + RegisterVT = MVT::v64i8; + IntermediateVT = MVT::v64i1; + NumIntermediates = NumElts / 64; + return NumIntermediates; + } + + // In HVX 128-byte mode, vectors of type vXi1 are split into (X / 128) vectors + // of type v128i1, provided that X is divisible by 128. + if (isBoolVector && Subtarget.useHVX128BOps() && isPowerOf2 && + NumElts >= 128) { + RegisterVT = MVT::v128i8; + IntermediateVT = MVT::v128i1; + NumIntermediates = NumElts / 128; + return NumIntermediates; + } + + return TargetLowering::getVectorTypeBreakdownForCallingConv( + Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT); +} + +std::pair +HexagonTargetLowering::handleMaskRegisterForCallingConv( + const HexagonSubtarget &Subtarget, EVT VT) const { + assert(VT.getVectorElementType() == MVT::i1); + + const unsigned NumElems = VT.getVectorNumElements(); + + if (!VT.isPow2VectorType()) + return {MVT::INVALID_SIMPLE_VALUE_TYPE, 0}; + + if (!Subtarget.useHVXOps() && NumElems >= 8) + return {MVT::v8i8, NumElems / 8}; + + if (Subtarget.useHVX64BOps() && NumElems >= 64) + return {MVT::v64i8, NumElems / 64}; + + if (Subtarget.useHVX128BOps() && NumElems >= 128) + return {MVT::v128i8, NumElems / 128}; + + return {MVT::INVALID_SIMPLE_VALUE_TYPE, 0}; +} + +MVT HexagonTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context, + CallingConv::ID CC, + EVT VT) const { + + if (VT.isVector() && VT.getVectorElementType() == MVT::i1) { + auto [RegisterVT, NumRegisters] = + handleMaskRegisterForCallingConv(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..790563475b12e 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -183,6 +183,9 @@ class HexagonTargetLowering : public TargetLowering { SelectionDAG &DAG) const override; const char *getTargetNodeName(unsigned Opcode) const override; + std::pair + handleMaskRegisterForCallingConv(const HexagonSubtarget &Subtarget, + EVT VT) const; SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const; @@ -263,6 +266,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]+}})