diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp')
| -rw-r--r-- | contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 90 | 
1 files changed, 52 insertions, 38 deletions
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 80628b23f111..743d51483ea1 100644 --- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -410,9 +410,9 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,      // If this is a select as part of a min/max pattern, don't simplify any      // further in case we break the structure.      Value *LHS, *RHS; -    if (matchSelectPattern(I, LHS, RHS) != SPF_UNKNOWN) +    if (matchSelectPattern(I, LHS, RHS).Flavor != SPF_UNKNOWN)        return nullptr; -       +      if (SimplifyDemandedBits(I->getOperandUse(2), DemandedMask, RHSKnownZero,                               RHSKnownOne, Depth + 1) ||          SimplifyDemandedBits(I->getOperandUse(1), DemandedMask, LHSKnownZero, @@ -1057,7 +1057,13 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,      APInt LeftDemanded(DemandedElts), RightDemanded(DemandedElts);      if (ConstantVector* CV = dyn_cast<ConstantVector>(I->getOperand(0))) {        for (unsigned i = 0; i < VWidth; i++) { -        if (CV->getAggregateElement(i)->isNullValue()) +        Constant *CElt = CV->getAggregateElement(i); +        // Method isNullValue always returns false when called on a +        // ConstantExpr. If CElt is a ConstantExpr then skip it in order to +        // to avoid propagating incorrect information. +        if (isa<ConstantExpr>(CElt)) +          continue; +        if (CElt->isNullValue())            LeftDemanded.clearBit(i);          else            RightDemanded.clearBit(i); @@ -1082,6 +1088,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,      if (!VTy) break;      unsigned InVWidth = VTy->getNumElements();      APInt InputDemandedElts(InVWidth, 0); +    UndefElts2 = APInt(InVWidth, 0);      unsigned Ratio;      if (VWidth == InVWidth) { @@ -1089,29 +1096,25 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,        // elements as are demanded of us.        Ratio = 1;        InputDemandedElts = DemandedElts; -    } else if (VWidth > InVWidth) { -      // Untested so far. -      break; - -      // If there are more elements in the result than there are in the source, -      // then an input element is live if any of the corresponding output -      // elements are live. -      Ratio = VWidth/InVWidth; -      for (unsigned OutIdx = 0; OutIdx != VWidth; ++OutIdx) { +    } else if ((VWidth % InVWidth) == 0) { +      // If the number of elements in the output is a multiple of the number of +      // elements in the input then an input element is live if any of the +      // corresponding output elements are live. +      Ratio = VWidth / InVWidth; +      for (unsigned OutIdx = 0; OutIdx != VWidth; ++OutIdx)          if (DemandedElts[OutIdx]) -          InputDemandedElts.setBit(OutIdx/Ratio); -      } -    } else { -      // Untested so far. -      break; - -      // If there are more elements in the source than there are in the result, -      // then an input element is live if the corresponding output element is -      // live. -      Ratio = InVWidth/VWidth; +          InputDemandedElts.setBit(OutIdx / Ratio); +    } else if ((InVWidth % VWidth) == 0) { +      // If the number of elements in the input is a multiple of the number of +      // elements in the output then an input element is live if the +      // corresponding output element is live. +      Ratio = InVWidth / VWidth;        for (unsigned InIdx = 0; InIdx != InVWidth; ++InIdx) -        if (DemandedElts[InIdx/Ratio]) +        if (DemandedElts[InIdx / Ratio])            InputDemandedElts.setBit(InIdx); +    } else { +      // Unsupported so far. +      break;      }      // div/rem demand all inputs, because they don't want divide by zero. @@ -1122,24 +1125,26 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,        MadeChange = true;      } -    UndefElts = UndefElts2; -    if (VWidth > InVWidth) { -      llvm_unreachable("Unimp"); -      // If there are more elements in the result than there are in the source, -      // then an output element is undef if the corresponding input element is -      // undef. +    if (VWidth == InVWidth) { +      UndefElts = UndefElts2; +    } else if ((VWidth % InVWidth) == 0) { +      // If the number of elements in the output is a multiple of the number of +      // elements in the input then an output element is undef if the +      // corresponding input element is undef.        for (unsigned OutIdx = 0; OutIdx != VWidth; ++OutIdx) -        if (UndefElts2[OutIdx/Ratio]) +        if (UndefElts2[OutIdx / Ratio]) +          UndefElts.setBit(OutIdx); +    } else if ((InVWidth % VWidth) == 0) { +      // If the number of elements in the input is a multiple of the number of +      // elements in the output then an output element is undef if all of the +      // corresponding input elements are undef. +      for (unsigned OutIdx = 0; OutIdx != VWidth; ++OutIdx) { +        APInt SubUndef = UndefElts2.lshr(OutIdx * Ratio).zextOrTrunc(Ratio); +        if (SubUndef.countPopulation() == Ratio)            UndefElts.setBit(OutIdx); -    } else if (VWidth < InVWidth) { +      } +    } else {        llvm_unreachable("Unimp"); -      // If there are more elements in the source than there are in the result, -      // then a result element is undef if all of the corresponding input -      // elements are undef. -      UndefElts = ~0ULL >> (64-VWidth);  // Start out all undef. -      for (unsigned InIdx = 0; InIdx != InVWidth; ++InIdx) -        if (!UndefElts2[InIdx])            // Not undef? -          UndefElts.clearBit(InIdx/Ratio);    // Clear undef bit.      }      break;    } @@ -1237,6 +1242,15 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,        // like undef&0.  The result is known zero, not undef.        UndefElts &= UndefElts2;        break; + +    // SSE4A instructions leave the upper 64-bits of the 128-bit result +    // in an undefined state. +    case Intrinsic::x86_sse4a_extrq: +    case Intrinsic::x86_sse4a_extrqi: +    case Intrinsic::x86_sse4a_insertq: +    case Intrinsic::x86_sse4a_insertqi: +      UndefElts |= APInt::getHighBitsSet(VWidth, VWidth / 2); +      break;      }      break;    }  | 
