[llvm] r289099 - [RDF] Fix incorrect lane mask calculation

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 8 12:33:45 PST 2016


Author: kparzysz
Date: Thu Dec  8 14:33:45 2016
New Revision: 289099

URL: http://llvm.org/viewvc/llvm-project?rev=289099&view=rev
Log:
[RDF] Fix incorrect lane mask calculation

This was exposed by some code that used more than one level of sub-
registers. There is no testcase, because there is no such code in the
Hexagon backend.

Modified:
    llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=289099&r1=289098&r2=289099&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Thu Dec  8 14:33:45 2016
@@ -651,10 +651,10 @@ RegisterRef RegisterAggr::normalize(Regi
     SuperReg = *SR;
   }
 
-  uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
   const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg);
-  LaneBitmask SuperMask = RR.Mask &
-                          TRI.composeSubRegIndexLaneMask(Sub, RC.LaneMask);
+  LaneBitmask Common = RR.Mask & RC.LaneMask;
+  uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
+  LaneBitmask SuperMask = TRI.composeSubRegIndexLaneMask(Sub, Common);
   return RegisterRef(SuperReg, SuperMask);
 }
 
@@ -1206,12 +1206,36 @@ bool DataFlowGraph::alias(RegisterRef RA
   while (UMA.isValid() && UMB.isValid()) {
     std::pair<uint32_t,LaneBitmask> PA = *UMA;
     std::pair<uint32_t,LaneBitmask> PB = *UMB;
-    // If the returned lane mask is 0, it should be treated as ~0
-    // (or the lane mask from the given register ref should be ignored).
-    // This can happen when a register has only one unit.
     if (PA.first == PB.first) {
-      if (!PA.second || !PB.second || (PA.second & PB.second))
+      // Lane mask of 0 (given by the iterator) should be treated as "full".
+      // This can happen when the register has only one unit, or when the
+      // unit corresponds to explicit aliasing. In such cases, the lane mask
+      // from RegisterRef should be ignored.
+      if (!PA.second || !PB.second)
         return true;
+
+      // At this point the common unit corresponds to a subregister. The lane
+      // masks correspond to the lane mask of that unit within the original
+      // register, for example assuming register quadruple q0 = r3:0, and
+      // a register pair d1 = r3:2, the lane mask of r2 in q0 may be 0b0100,
+      // while the lane mask of r2 in d1 may be 0b0001.
+      LaneBitmask LA = PA.second & RA.Mask;
+      LaneBitmask LB = PB.second & RB.Mask;
+      if (LA != 0 && LB != 0) {
+        unsigned Root = *MCRegUnitRootIterator(PA.first, &TRI);
+        // If register units were guaranteed to only have 1 bit in any lane
+        // mask, the code below would not be necessary. This is because LA
+        // and LB would have at most 1 bit set each, and that bit would be
+        // guaranteed to correspond to the given register unit.
+        uint32_t SubA = TRI.getSubRegIndex(RA.Reg, Root);
+        uint32_t SubB = TRI.getSubRegIndex(RB.Reg, Root);
+        const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(Root);
+        LaneBitmask MaskA = TRI.reverseComposeSubRegIndexLaneMask(SubA, LA);
+        LaneBitmask MaskB = TRI.reverseComposeSubRegIndexLaneMask(SubB, LB);
+        if (MaskA & MaskB & RC.LaneMask)
+          return true;
+      }
+
       ++UMA;
       ++UMB;
       continue;




More information about the llvm-commits mailing list