[llvm] 4108535 - [Hexagon] Extend OptAddrMode pass to vgather

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 5 08:44:36 PST 2022


Author: Shubham Pawar
Date: 2022-01-05T08:44:21-08:00
New Revision: 41085357df2b2926bbe4494d8572395f891fdd02

URL: https://github.com/llvm/llvm-project/commit/41085357df2b2926bbe4494d8572395f891fdd02
DIFF: https://github.com/llvm/llvm-project/commit/41085357df2b2926bbe4494d8572395f891fdd02.diff

LOG: [Hexagon] Extend OptAddrMode pass to vgather

This change extends the addressing mode optimization
pass to HVX vgather. This is specifically intended to
resolve compiler not generating indexed addresses for
vgather stores to vtcm. Changed the vgather pseudo
instructions to accept an immediate operand and handled
addition of appropriate immediate operand in addressing
mode optimization pass.

Added: 
    llvm/test/CodeGen/Hexagon/vgather-opt-addr.ll

Modified: 
    llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
    llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
    llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp
    llvm/lib/Target/Hexagon/HexagonPatternsV65.td
    llvm/test/CodeGen/Hexagon/packetize-vgather-slot01.mir
    llvm/test/CodeGen/Hexagon/vgather-packetize.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
index 95e202647246e..0a6dd727eb82d 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
@@ -2393,6 +2393,7 @@ void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) {
   SDValue Base = N->getOperand(4);
   SDValue Modifier = N->getOperand(5);
   SDValue Offset = N->getOperand(6);
+  SDValue ImmOperand = CurDAG->getTargetConstant(0, dl, MVT::i32);
 
   unsigned Opcode;
   unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
@@ -2414,7 +2415,8 @@ void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) {
   }
 
   SDVTList VTs = CurDAG->getVTList(MVT::Other);
-  SDValue Ops[] = { Address, Predicate, Base, Modifier, Offset, Chain };
+  SDValue Ops[] = { Address, ImmOperand,
+                    Predicate, Base, Modifier, Offset, Chain };
   SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
 
   MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();
@@ -2430,6 +2432,7 @@ void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) {
   SDValue Base = N->getOperand(3);
   SDValue Modifier = N->getOperand(4);
   SDValue Offset = N->getOperand(5);
+  SDValue ImmOperand = CurDAG->getTargetConstant(0, dl, MVT::i32);
 
   unsigned Opcode;
   unsigned IntNo = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
@@ -2451,7 +2454,7 @@ void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) {
   }
 
   SDVTList VTs = CurDAG->getVTList(MVT::Other);
-  SDValue Ops[] = { Address, Base, Modifier, Offset, Chain };
+  SDValue Ops[] = { Address, ImmOperand, Base, Modifier, Offset, Chain };
   SDNode *Result = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
 
   MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand();

diff  --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index a38e437091329..a36be6b02caa8 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -1506,75 +1506,75 @@ HexagonInstrInfo::expandVGatherPseudo(MachineInstr &MI) const {
   switch (Opc) {
     case Hexagon::V6_vgathermh_pseudo:
       First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
-                  .add(MI.getOperand(1))
                   .add(MI.getOperand(2))
-                  .add(MI.getOperand(3));
+                  .add(MI.getOperand(3))
+                  .add(MI.getOperand(4));
       BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
           .add(MI.getOperand(0))
-          .addImm(0)
+          .addImm(MI.getOperand(1).getImm())
           .addReg(Hexagon::VTMP);
       MBB.erase(MI);
       return First.getInstrIterator();
 
     case Hexagon::V6_vgathermw_pseudo:
       First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))
-                  .add(MI.getOperand(1))
                   .add(MI.getOperand(2))
-                  .add(MI.getOperand(3));
+                  .add(MI.getOperand(3))
+                  .add(MI.getOperand(4));
       BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
           .add(MI.getOperand(0))
-          .addImm(0)
+          .addImm(MI.getOperand(1).getImm())
           .addReg(Hexagon::VTMP);
       MBB.erase(MI);
       return First.getInstrIterator();
 
     case Hexagon::V6_vgathermhw_pseudo:
       First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))
