diff options
Diffstat (limited to 'clang/lib/AST/ByteCode')
-rw-r--r-- | clang/lib/AST/ByteCode/Compiler.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Interp.h | 6 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 35 | ||||
-rw-r--r-- | clang/lib/AST/ByteCode/Pointer.cpp | 2 |
5 files changed, 40 insertions, 8 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index c71fd22..74cae03 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -4660,7 +4660,7 @@ const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) { template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) { if (const auto *RecordTy = getRecordTy(Ty)) - return getRecord(RecordTy->getOriginalDecl()->getDefinitionOrSelf()); + return getRecord(RecordTy->getDecl()->getDefinitionOrSelf()); return nullptr; } diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 8904396..a72282c 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1358,9 +1358,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED, const APSInt &Value) { - if (S.EvaluatingDecl && !S.EvaluatingDecl->isConstexpr()) - return; - llvm::APInt Min; llvm::APInt Max; ED->getValueRange(Max, Min); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 57cc705..812d25f 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3096,7 +3096,8 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) { } if (Offset.isZero()) { - if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) { + if (const Descriptor *Desc = Ptr.getFieldDesc(); + Desc && Desc->isArray() && Ptr.getIndex() == 0) { S.Stk.push<Pointer>(Ptr.atIndex(0).narrow()); return true; } @@ -3126,7 +3127,8 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) { } if (Offset.isZero()) { - if (Ptr.getFieldDesc()->isArray() && Ptr.getIndex() == 0) { + if (const Descriptor *Desc = Ptr.getFieldDesc(); + Desc && Desc->isArray() && Ptr.getIndex() == 0) { S.Stk.push<Pointer>(Ptr.atIndex(0).narrow()); return true; } diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index b69f360..a0d2c76 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -3101,6 +3101,33 @@ static bool interp__builtin_vec_set(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_ia32_vpconflict(InterpState &S, CodePtr OpPC, + const CallExpr *Call) { + assert(Call->getNumArgs() == 1); + + QualType Arg0Type = Call->getArg(0)->getType(); + const auto *VecT = Arg0Type->castAs<VectorType>(); + PrimType ElemT = *S.getContext().classify(VecT->getElementType()); + unsigned NumElems = VecT->getNumElements(); + bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType(); + const Pointer &Src = S.Stk.pop<Pointer>(); + const Pointer &Dst = S.Stk.peek<Pointer>(); + + for (unsigned I = 0; I != NumElems; ++I) { + INT_TYPE_SWITCH_NO_BOOL(ElemT, { + APSInt ElemI = Src.elem<T>(I).toAPSInt(); + APInt ConflictMask(ElemI.getBitWidth(), 0); + for (unsigned J = 0; J != I; ++J) { + APSInt ElemJ = Src.elem<T>(J).toAPSInt(); + ConflictMask.setBitVal(J, ElemI == ElemJ); + } + Dst.elem<T>(I) = static_cast<T>(APSInt(ConflictMask, DestUnsigned)); + }); + } + Dst.initializeAllElements(); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID) { if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID)) @@ -3891,7 +3918,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, [](const APSInt &Lo, const APSInt &Hi, const APSInt &Amt) { return llvm::APIntOps::fshr(Hi, Lo, Amt); }); - + case X86::BI__builtin_ia32_vpconflictsi_128: + case X86::BI__builtin_ia32_vpconflictsi_256: + case X86::BI__builtin_ia32_vpconflictsi_512: + case X86::BI__builtin_ia32_vpconflictdi_128: + case X86::BI__builtin_ia32_vpconflictdi_256: + case X86::BI__builtin_ia32_vpconflictdi_512: + return interp__builtin_ia32_vpconflict(S, OpPC, Call); case clang::X86::BI__builtin_ia32_blendpd: case clang::X86::BI__builtin_ia32_blendpd256: case clang::X86::BI__builtin_ia32_blendps: diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 663134c..e417bdf 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -751,7 +751,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, assert(Record && "Missing record descriptor"); bool Ok = true; - if (RT->getOriginalDecl()->isUnion()) { + if (RT->getDecl()->isUnion()) { const FieldDecl *ActiveField = nullptr; APValue Value; for (const auto &F : Record->fields()) { |