diff options
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 46 | 
1 files changed, 39 insertions, 7 deletions
| diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d0404b9..97eeba8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11621,7 +11621,7 @@ static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result,  static bool evalShuffleGeneric(      EvalInfo &Info, const CallExpr *Call, APValue &Out, -    llvm::function_ref<std::pair<unsigned, unsigned>(unsigned, unsigned)> +    llvm::function_ref<std::pair<unsigned, int>(unsigned, unsigned)>          GetSourceIndex) {    const auto *VT = Call->getType()->getAs<VectorType>(); @@ -11644,8 +11644,16 @@ static bool evalShuffleGeneric(    for (unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {      auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask); -    const APValue &Src = (SrcVecIdx == 0) ? A : B; -    ResultElements.push_back(Src.getVectorElt(SrcIdx)); + +    if (SrcIdx < 0) { +      // Zero out this element +      QualType ElemTy = VT->getElementType(); +      ResultElements.push_back( +          APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy)))); +    } else { +      const APValue &Src = (SrcVecIdx == 0) ? A : B; +      ResultElements.push_back(Src.getVectorElt(SrcIdx)); +    }    }    Out = APValue(ResultElements.data(), ResultElements.size()); @@ -12438,7 +12446,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {      if (!evalShuffleGeneric(              Info, E, R,              [](unsigned DstIdx, -               unsigned ShuffleMask) -> std::pair<unsigned, unsigned> { +               unsigned ShuffleMask) -> std::pair<unsigned, int> {                constexpr unsigned LaneBits = 128u;                unsigned NumElemPerLane = LaneBits / 32;                unsigned NumSelectableElems = NumElemPerLane / 2; @@ -12451,7 +12459,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {                unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;                unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;                unsigned Index = (ShuffleMask >> BitIndex) & IndexMask; -              return {SrcIdx, LaneOffset + Index}; +              return {SrcIdx, static_cast<int>(LaneOffset + Index)};              }))        return false;      return Success(R, E); @@ -12463,7 +12471,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {      if (!evalShuffleGeneric(              Info, E, R,              [](unsigned DstIdx, -               unsigned ShuffleMask) -> std::pair<unsigned, unsigned> { +               unsigned ShuffleMask) -> std::pair<unsigned, int> {                constexpr unsigned LaneBits = 128u;                unsigned NumElemPerLane = LaneBits / 64;                unsigned NumSelectableElems = NumElemPerLane / 2; @@ -12476,7 +12484,31 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {                unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;                unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;                unsigned Index = (ShuffleMask >> BitIndex) & IndexMask; -              return {SrcIdx, LaneOffset + Index}; +              return {SrcIdx, static_cast<int>(LaneOffset + Index)}; +            })) +      return false; +    return Success(R, E); +  } +  case X86::BI__builtin_ia32_insertps128: { +    APValue R; +    if (!evalShuffleGeneric( +            Info, E, R, +            [](unsigned DstIdx, unsigned Mask) -> std::pair<unsigned, int> { +              // Bits [3:0]: zero mask - if bit is set, zero this element +              if ((Mask & (1 << DstIdx)) != 0) { +                return {0, -1}; +              } +              // Bits [7:6]: select element from source vector Y (0-3) +              // Bits [5:4]: select destination position (0-3) +              unsigned SrcElem = (Mask >> 6) & 0x3; +              unsigned DstElem = (Mask >> 4) & 0x3; +              if (DstIdx == DstElem) { +                // Insert element from source vector (B) at this position +                return {1, static_cast<int>(SrcElem)}; +              } else { +                // Copy from destination vector (A) +                return {0, static_cast<int>(DstIdx)}; +              }              }))        return false;      return Success(R, E); | 