-                  .add(MI.getOperand(1))
                   .add(MI.getOperand(2))
-                  .add(MI.getOperand(3));
+                  .add(MI.getOperand(3))
+                  .add(MI.getOperand(4));
       BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
           .add(MI.getOperand(0))
-          .addImm(0)
+          .addImm(MI.getOperand(1).getImm())
           .addReg(Hexagon::VTMP);
       MBB.erase(MI);
       return First.getInstrIterator();
 
     case Hexagon::V6_vgathermhq_pseudo:
       First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))
-                  .add(MI.getOperand(1))
                   .add(MI.getOperand(2))
                   .add(MI.getOperand(3))
-                  .add(MI.getOperand(4));
+                  .add(MI.getOperand(4))
+                  .add(MI.getOperand(5));
       BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
           .add(MI.getOperand(0))
-          .addImm(0)
+          .addImm(MI.getOperand(1).getImm())
           .addReg(Hexagon::VTMP);
       MBB.erase(MI);
       return First.getInstrIterator();
 
     case Hexagon::V6_vgathermwq_pseudo:
       First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))
-                  .add(MI.getOperand(1))
                   .add(MI.getOperand(2))
                   .add(MI.getOperand(3))
-                  .add(MI.getOperand(4));
+                  .add(MI.getOperand(4))
+                  .add(MI.getOperand(5));
       BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
           .add(MI.getOperand(0))
-          .addImm(0)
+          .addImm(MI.getOperand(1).getImm())
           .addReg(Hexagon::VTMP);
       MBB.erase(MI);
       return First.getInstrIterator();
 
     case Hexagon::V6_vgathermhwq_pseudo:
       First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))
-                  .add(MI.getOperand(1))
                   .add(MI.getOperand(2))
                   .add(MI.getOperand(3))
-                  .add(MI.getOperand(4));
+                  .add(MI.getOperand(4))
+                  .add(MI.getOperand(5));
       BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
           .add(MI.getOperand(0))
-          .addImm(0)
+          .addImm(MI.getOperand(1).getImm())
           .addReg(Hexagon::VTMP);
       MBB.erase(MI);
       return First.getInstrIterator();
@@ -2767,7 +2767,13 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
   case Hexagon::V6_vL32b_nt_ai:
   case Hexagon::V6_vS32b_nt_ai:
   case Hexagon::V6_vL32Ub_ai:
-  case Hexagon::V6_vS32Ub_ai: {
+  case Hexagon::V6_vS32Ub_ai:
+  case Hexagon::V6_vgathermh_pseudo:
+  case Hexagon::V6_vgathermw_pseudo:
+  case Hexagon::V6_vgathermhw_pseudo:
+  case Hexagon::V6_vgathermhq_pseudo:
+  case Hexagon::V6_vgathermwq_pseudo:
+  case Hexagon::V6_vgathermhwq_pseudo: {
     unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);
     assert(isPowerOf2_32(VectorSize));
     if (Offset & (VectorSize-1))

diff  --git a/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp b/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp
index 2cdfbe7845b63..988b88a0f0ae4 100644
--- a/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonOptAddrMode.cpp
@@ -110,6 +110,8 @@ class HexagonOptAddrMode : public MachineFunctionPass {
   bool changeAddAsl(NodeAddr<UseNode *> AddAslUN, MachineInstr *AddAslMI,
                     const MachineOperand &ImmOp, unsigned ImmOpNum);
   bool isValidOffset(MachineInstr *MI, int Offset);
+  unsigned getBaseOpPosition(MachineInstr *MI);
+  unsigned getOffsetOpPosition(MachineInstr *MI);
 };
 
 } // end anonymous namespace
