[llvm] [Hexagon] Handle Call Operand vxi1 in Hexagon without HVX Enabled (PR #136546)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 21 01:42:54 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-hexagon

Author: None (pkarveti)

<details>
<summary>Changes</summary>

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.



---
Full diff: https://github.com/llvm/llvm-project/pull/136546.diff


6 Files Affected:

- (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.cpp (+77) 
- (modified) llvm/lib/Target/Hexagon/HexagonISelLowering.h (+12) 
- (modified) llvm/test/CodeGen/Hexagon/calloperand-v128i1.ll (+21-9) 
- (modified) llvm/test/CodeGen/Hexagon/calloperand-v16i1.ll (+15-8) 
- (modified) llvm/test/CodeGen/Hexagon/calloperand-v32i1.ll (+6) 
- (modified) llvm/test/CodeGen/Hexagon/calloperand-v64i1.ll (+7) 


``````````diff
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<MVT, unsigned>
+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<MVT, unsigned>
+  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]+}})

``````````

</details>


https://github.com/llvm/llvm-project/pull/136546


More information about the llvm-commits mailing list