[llvm-commits] [llvm] r64825 - in /llvm/branches/Apple/Dib: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp lib/Transforms/Scalar/InstructionCombining.cpp test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll test/Transforms/InstCombine/vec_demanded_elts-2.ll

Bill Wendling isanbard at gmail.com
Tue Feb 17 14:10:40 PST 2009


Author: void
Date: Tue Feb 17 16:10:39 2009
New Revision: 64825

URL: http://llvm.org/viewvc/llvm-project?rev=64825&view=rev
Log:
--- Merging (from foreign repository) r63631 into '.':
A    test/Transforms/InstCombine/vec_demanded_elts-2.ll
U    lib/Transforms/Scalar/InstructionCombining.cpp

APInt'fy SimplifyDemandedVectorElts so it can analyze vectors with more than 64
elements.

--- Merging (from foreign repository) r63632 into '.':
A    test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll
U    lib/CodeGen/SelectionDAG/LegalizeTypes.cpp

Fix PR3411.  When replacing values, nodes are analyzed
in any old order.  Since analyzing a node analyzes its
operands also, this can mean that when we pop a node
off the list of nodes to be analyzed, it may already
have been analyzed.

Added:
    llvm/branches/Apple/Dib/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll
    llvm/branches/Apple/Dib/test/Transforms/InstCombine/vec_demanded_elts-2.ll
Modified:
    llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
    llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=64825&r1=64824&r2=64825&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Tue Feb 17 16:10:39 2009
@@ -651,7 +651,7 @@
       DTL.NoteDeletion(N, E);
 
       // In theory the deleted node could also have been scheduled for analysis.
-      // So add it to the set of nodes which will not be analyzed.
+      // So remove it from the set of nodes which will be analyzed.
       NodesToAnalyze.remove(N);
 
       // In general nothing needs to be done for E, since it didn't change but
@@ -669,6 +669,7 @@
       assert(N->getNodeId() != DAGTypeLegalizer::ReadyToProcess &&
              N->getNodeId() != DAGTypeLegalizer::Processed &&
              "Invalid node ID for RAUW deletion!");
+      N->setNodeId(DAGTypeLegalizer::NewNode);
       NodesToAnalyze.insert(N);
     }
   };
@@ -695,12 +696,13 @@
   while (!NodesToAnalyze.empty()) {
     SDNode *N = NodesToAnalyze.back();
     NodesToAnalyze.pop_back();
+    if (N->getNodeId() != DAGTypeLegalizer::NewNode)
+      // The node was analyzed while reanalyzing an earlier node - it is safe to
+      // skip.  Note that this is not a morphing node - otherwise it would still
+      // be marked NewNode.
+      continue;
 
     // Analyze the node's operands and recalculate the node ID.
-    assert(N->getNodeId() != DAGTypeLegalizer::ReadyToProcess &&
-           N->getNodeId() != DAGTypeLegalizer::Processed &&
-           "Invalid node ID for RAUW analysis!");
-    N->setNodeId(NewNode);
     SDNode *M = AnalyzeNewNode(N);
     if (M != N) {
       // The node morphed into a different node.  Make everyone use the new node

Modified: llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp?rev=64825&r1=64824&r2=64825&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 17 16:10:39 2009
@@ -352,8 +352,8 @@
     /// properties that allow us to simplify its operands.
     bool SimplifyDemandedInstructionBits(Instruction &Inst);
         
-    Value *SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts,
-                                      uint64_t &UndefElts, unsigned Depth = 0);
+    Value *SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
+                                      APInt& UndefElts, unsigned Depth = 0);
       
     // FoldOpIntoPhi - Given a binary operator or cast instruction which has a
     // PHI node as operand #0, see if we can fold the instruction into the PHI
@@ -1396,19 +1396,18 @@
 
 
 /// SimplifyDemandedVectorElts - The specified value produces a vector with
-/// 64 or fewer elements.  DemandedElts contains the set of elements that are
+/// any number of elements. DemandedElts contains the set of elements that are
 /// actually used by the caller.  This method analyzes which elements of the
 /// operand are undef and returns that information in UndefElts.
 ///
 /// If the information about demanded elements can be used to simplify the
 /// operation, the operation is simplified, then the resultant value is
 /// returned.  This returns null if no change was made.
-Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts,
-                                                uint64_t &UndefElts,
+Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
+                                                APInt& UndefElts,
                                                 unsigned Depth) {
   unsigned VWidth = cast<VectorType>(V->getType())->getNumElements();
-  assert(VWidth <= 64 && "Vector too wide to analyze!");
-  uint64_t EltMask = ~0ULL >> (64-VWidth);
+  APInt EltMask(APInt::getAllOnesValue(VWidth));
   assert((DemandedElts & ~EltMask) == 0 && "Invalid DemandedElts!");
 
   if (isa<UndefValue>(V)) {
@@ -1427,12 +1426,12 @@
 
     std::vector<Constant*> Elts;
     for (unsigned i = 0; i != VWidth; ++i)
-      if (!(DemandedElts & (1ULL << i))) {   // If not demanded, set to undef.
+      if (!DemandedElts[i]) {   // If not demanded, set to undef.
         Elts.push_back(Undef);
-        UndefElts |= (1ULL << i);
+        UndefElts.set(i);
       } else if (isa<UndefValue>(CP->getOperand(i))) {   // Already undef.
         Elts.push_back(Undef);
-        UndefElts |= (1ULL << i);
+        UndefElts.set(i);
       } else {                               // Otherwise, defined.
         Elts.push_back(CP->getOperand(i));
       }
@@ -1453,8 +1452,10 @@
     Constant *Zero = Constant::getNullValue(EltTy);
     Constant *Undef = UndefValue::get(EltTy);
     std::vector<Constant*> Elts;
-    for (unsigned i = 0; i != VWidth; ++i)
-      Elts.push_back((DemandedElts & (1ULL << i)) ? Zero : Undef);
+    for (unsigned i = 0; i != VWidth; ++i) {
+      Constant *Elt = DemandedElts[i] ? Zero : Undef;
+      Elts.push_back(Elt);
+    }
     UndefElts = DemandedElts ^ EltMask;
     return ConstantVector::get(Elts);
   }
@@ -1482,7 +1483,7 @@
   if (!I) return false;        // Only analyze instructions.
   
   bool MadeChange = false;
-  uint64_t UndefElts2;
+  APInt UndefElts2(VWidth, 0);
   Value *TmpV;
   switch (I->getOpcode()) {
   default: break;
@@ -1503,35 +1504,36 @@
     // If this is inserting an element that isn't demanded, remove this
     // insertelement.
     unsigned IdxNo = Idx->getZExtValue();
-    if (IdxNo >= VWidth || (DemandedElts & (1ULL << IdxNo)) == 0)
+    if (IdxNo >= VWidth || !DemandedElts[IdxNo])
       return AddSoonDeadInstToWorklist(*I, 0);
     
     // Otherwise, the element inserted overwrites whatever was there, so the
     // input demanded set is simpler than the output set.
-    TmpV = SimplifyDemandedVectorElts(I->getOperand(0),
-                                      DemandedElts & ~(1ULL << IdxNo),
+    APInt DemandedElts2 = DemandedElts;
+    DemandedElts2.clear(IdxNo);
+    TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts2,
                                       UndefElts, Depth+1);
     if (TmpV) { I->setOperand(0, TmpV); MadeChange = true; }
 
     // The inserted element is defined.
-    UndefElts &= ~(1ULL << IdxNo);
+    UndefElts.clear(IdxNo);
     break;
   }
   case Instruction::ShuffleVector: {
     ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(I);
     uint64_t LHSVWidth =
       cast<VectorType>(Shuffle->getOperand(0)->getType())->getNumElements();
-    uint64_t LeftDemanded = 0, RightDemanded = 0;
+    APInt LeftDemanded(LHSVWidth, 0), RightDemanded(LHSVWidth, 0);
     for (unsigned i = 0; i < VWidth; i++) {
-      if (DemandedElts & (1ULL << i)) {
+      if (DemandedElts[i]) {
         unsigned MaskVal = Shuffle->getMaskValue(i);
         if (MaskVal != -1u) {
           assert(MaskVal < LHSVWidth * 2 &&
                  "shufflevector mask index out of range!");
           if (MaskVal < LHSVWidth)
-            LeftDemanded |= 1ULL << MaskVal;
+            LeftDemanded.set(MaskVal);
           else
-            RightDemanded |= 1ULL << (MaskVal - LHSVWidth);
+            RightDemanded.set(MaskVal - LHSVWidth);
         }
       }
     }
@@ -1540,7 +1542,7 @@
                                       UndefElts2, Depth+1);
     if (TmpV) { I->setOperand(0, TmpV); MadeChange = true; }
 
-    uint64_t UndefElts3;
+    APInt UndefElts3(VWidth, 0);
     TmpV = SimplifyDemandedVectorElts(I->getOperand(1), RightDemanded,
                                       UndefElts3, Depth+1);
     if (TmpV) { I->setOperand(1, TmpV); MadeChange = true; }
@@ -1549,16 +1551,17 @@
     for (unsigned i = 0; i < VWidth; i++) {
       unsigned MaskVal = Shuffle->getMaskValue(i);
       if (MaskVal == -1u) {
-        uint64_t NewBit = 1ULL << i;
-        UndefElts |= NewBit;
+        UndefElts.set(i);
       } else if (MaskVal < LHSVWidth) {
-        uint64_t NewBit = ((UndefElts2 >> MaskVal) & 1) << i;
-        NewUndefElts |= NewBit;
-        UndefElts |= NewBit;
+        if (UndefElts2[MaskVal]) {
+          NewUndefElts = true;
+          UndefElts.set(i);
+        }
       } else {
-        uint64_t NewBit = ((UndefElts3 >> (MaskVal - LHSVWidth)) & 1) << i;
-        NewUndefElts |= NewBit;
-        UndefElts |= NewBit;
+        if (UndefElts3[MaskVal - LHSVWidth]) {
+          NewUndefElts = true;
+          UndefElts.set(i);
+        }
       }
     }
 
@@ -1566,7 +1569,7 @@
       // Add additional discovered undefs.
       std::vector<Constant*> Elts;
       for (unsigned i = 0; i < VWidth; ++i) {
-        if (UndefElts & (1ULL << i))
+        if (UndefElts[i])
           Elts.push_back(UndefValue::get(Type::Int32Ty));
         else
           Elts.push_back(ConstantInt::get(Type::Int32Ty,
@@ -1582,7 +1585,7 @@
     const VectorType *VTy = dyn_cast<VectorType>(I->getOperand(0)->getType());
     if (!VTy) break;
     unsigned InVWidth = VTy->getNumElements();
-    uint64_t InputDemandedElts = 0;
+    APInt InputDemandedElts(InVWidth, 0);
     unsigned Ratio;
 
     if (VWidth == InVWidth) {
@@ -1599,8 +1602,8 @@
       // elements are live.
       Ratio = VWidth/InVWidth;
       for (unsigned OutIdx = 0; OutIdx != VWidth; ++OutIdx) {
-        if (DemandedElts & (1ULL << OutIdx))
-          InputDemandedElts |= 1ULL << (OutIdx/Ratio);
+        if (DemandedElts[OutIdx])
+          InputDemandedElts.set(OutIdx/Ratio);
       }
     } else {
       // Untested so far.
@@ -1611,8 +1614,8 @@
       // live.
       Ratio = InVWidth/VWidth;
       for (unsigned InIdx = 0; InIdx != InVWidth; ++InIdx)
-        if (DemandedElts & (1ULL << InIdx/Ratio))
-          InputDemandedElts |= 1ULL << InIdx;
+        if (DemandedElts[InIdx/Ratio])
+          InputDemandedElts.set(InIdx);
     }
     
     // div/rem demand all inputs, because they don't want divide by zero.
@@ -1630,8 +1633,8 @@
       // then an output element is undef if the corresponding input element is
       // undef.
       for (unsigned OutIdx = 0; OutIdx != VWidth; ++OutIdx)
-        if (UndefElts2 & (1ULL << (OutIdx/Ratio)))
-          UndefElts |= 1ULL << OutIdx;
+        if (UndefElts2[OutIdx/Ratio])
+          UndefElts.set(OutIdx);
     } else if (VWidth < InVWidth) {
       assert(0 && "Unimp");
       // If there are more elements in the source than there are in the result,
@@ -1639,8 +1642,8 @@
       // elements are undef.
       UndefElts = ~0ULL >> (64-VWidth);  // Start out all undef.
       for (unsigned InIdx = 0; InIdx != InVWidth; ++InIdx)
-        if ((UndefElts2 & (1ULL << InIdx)) == 0)    // Not undef?
-          UndefElts &= ~(1ULL << (InIdx/Ratio));    // Clear undef bit.
+        if (!UndefElts2[InIdx])            // Not undef?
+          UndefElts.clear(InIdx/Ratio);    // Clear undef bit.
     }
     break;
   }
@@ -9493,8 +9496,11 @@
   case Intrinsic::x86_sse_cvttss2si: {
     // These intrinsics only demands the 0th element of its input vector.  If
     // we can simplify the input based on that, do so now.
-    uint64_t UndefElts;
-    if (Value *V = SimplifyDemandedVectorElts(II->getOperand(1), 1, 
+    unsigned VWidth =
+      cast<VectorType>(II->getOperand(1)->getType())->getNumElements();
+    APInt DemandedElts(VWidth, 1);
+    APInt UndefElts(VWidth, 0);
+    if (Value *V = SimplifyDemandedVectorElts(II->getOperand(1), DemandedElts,
                                               UndefElts)) {
       II->setOperand(1, V);
       return II;
@@ -11874,10 +11880,10 @@
     // If the input vector has a single use, simplify it based on this use
     // property.
     if (EI.getOperand(0)->hasOneUse() && VectorWidth != 1) {
-      uint64_t UndefElts;
+      APInt UndefElts(VectorWidth, 0);
+      APInt DemandedMask(VectorWidth, 1 << IndexVal);
       if (Value *V = SimplifyDemandedVectorElts(EI.getOperand(0),
-                                                1 << IndexVal,
-                                                UndefElts)) {
+                                                DemandedMask, UndefElts)) {
         EI.setOperand(0, V);
         return &EI;
       }
@@ -12176,15 +12182,14 @@
   if (isa<UndefValue>(SVI.getOperand(2)))
     return ReplaceInstUsesWith(SVI, UndefValue::get(SVI.getType()));
 
-  uint64_t UndefElts;
   unsigned VWidth = cast<VectorType>(SVI.getType())->getNumElements();
 
   if (VWidth != cast<VectorType>(LHS->getType())->getNumElements())
     return 0;
 
-  uint64_t AllOnesEltMask = ~0ULL >> (64-VWidth);
-  if (VWidth <= 64 &&
-      SimplifyDemandedVectorElts(&SVI, AllOnesEltMask, UndefElts)) {
+  APInt UndefElts(VWidth, 0);
+  APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth));
+  if (SimplifyDemandedVectorElts(&SVI, AllOnesEltMask, UndefElts)) {
     LHS = SVI.getOperand(0);
     RHS = SVI.getOperand(1);
     MadeChange = true;

Added: llvm/branches/Apple/Dib/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll?rev=64825&view=auto

==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll (added)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll Tue Feb 17 16:10:39 2009
@@ -0,0 +1,30 @@
+; RUN: llvm-as < %s | llc -march=x86
+; PR3411
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-pc-linux-gnu"
+ at g_3 = external global i32		; <i32*> [#uses=1]
+
+define void @bar(i64 %p_66) nounwind {
+entry:
+	br i1 false, label %bb, label %bb1
+
+bb:		; preds = %entry
+	unreachable
+
+bb1:		; preds = %entry
+	%0 = load i32* @g_3, align 4		; <i32> [#uses=2]
+	%1 = sext i32 %0 to i64		; <i64> [#uses=1]
+	%2 = or i64 %1, %p_66		; <i64> [#uses=1]
+	%3 = shl i64 %2, 0		; <i64> [#uses=1]
+	%4 = and i64 %3, %p_66		; <i64> [#uses=1]
+	%5 = icmp eq i64 %4, 1		; <i1> [#uses=1]
+	%6 = trunc i64 %p_66 to i32		; <i32> [#uses=2]
+	%7 = or i32 %0, %6		; <i32> [#uses=2]
+	%8 = sub i32 %7, %6		; <i32> [#uses=1]
+	%iftmp.0.0 = select i1 %5, i32 %8, i32 %7		; <i32> [#uses=1]
+	%9 = tail call i32 @foo(i32 %iftmp.0.0) nounwind		; <i32> [#uses=0]
+	ret void
+}
+
+declare i32 @foo(i32)

Added: llvm/branches/Apple/Dib/test/Transforms/InstCombine/vec_demanded_elts-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/Transforms/InstCombine/vec_demanded_elts-2.ll?rev=64825&view=auto

==============================================================================
--- llvm/branches/Apple/Dib/test/Transforms/InstCombine/vec_demanded_elts-2.ll (added)
+++ llvm/branches/Apple/Dib/test/Transforms/InstCombine/vec_demanded_elts-2.ll Tue Feb 17 16:10:39 2009
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep extractelement
+
+define void @get_image() nounwind {
+entry:
+        %0 = call i32 @fgetc(i8* null) nounwind               ; <i32> [#uses=1]
+        %1 = trunc i32 %0 to i8         ; <i8> [#uses=1]
+        %tmp2 = insertelement <100 x i8> zeroinitializer, i8 %1, i32 1          ; <<100 x i8>> [#uses=1]
+        %tmp1 = extractelement <100 x i8> %tmp2, i32 0          ; <i8> [#uses=1]
+        %2 = icmp eq i8 %tmp1, 80               ; <i1> [#uses=1]
+        br i1 %2, label %bb2, label %bb3
+
+bb2:            ; preds = %entry
+        br label %bb3
+
+bb3:            ; preds = %bb2, %entry
+        unreachable
+}
+
+declare i32 @fgetc(i8*)





More information about the llvm-commits mailing list