@@ -322,6 +324,25 @@ bool HexagonOptAddrMode::isSafeToExtLR(NodeAddr<StmtNode *> SN,
 }
 
 bool HexagonOptAddrMode::isValidOffset(MachineInstr *MI, int Offset) {
+  if (HII->isHVXVec(*MI)) {
+    // only HVX vgather instructions handled
+    // TODO: extend the pass to other vector load/store operations
+    switch (MI->getOpcode()) {
+    case Hexagon::V6_vgathermh_pseudo:
+    case Hexagon::V6_vgathermw_pseudo:
+    case Hexagon::V6_vgathermhw_pseudo:
+    case Hexagon::V6_vgathermhq_pseudo:
+    case Hexagon::V6_vgathermwq_pseudo:
+    case Hexagon::V6_vgathermhwq_pseudo:
+      return HII->isValidOffset(MI->getOpcode(), Offset, HRI, false);
+    default:
+      return false;
+    }
+  }
+
+  if (HII->getAddrMode(*MI) != HexagonII::BaseImmOffset)
+    return false;
+
   unsigned AlignMask = 0;
   switch (HII->getMemAccessSize(*MI)) {
   case HexagonII::MemAccessSize::DoubleWordAccess:
@@ -345,29 +366,62 @@ bool HexagonOptAddrMode::isValidOffset(MachineInstr *MI, int Offset) {
   return HII->isValidOffset(MI->getOpcode(), Offset, HRI, false);
 }
 
+unsigned HexagonOptAddrMode::getBaseOpPosition(MachineInstr *MI) {
+  const MCInstrDesc &MID = MI->getDesc();
+  switch (MI->getOpcode()) {
+  // vgather pseudos are mayLoad and mayStore
+  // hence need to explicitly specify Base and
+  // Offset operand positions
+  case Hexagon::V6_vgathermh_pseudo:
+  case Hexagon::V6_vgathermw_pseudo:
+  case Hexagon::V6_vgathermhw_pseudo:
+  case Hexagon::V6_vgathermhq_pseudo:
+  case Hexagon::V6_vgathermwq_pseudo:
+  case Hexagon::V6_vgathermhwq_pseudo:
+    return 0;
+  default:
+    return MID.mayLoad() ? 1 : 0;
+  }
+}
+
+unsigned HexagonOptAddrMode::getOffsetOpPosition(MachineInstr *MI) {
+  const MCInstrDesc &MID = MI->getDesc();
+  switch (MI->getOpcode()) {
+  // vgather pseudos are mayLoad and mayStore
+  // hence need to explicitly specify Base and
+  // Offset operand positions
+  case Hexagon::V6_vgathermh_pseudo:
+  case Hexagon::V6_vgathermw_pseudo:
+  case Hexagon::V6_vgathermhw_pseudo:
+  case Hexagon::V6_vgathermhq_pseudo:
+  case Hexagon::V6_vgathermwq_pseudo:
+  case Hexagon::V6_vgathermhwq_pseudo:
+    return 1;
+  default:
+    return MID.mayLoad() ? 2 : 1;
+  }
+}
+
 bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
                                         MachineInstr *AddMI,
                                         const NodeList &UNodeList) {
 
   Register AddDefR = AddMI->getOperand(0).getReg();
+  Register BaseReg = AddMI->getOperand(1).getReg();
   for (auto I = UNodeList.rbegin(), E = UNodeList.rend(); I != E; ++I) {
     NodeAddr<UseNode *> UN = *I;
     NodeAddr<StmtNode *> SN = UN.Addr->getOwner(*DFG);
     MachineInstr *MI = SN.Addr->getCode();
     const MCInstrDesc &MID = MI->getDesc();
-    if ((!MID.mayLoad() && !MID.mayStore()) ||
-        HII->getAddrMode(*MI) != HexagonII::BaseImmOffset ||
-        HII->isHVXVec(*MI))
-      return false;
+    if ((!MID.mayLoad() && !MID.mayStore()))
+        return false;
 
-    MachineOperand BaseOp = MID.mayLoad() ? MI->getOperand(1)
-                                          : MI->getOperand(0);
+    MachineOperand BaseOp = MI->getOperand(getBaseOpPosition(MI));
 
     if (!BaseOp.isReg() || BaseOp.getReg() != AddDefR)
       return false;
 
-    MachineOperand OffsetOp = MID.mayLoad() ? MI->getOperand(2)
-                                            : MI->getOperand(1);
+    MachineOperand OffsetOp = MI->getOperand(getOffsetOpPosition(MI));
     if (!OffsetOp.isImm())
       return false;
 
@@ -382,11 +436,19 @@ bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
     // Ex: Rx= add(Rt,#10)
     //     memw(Rx+#0) = Rs
     // will be replaced with =>  memw(Rt+#10) = Rs
-    Register BaseReg = AddMI->getOperand(1).getReg();
     if (!isSafeToExtLR(AddSN, AddMI, BaseReg, UNodeList))
       return false;
   }
 
+  NodeId LRExtRegRD = 0;
+  // Iterate through all the UseNodes in SN and find the reaching def
+  // for the LRExtReg.
+  for (NodeAddr<UseNode *> UA : AddSN.Addr->members_if(DFG->IsUse, *DFG)) {
+    RegisterRef RR = UA.Addr->getRegRef(*DFG);
+    if (BaseReg == RR.Reg)
+      LRExtRegRD = UA.Addr->getReachingDef();
+  }
+
   // Update all the uses of 'add' with the appropriate base and offset
   // values.
   bool Changed = false;
@@ -400,6 +462,12 @@ bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
     LLVM_DEBUG(dbgs() << "\t\t[MI <BB#" << UseMI->getParent()->getNumber()
                       << ">]: " << *UseMI << "\n");
     Changed |= updateAddUses(AddMI, UseMI);
+
+    // Set the reachingDef for UseNode under consideration
+    // after updating the Add use. This local change is
+    // to avoid rebuilding of the RDF graph after update.
+    NodeAddr<DefNode *> LRExtRegDN = DFG->addr<DefNode *>(LRExtRegRD);
+    UseN.Addr->linkToDef(UseN.Id, LRExtRegDN);
   }
 
   if (Changed)
@@ -409,21 +477,18 @@ bool HexagonOptAddrMode::processAddUses(NodeAddr<StmtNode *> AddSN,
 }
 
 bool HexagonOptAddrMode::updateAddUses(MachineInstr *AddMI,
-                                        MachineInstr *UseMI) {
+                                       MachineInstr *UseMI) {
   const MachineOperand ImmOp = AddMI->getOperand(2);
   const MachineOperand AddRegOp = AddMI->getOperand(1);
-  Register newReg = AddRegOp.getReg();
-  const MCInstrDesc &MID = UseMI->getDesc();
+  Register NewReg = AddRegOp.getReg();
 
-  MachineOperand &BaseOp = MID.mayLoad() ? UseMI->getOperand(1)
-                                         : UseMI->getOperand(0);
-  MachineOperand &OffsetOp = MID.mayLoad() ? UseMI->getOperand(2)
-                                           : UseMI->getOperand(1);
-  BaseOp.setReg(newReg);
+  MachineOperand &BaseOp = UseMI->getOperand(getBaseOpPosition(UseMI));
+  MachineOperand &OffsetOp = UseMI->getOperand(getOffsetOpPosition(UseMI));
+  BaseOp.setReg(NewReg);
   BaseOp.setIsUndef(AddRegOp.isUndef());
   BaseOp.setImplicit(AddRegOp.isImplicit());
   OffsetOp.setImm(ImmOp.getImm() + OffsetOp.getImm());
-  MRI->clearKillFlags(newReg);
+  MRI->clearKillFlags(NewReg);
 
   return true;
 }

diff  --git a/llvm/lib/Target/Hexagon/HexagonPatternsV65.td b/llvm/lib/Target/Hexagon/HexagonPatternsV65.td
index 4cd45ecbe1a1f..3f5d05d1c0e13 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatternsV65.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatternsV65.td
@@ -9,8 +9,8 @@
 multiclass vgathermh<RegisterClass RC> {
   let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in
   def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ),
-                           (ins  IntRegs:$_dst_, IntRegs:$Rt,
-                                 ModRegs:$Mu, RC:$Vv),
+                           (ins IntRegs:$_dst_, s4_0Imm:$Ii,
+                                IntRegs:$Rt, ModRegs:$Mu, RC:$Vv),
                            ".error \"should not emit\" ",
                            []>;
 }
@@ -18,8 +18,8 @@ multiclass vgathermh<RegisterClass RC> {
 multiclass vgathermw<RegisterClass RC> {
   let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in
   def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ),
-                           (ins IntRegs:$_dst_, IntRegs:$Rt,
-                                ModRegs:$Mu, RC:$Vv),
+                           (ins IntRegs:$_dst_, s4_0Imm:$Ii,
+                                IntRegs:$Rt, ModRegs:$Mu, RC:$Vv),
                            ".error \"should not emit\" ",
                            []>;
 }
@@ -27,8 +27,8 @@ multiclass vgathermw<RegisterClass RC> {
 multiclass vgathermhw<RegisterClass RC> {
   let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in
   def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ),
-                           (ins IntRegs:$_dst_, IntRegs:$Rt,
-                                ModRegs:$Mu, RC:$Vv),
+                           (ins IntRegs:$_dst_, s4_0Imm:$Ii,
+                                IntRegs:$Rt, ModRegs:$Mu, RC:$Vv),
                            ".error \"should not emit\" ",
                            []>;
 }
@@ -40,8 +40,9 @@ defm V6_vgathermhw_pseudo  : vgathermhw<HvxWR>;
 multiclass vgathermhq<RegisterClass RC1, RegisterClass RC2> {
   let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in
   def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ),
-                           (ins  IntRegs:$_dst_, RC2:$Vq, IntRegs:$Rt,
-                                 ModRegs:$Mu, RC1:$Vv),
+                           (ins IntRegs:$_dst_, s4_0Imm:$Ii,
+                                RC2:$Vq, IntRegs:$Rt, ModRegs:$Mu,
+                                RC1:$Vv),
                            ".error \"should not emit\" ",
                            []>;
 }
@@ -49,8 +50,9 @@ multiclass vgathermhq<RegisterClass RC1, RegisterClass RC2> {
 multiclass vgathermwq<RegisterClass RC1, RegisterClass RC2> {
   let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in
   def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ),
-                           (ins IntRegs:$_dst_, RC2:$Vq, IntRegs:$Rt,
-                                ModRegs:$Mu, RC1:$Vv),
+                           (ins IntRegs:$_dst_, s4_0Imm:$Ii,
+                                RC2:$Vq, IntRegs:$Rt, ModRegs:$Mu,
+                                RC1:$Vv),
                            ".error \"should not emit\" ",
                            []>;
 }
@@ -58,8 +60,9 @@ multiclass vgathermwq<RegisterClass RC1, RegisterClass RC2> {
 multiclass vgathermhwq<RegisterClass RC1, RegisterClass RC2> {
   let isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1 in
   def NAME : CVI_GATHER_TMP_LD_Resource_NoOpcode<(outs ),
-                           (ins IntRegs:$_dst_, RC2:$Vq, IntRegs:$Rt,
-                                ModRegs:$Mu, RC1:$Vv),
+                           (ins IntRegs:$_dst_, s4_0Imm:$Ii,
+                              RC2:$Vq, IntRegs:$Rt, ModRegs:$Mu,
+                              RC1:$Vv),
                            ".error \"should not emit\" ",
                            []>;
 }

diff  --git a/llvm/test/CodeGen/Hexagon/packetize-vgather-slot01.mir b/llvm/test/CodeGen/Hexagon/packetize-vgather-slot01.mir
index 5271b8535b219..fd9df82e79598 100644
--- a/llvm/test/CodeGen/Hexagon/packetize-vgather-slot01.mir
+++ b/llvm/test/CodeGen/Hexagon/packetize-vgather-slot01.mir
@@ -15,8 +15,8 @@ body: |
   bb.0:
     liveins: $r0, $r1, $r2, $r3, $m0, $v0, $v1, $v2
     $v0 = V6_vaslw_acc $v0, killed $v1, $r0
-    V6_vgathermw_pseudo $r1, $r2, $m0, killed $v2
+    V6_vgathermw_pseudo $r1, 0, $r2, $m0, killed $v2
     $r4 = A2_addi $r1, 512
     $r5 = A2_addi $r1, 640
-    V6_vgathermw_pseudo killed $r3, $r2, $m0, killed $v0
+    V6_vgathermw_pseudo killed $r3, 0, $r2, $m0, killed $v0
 ...

diff  --git a/llvm/test/CodeGen/Hexagon/vgather-opt-addr.ll b/llvm/test/CodeGen/Hexagon/vgather-opt-addr.ll
new file mode 100644
index 0000000000000..b43f79a3b4152
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/vgather-opt-addr.ll
@@ -0,0 +1,103 @@
+; RUN: llc -march=hexagon -O3 -disable-hexagon-amodeopt < %s | FileCheck %s --check-prefix=CHECK-NO-AMODE
+; RUN: llc -march=hexagon -O3 < %s | FileCheck %s --check-prefix=CHECK-AMODE
+
+; CHECK-NO-AMODE: [[REG1:(r[0-9]+)]] = add({{r[0-9]+}},#0)
+
+; CHECK-NO-AMODE: [[REG2:(r[0-9]+)]] = add([[REG1]],#128)
+; CHECK-NO-AMODE: [[REG3:(r[0-9]+)]] = add([[REG1]],#256)
+; CHECK-NO-AMODE: [[REG4:(r[0-9]+)]] = add([[REG1]],#384)
+; CHECK-NO-AMODE: [[REG5:(r[0-9]+)]] = add([[REG1]],#512)
+; CHECK-NO-AMODE: [[REG6:(r[0-9]+)]] = add([[REG1]],#640)
+; CHECK-NO-AMODE: vmem([[REG1]]+#0) = vtmp.new
+; CHECK-NO-AMODE: vmem([[REG2]]+#0) = vtmp.new
+; CHECK-NO-AMODE: vmem([[REG3]]+#0) = vtmp.new
+; CHECK-NO-AMODE: vmem([[REG4]]+#0) = vtmp.new
+; CHECK-NO-AMODE: vmem([[REG5]]+#0) = vtmp.new
+; CHECK-NO-AMODE: vmem([[REG6]]+#0) = vtmp.new
+
+
+; CHECK-AMODE: [[REG1:(r[0-9]+)]] = add({{r[0-9]+}},#0)
+; CHECK-AMODE-NOT: {{r[0-9]+}} = add([[REG1]],{{[0-9]+}})
+; CHECK-AMODE: vmem([[REG1]]+#0) = vtmp.new
+; CHECK-AMODE: vmem([[REG1]]+#1) = vtmp.new
+; CHECK-AMODE: vmem([[REG1]]+#2) = vtmp.new
+; CHECK-AMODE: vmem([[REG1]]+#3) = vtmp.new
+; CHECK-AMODE: vmem([[REG1]]+#4) = vtmp.new
+; CHECK-AMODE: vmem([[REG1]]+#5) = vtmp.new
+
+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"
+
+; Function Attrs: nounwind readnone
+define dso_local void @contiguos_vgather_test(i32 %Rb, i32 %mu, i32 %nloops, <32 x i32> %Vv, <64 x i32> %Vvv, <32 x i32> %Qs) local_unnamed_addr #0 {
+entry:
+  %Vout1 = alloca <32 x i32>, align 128
+  %0 = bitcast <32 x i32>* %Vout1 to i8*
+  call void @llvm.lifetime.start.p0i8(i64 128, i8* nonnull %0) #2
+  %cmp23 = icmp sgt i32 %nloops, 0
+  br i1 %cmp23, label %for.body.lr.ph, label %for.cond.cleanup
+
+for.body.lr.ph:                                   ; preds = %entry
+  %add.ptr = getelementptr inbounds <32 x i32>, <32 x i32>* %Vout1, i32 1
+  %1 = bitcast <32 x i32>* %add.ptr to i8*
+  %add.ptr1 = getelementptr inbounds <32 x i32>, <32 x i32>* %Vout1, i32 2
+  %2 = bitcast <32 x i32>* %add.ptr1 to i8*
+  %add.ptr2 = getelementptr inbounds <32 x i32>, <32 x i32>* %Vout1, i32 3
+  %3 = bitcast <32 x i32>* %add.ptr2 to i8*
+  %4 = tail call <128 x i1> @llvm.hexagon.V6.vandvrt.128B(<32 x i32> %Qs, i32 -1)
+  %add.ptr3 = getelementptr inbounds <32 x i32>, <32 x i32>* %Vout1, i32 4
+  %5 = bitcast <32 x i32>* %add.ptr3 to i8*
+  %add.ptr4 = getelementptr inbounds <32 x i32>, <32 x i32>* %Vout1, i32 5
+  %6 = bitcast <32 x i32>* %add.ptr4 to i8*
+  br label %for.body
+
+for.cond.cleanup:                                 ; preds = %for.body, %entry
+  call void @llvm.lifetime.end.p0i8(i64 128, i8* nonnull %0) #2
+  ret void
+
+for.body:                                         ; preds = %for.body, %for.body.lr.ph
+  %i.024 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+  call void @llvm.hexagon.V6.vgathermh.128B(i8* nonnull %0, i32 %Rb, i32 %mu, <32 x i32> %Vv)
+  call void @llvm.hexagon.V6.vgathermw.128B(i8* nonnull %1, i32 %Rb, i32 %mu, <32 x i32> %Vv)
+  call void @llvm.hexagon.V6.vgathermhw.128B(i8* nonnull %2, i32 %Rb, i32 %mu, <64 x i32> %Vvv)
+  call void @llvm.hexagon.V6.vgathermhq.128B(i8* nonnull %3, <128 x i1> %4, i32 %Rb, i32 %mu, <32 x i32> %Vv)
+  call void @llvm.hexagon.V6.vgathermwq.128B(i8* nonnull %5, <128 x i1> %4, i32 %Rb, i32 %mu, <32 x i32> %Vv)
+  call void @llvm.hexagon.V6.vgathermhwq.128B(i8* nonnull %6, <128 x i1> %4, i32 %Rb, i32 %mu, <64 x i32> %Vvv)
+  %inc = add nuw nsw i32 %i.024, 1
+  %exitcond = icmp eq i32 %inc, %nloops
+  br i1 %exitcond, label %for.cond.cleanup, label %for.body
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.hexagon.V6.vgathermh.128B(i8*, i32, i32, <32 x i32>) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.hexagon.V6.vgathermw.128B(i8*, i32, i32, <32 x i32>) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.hexagon.V6.vgathermhw.128B(i8*, i32, i32, <64 x i32>) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.hexagon.V6.vgathermhq.128B(i8*, <128 x i1>, i32, i32, <32 x i32>) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.hexagon.V6.vgathermwq.128B(i8*, <128 x i1>, i32, i32, <32 x i32>) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.hexagon.V6.vgathermhwq.128B(i8*, <128 x i1>, i32, i32, <64 x i32>) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
+
+declare <128 x i1> @llvm.hexagon.V6.vandvrt.128B(<32 x i32>, i32) #1
+
+attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv65" "target-features"="+hvx-length128b,+hvxv65,-long-calls" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { argmemonly nounwind }
+attributes #2 = { nounwind }
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"wchar_size", i32 4}

diff  --git a/llvm/test/CodeGen/Hexagon/vgather-packetize.mir b/llvm/test/CodeGen/Hexagon/vgather-packetize.mir
index 688a770ad2bf9..7e3eb21c446e7 100644
--- a/llvm/test/CodeGen/Hexagon/vgather-packetize.mir
+++ b/llvm/test/CodeGen/Hexagon/vgather-packetize.mir
@@ -21,7 +21,7 @@ body: |
   bb.1:
     liveins: $r0, $r1, $r2, $m0, $w0
     $r1 = A2_addi $r1, 1
-    V6_vgathermhw_pseudo $r0, $r2, $m0, $w0, implicit-def $vtmp
+    V6_vgathermhw_pseudo killed $r0, 0, killed $r2, killed $m0, killed $w0, implicit-def $vtmp
     ENDLOOP0 %bb.1, implicit $lc0, implicit $sa0, implicit-def $lc0, implicit-def $p3, implicit-def $pc, implicit-def $usr
 
   bb.2:


        


More information about the llvm-commits mailing list