35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
196static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
198 "Expected a unary or binary operator");
202 if (!Op.mayHaveIntegerOverflow())
205 if (Op.Ty->isSignedIntegerType() &&
211 if (Op.Ty->isUnsignedIntegerType() &&
232 if (BO->hasExcludedOverflowPattern())
248 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
254 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
255 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
259class ScalarExprEmitter
261 CodeGenFunction &CGF;
262 CGBuilderTy &Builder;
263 bool IgnoreResultAssign;
264 llvm::LLVMContext &VMContext;
267 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
268 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
269 VMContext(cgf.getLLVMContext()) {
276 bool TestAndClearIgnoreResultAssign() {
277 bool I = IgnoreResultAssign;
278 IgnoreResultAssign =
false;
282 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
283 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
289 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
290 const BinOpInfo &Info);
292 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
296 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
297 const AlignValueAttr *AVAttr =
nullptr;
298 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
299 const ValueDecl *VD = DRE->getDecl();
302 if (
const auto *TTy =
304 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
314 AVAttr = VD->
getAttr<AlignValueAttr>();
319 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
320 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
333 Value *EmitLoadOfLValue(
const Expr *E) {
337 EmitLValueAlignmentAssumption(E,
V);
343 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
347 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
348 Value *Src, QualType SrcType, QualType DstType,
349 llvm::Type *DstTy, SourceLocation Loc);
354 enum ImplicitConversionCheckKind :
unsigned char {
355 ICCK_IntegerTruncation = 0,
356 ICCK_UnsignedIntegerTruncation = 1,
357 ICCK_SignedIntegerTruncation = 2,
358 ICCK_IntegerSignChange = 3,
359 ICCK_SignedIntegerTruncationOrSignChange = 4,
364 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
365 QualType DstType, SourceLocation Loc);
370 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
371 QualType DstType, SourceLocation Loc);
375 struct ScalarConversionOpts {
376 bool TreatBooleanAsSigned;
377 bool EmitImplicitIntegerTruncationChecks;
378 bool EmitImplicitIntegerSignChangeChecks;
380 ScalarConversionOpts()
381 : TreatBooleanAsSigned(
false),
382 EmitImplicitIntegerTruncationChecks(
false),
383 EmitImplicitIntegerSignChangeChecks(
false) {}
385 ScalarConversionOpts(clang::SanitizerSet SanOpts)
386 : TreatBooleanAsSigned(
false),
387 EmitImplicitIntegerTruncationChecks(
388 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
389 EmitImplicitIntegerSignChangeChecks(
390 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
392 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
393 llvm::Type *SrcTy, llvm::Type *DstTy,
394 ScalarConversionOpts Opts);
396 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
398 ScalarConversionOpts Opts = ScalarConversionOpts());
402 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
408 QualType SrcTy, QualType DstTy,
412 Value *EmitNullValue(QualType Ty);
417 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
418 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
422 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
425 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
432 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
433 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
439 ZI->eraseFromParent();
444 return Builder.CreateIsNotNull(
V,
"tobool");
451 Value *Visit(Expr *E) {
452 ApplyDebugLocation DL(CGF, E);
453 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
456 Value *VisitStmt(Stmt *S) {
458 llvm_unreachable(
"Stmt can't have complex result type!");
460 Value *VisitExpr(Expr *S);
462 Value *VisitConstantExpr(ConstantExpr *E) {
468 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
483 Value *VisitParenExpr(ParenExpr *PE) {
486 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
489 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
490 return Visit(
GE->getResultExpr());
492 Value *VisitCoawaitExpr(CoawaitExpr *S) {
495 Value *VisitCoyieldExpr(CoyieldExpr *S) {
498 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
503 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
504 return Builder.getInt(E->
getValue());
506 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
507 return Builder.getInt(E->
getValue());
509 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
510 return llvm::ConstantFP::get(VMContext, E->
getValue());
512 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
515 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
518 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
519 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
521 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
522 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
524 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
528 return EmitNullValue(E->
getType());
530 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
531 return EmitNullValue(E->
getType());
533 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
534 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
535 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
537 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
540 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
544 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
548 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
549 Value *VisitEmbedExpr(EmbedExpr *E);
551 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
560 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
561 llvm_unreachable(
"Codegen for this isn't defined/implemented");
565 Value *VisitDeclRefExpr(DeclRefExpr *E) {
568 return EmitLoadOfLValue(E);
571 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
574 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
577 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
578 return EmitLoadOfLValue(E);
580 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
583 return EmitLoadOfLValue(E);
587 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
593 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
599 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
604 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
605 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
606 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
607 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
608 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
609 Value *VisitMemberExpr(MemberExpr *E);
610 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
611 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
617 return EmitLoadOfLValue(E);
620 Value *VisitInitListExpr(InitListExpr *E);
622 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
624 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
628 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
629 return EmitNullValue(E->
getType());
631 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
633 return VisitCastExpr(E);
637 Value *VisitCallExpr(
const CallExpr *E) {
639 return EmitLoadOfLValue(E);
643 EmitLValueAlignmentAssumption(E,
V);
647 Value *VisitStmtExpr(
const StmtExpr *E);
650 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
652 return EmitScalarPrePostIncDec(E, LV,
false,
false);
654 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
656 return EmitScalarPrePostIncDec(E, LV,
true,
false);
658 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
660 return EmitScalarPrePostIncDec(E, LV,
false,
true);
662 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
664 return EmitScalarPrePostIncDec(E, LV,
true,
true);
667 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
671 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
672 bool isInc,
bool isPre);
675 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
679 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
681 Value *VisitUnaryDeref(
const UnaryOperator *E) {
684 return EmitLoadOfLValue(E);
687 Value *VisitUnaryPlus(
const UnaryOperator *E,
688 QualType PromotionType = QualType());
689 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
690 Value *VisitUnaryMinus(
const UnaryOperator *E,
691 QualType PromotionType = QualType());
692 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
694 Value *VisitUnaryNot (
const UnaryOperator *E);
695 Value *VisitUnaryLNot (
const UnaryOperator *E);
696 Value *VisitUnaryReal(
const UnaryOperator *E,
697 QualType PromotionType = QualType());
698 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
699 Value *VisitUnaryImag(
const UnaryOperator *E,
700 QualType PromotionType = QualType());
701 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
702 Value *VisitUnaryExtension(
const UnaryOperator *E) {
707 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
708 return EmitLoadOfLValue(E);
710 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
718 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
719 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
722 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
723 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
726 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
730 Value *VisitExprWithCleanups(ExprWithCleanups *E);
731 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
734 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
739 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
741 return llvm::ConstantInt::get(ConvertType(E->
getType()),
744 return llvm::ConstantInt::get(ConvertType(E->
getType()),
748 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
756 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
757 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
760 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
761 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
764 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
774 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
775 return EmitNullValue(E->
getType());
778 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
783 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
784 return Builder.getInt1(E->
getValue());
788 Value *EmitMul(
const BinOpInfo &Ops) {
789 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
790 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
791 case LangOptions::SOB_Defined:
792 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
793 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
795 case LangOptions::SOB_Undefined:
796 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
797 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
799 case LangOptions::SOB_Trapping:
800 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
801 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
802 return EmitOverflowCheckedBinOp(Ops);
806 if (Ops.Ty->isConstantMatrixType()) {
807 llvm::MatrixBuilder MB(Builder);
811 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
812 BO->getLHS()->getType().getCanonicalType());
813 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
814 BO->getRHS()->getType().getCanonicalType());
815 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
816 if (LHSMatTy && RHSMatTy)
817 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
818 LHSMatTy->getNumColumns(),
819 RHSMatTy->getNumColumns());
820 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
823 if (Ops.Ty->isUnsignedIntegerType() &&
824 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
825 !CanElideOverflowCheck(CGF.
getContext(), Ops))
826 return EmitOverflowCheckedBinOp(Ops);
828 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
830 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
831 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
833 if (Ops.isFixedPointOp())
834 return EmitFixedPointBinOp(Ops);
835 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
839 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
842 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
843 llvm::Value *
Zero,
bool isDiv);
845 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
851 Value *EmitDiv(
const BinOpInfo &Ops);
852 Value *EmitRem(
const BinOpInfo &Ops);
853 Value *EmitAdd(
const BinOpInfo &Ops);
854 Value *EmitSub(
const BinOpInfo &Ops);
855 Value *EmitShl(
const BinOpInfo &Ops);
856 Value *EmitShr(
const BinOpInfo &Ops);
857 Value *EmitAnd(
const BinOpInfo &Ops) {
858 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
860 Value *EmitXor(
const BinOpInfo &Ops) {
861 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
863 Value *EmitOr (
const BinOpInfo &Ops) {
864 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
868 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
870 BinOpInfo EmitBinOps(
const BinaryOperator *E,
871 QualType PromotionTy = QualType());
873 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
874 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
875 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
877 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
878 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
881 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
882 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
884 QualType getPromotionType(QualType Ty) {
886 if (
auto *CT = Ty->
getAs<ComplexType>()) {
887 QualType ElementType = CT->getElementType();
893 if (
auto *VT = Ty->
getAs<VectorType>()) {
894 unsigned NumElements = VT->getNumElements();
904#define HANDLEBINOP(OP) \
905 Value *VisitBin##OP(const BinaryOperator *E) { \
906 QualType promotionTy = getPromotionType(E->getType()); \
907 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
908 if (result && !promotionTy.isNull()) \
909 result = EmitUnPromotedValue(result, E->getType()); \
912 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
913 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
914 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
930 llvm::CmpInst::Predicate SICmpOpc,
931 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
932#define VISITCOMP(CODE, UI, SI, FP, SIG) \
933 Value *VisitBin##CODE(const BinaryOperator *E) { \
934 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
935 llvm::FCmpInst::FP, SIG); }
936 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
950 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
951 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
953 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
958 Value *VisitBlockExpr(
const BlockExpr *BE);
959 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
960 Value *VisitChooseExpr(ChooseExpr *CE);
961 Value *VisitVAArgExpr(VAArgExpr *VE);
962 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
965 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
968 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
971 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
974 Value *VisitAsTypeExpr(AsTypeExpr *CE);
975 Value *VisitAtomicExpr(AtomicExpr *AE);
976 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
989 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
992 return EmitFloatToBoolConversion(Src);
994 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
998 "Unknown scalar type to convert");
1001 return EmitIntToBoolConversion(Src);
1004 return EmitPointerToBoolConversion(Src, SrcType);
1007void ScalarExprEmitter::EmitFloatConversionCheck(
1008 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1009 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1010 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1014 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1015 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1016 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1017 using llvm::APFloat;
1020 llvm::Value *Check =
nullptr;
1021 const llvm::fltSemantics &SrcSema =
1031 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1032 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1033 APFloat::opOverflow)
1036 MinSrc = APFloat::getInf(SrcSema,
true);
1040 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1043 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1044 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1045 APFloat::opOverflow)
1048 MaxSrc = APFloat::getInf(SrcSema,
false);
1052 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1057 const llvm::fltSemantics &Sema =
1060 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1061 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1065 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1067 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1068 Check = Builder.CreateAnd(GE, LE);
1073 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1079static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1080 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1083 llvm::Type *SrcTy = Src->
getType();
1084 llvm::Type *DstTy = Dst->
getType();
1089 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1091 "non-integer llvm type");
1098 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1100 if (!SrcSigned && !DstSigned) {
1101 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1102 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1104 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1105 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1108 llvm::Value *Check =
nullptr;
1110 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1112 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1114 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1122void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1123 Value *Dst, QualType DstType,
1124 SourceLocation Loc) {
1134 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1135 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1137 if (SrcBits <= DstBits)
1140 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1147 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1148 (!SrcSigned && DstSigned))
1151 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1152 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1155 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1160 SanitizerDebugLocation SanScope(
1162 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1163 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1174 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1181 llvm::Constant *StaticArgs[] = {
1184 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1185 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1187 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1194 llvm::Type *VTy =
V->getType();
1197 return llvm::ConstantInt::getFalse(VTy->getContext());
1199 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1200 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1201 llvm::Twine(Name) +
"." +
V->getName() +
1202 ".negativitycheck");
1207static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1208 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1211 llvm::Type *SrcTy = Src->
getType();
1212 llvm::Type *DstTy = Dst->
getType();
1215 "non-integer llvm type");
1221 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1222 unsigned DstBits = DstTy->getScalarSizeInBits();
1226 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1227 "either the widths should be different, or the signednesses.");
1230 llvm::Value *SrcIsNegative =
1233 llvm::Value *DstIsNegative =
1239 llvm::Value *Check =
nullptr;
1240 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1242 return std::make_pair(
1243 ScalarExprEmitter::ICCK_IntegerSignChange,
1244 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1247void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1248 Value *Dst, QualType DstType,
1249 SourceLocation Loc) {
1250 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1253 llvm::Type *SrcTy = Src->
getType();
1254 llvm::Type *DstTy = Dst->
getType();
1264 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1265 unsigned DstBits = DstTy->getScalarSizeInBits();
1272 if (SrcSigned == DstSigned && SrcBits == DstBits)
1276 if (!SrcSigned && !DstSigned)
1281 if ((DstBits > SrcBits) && DstSigned)
1283 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1284 (SrcBits > DstBits) && SrcSigned) {
1293 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1297 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1301 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1302 SanitizerDebugLocation SanScope(
1304 {SanitizerKind::SO_ImplicitIntegerSignChange,
1305 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1306 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1309 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1310 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1314 ImplicitConversionCheckKind CheckKind;
1315 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1322 CheckKind = Check.first;
1323 Checks.emplace_back(Check.second);
1325 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1326 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1332 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1333 Checks.emplace_back(Check.second);
1337 llvm::Constant *StaticArgs[] = {
1340 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1341 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1343 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1348static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1349 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1355 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1356 if (!SrcSigned && !DstSigned)
1357 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1359 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1361 llvm::Value *Check =
nullptr;
1363 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1365 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1368 return std::make_pair(
1370 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1375static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1376 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1380 llvm::Value *SrcIsNegative =
1383 llvm::Value *DstIsNegative =
1389 llvm::Value *Check =
nullptr;
1391 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1393 return std::make_pair(
1394 ScalarExprEmitter::ICCK_IntegerSignChange,
1395 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1403 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1421 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1422 unsigned DstBits = Info.
Size;
1427 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1429 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1431 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1432 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1436 bool EmitTruncation = DstBits < SrcBits;
1440 bool EmitTruncationFromUnsignedToSigned =
1441 EmitTruncation && DstSigned && !SrcSigned;
1443 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1444 bool BothUnsigned = !SrcSigned && !DstSigned;
1445 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1452 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1457 else if (EmitSignChange) {
1458 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1459 "either the widths should be different, or the signednesses.");
1465 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1466 if (EmitTruncationFromUnsignedToSigned)
1467 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1469 llvm::Constant *StaticArgs[] = {
1472 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1473 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1475 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1479 QualType DstType, llvm::Type *SrcTy,
1481 ScalarConversionOpts Opts) {
1483 llvm::Type *SrcElementTy;
1484 llvm::Type *DstElementTy;
1494 "cannot cast between matrix and non-matrix types");
1495 SrcElementTy = SrcTy;
1496 DstElementTy = DstTy;
1497 SrcElementType = SrcType;
1498 DstElementType = DstType;
1503 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1508 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1510 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1511 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1515 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1522 llvm::Intrinsic::ID IID =
1523 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1524 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1528 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1529 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1532 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1533 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1534 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1536 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1537 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1538 return Builder.CreateFPExt(Src, DstTy,
"conv");
1543Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1546 ScalarConversionOpts Opts) {
1561 return Builder.CreateIsNotNull(Src,
"tobool");
1564 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1567 "Unhandled scalar conversion from a fixed point type to another type.");
1571 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1574 "Unhandled scalar conversion to a fixed point type from another type.");
1577 QualType NoncanonicalSrcType = SrcType;
1578 QualType NoncanonicalDstType = DstType;
1582 if (SrcType == DstType)
return Src;
1586 llvm::Value *OrigSrc = Src;
1587 QualType OrigSrcType = SrcType;
1588 llvm::Type *SrcTy = Src->
getType();
1592 return EmitConversionToBool(Src, SrcType);
1594 llvm::Type *DstTy = ConvertType(DstType);
1599 if (DstTy->isFloatingPointTy()) {
1602 return Builder.CreateFPExt(BitCast, DstTy,
"conv");
1611 Src = Builder.CreateBitCast(Src, CGF.
CGM.
HalfTy);
1614 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1621 if (SrcTy == DstTy) {
1622 if (Opts.EmitImplicitIntegerSignChangeChecks)
1623 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1624 NoncanonicalDstType, Loc);
1632 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1637 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1642 llvm::Value* IntResult =
1643 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1645 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1651 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1658 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1660 "Splatted expr doesn't match with vector element type?");
1664 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1668 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1672 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1673 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1674 if (SrcSize == DstSize)
1675 return Builder.CreateBitCast(Src, DstTy,
"conv");
1688 assert(((SrcElementTy->isIntegerTy() &&
1689 DstElementTy->isIntegerTy()) ||
1690 (SrcElementTy->isFloatingPointTy() &&
1691 DstElementTy->isFloatingPointTy())) &&
1692 "unexpected conversion between a floating-point vector and an "
1696 if (SrcElementTy->isIntegerTy())
1697 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1700 if (SrcSize > DstSize)
1701 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1704 return Builder.CreateFPExt(Src, DstTy,
"conv");
1708 Value *Res =
nullptr;
1709 llvm::Type *ResTy = DstTy;
1716 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1718 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1724 if (SrcTy->isFloatingPointTy()) {
1733 assert(DstTy->isIntegerTy(16) &&
1735 "Only half FP requires extra conversion");
1736 return Builder.CreateBitCast(Res, DstTy);
1742 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1744 if (DstTy != ResTy) {
1745 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1748 assert(ResTy->isIntegerTy(16) &&
1750 "Only half FP requires extra conversion");
1751 Res = Builder.CreateBitCast(Res, ResTy);
1755 if (Opts.EmitImplicitIntegerTruncationChecks)
1756 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1757 NoncanonicalDstType, Loc);
1759 if (Opts.EmitImplicitIntegerSignChangeChecks)
1760 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1761 NoncanonicalDstType, Loc);
1766Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1768 SourceLocation Loc) {
1769 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1772 Result = FPBuilder.CreateFloatingToFixed(Src,
1775 Result = FPBuilder.CreateFixedToFloating(Src,
1777 ConvertType(DstTy));
1783 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1784 DstFPSema.getWidth(),
1785 DstFPSema.isSigned());
1787 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1790 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1797Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1799 SourceLocation Loc) {
1801 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1806 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1807 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1808 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1815 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1818Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1826void ScalarExprEmitter::EmitBinOpCheck(
1827 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1828 const BinOpInfo &Info) {
1831 SmallVector<llvm::Constant *, 4> StaticData;
1832 SmallVector<llvm::Value *, 2> DynamicData;
1840 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1841 if (UO && UO->
getOpcode() == UO_Minus) {
1842 Check = SanitizerHandler::NegateOverflow;
1844 DynamicData.push_back(Info.RHS);
1848 Check = SanitizerHandler::ShiftOutOfBounds;
1850 StaticData.push_back(
1852 StaticData.push_back(
1854 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1856 Check = SanitizerHandler::DivremOverflow;
1860 int ArithOverflowKind = 0;
1863 Check = SanitizerHandler::AddOverflow;
1864 ArithOverflowKind = diag::UBSanArithKind::Add;
1868 Check = SanitizerHandler::SubOverflow;
1869 ArithOverflowKind = diag::UBSanArithKind::Sub;
1873 Check = SanitizerHandler::MulOverflow;
1874 ArithOverflowKind = diag::UBSanArithKind::Mul;
1878 llvm_unreachable(
"unexpected opcode for bin op check");
1882 SanitizerKind::UnsignedIntegerOverflow) ||
1884 SanitizerKind::SignedIntegerOverflow)) {
1888 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1892 DynamicData.push_back(Info.LHS);
1893 DynamicData.push_back(Info.RHS);
1896 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1903Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1911ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1913 unsigned AddrSpace =
1915 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1918 llvm::Type *ExprTy = ConvertType(E->
getType());
1919 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1923Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1925 auto It = E->
begin();
1926 return Builder.getInt((*It)->getValue());
1929Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1937 unsigned LHSElts = LTy->getNumElements();
1945 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1946 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1954 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1955 MTy->getNumElements());
1956 Value* NewV = llvm::PoisonValue::get(RTy);
1957 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1958 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1959 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1961 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1962 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1970 SmallVector<int, 32> Indices;
1974 if (Idx.isSigned() && Idx.isAllOnes())
1975 Indices.push_back(-1);
1977 Indices.push_back(Idx.getZExtValue());
1980 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1983Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1991 if (SrcType == DstType)
return Src;
1994 "ConvertVector source type must be a vector");
1996 "ConvertVector destination type must be a vector");
1998 llvm::Type *SrcTy = Src->
getType();
1999 llvm::Type *DstTy = ConvertType(DstType);
2005 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2006 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2008 assert(SrcTy->isVectorTy() &&
2009 "ConvertVector source IR type must be a vector");
2010 assert(DstTy->isVectorTy() &&
2011 "ConvertVector destination IR type must be a vector");
2016 if (DstEltType->isBooleanType()) {
2017 assert((SrcEltTy->isFloatingPointTy() ||
2020 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2021 if (SrcEltTy->isFloatingPointTy()) {
2022 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2023 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2025 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2030 Value *Res =
nullptr;
2035 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2037 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2039 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2041 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2044 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2045 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2046 if (DstEltType->isSignedIntegerOrEnumerationType())
2047 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2049 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2051 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2052 "Unknown real conversion");
2053 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2054 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2055 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2057 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2063Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2072 return Builder.getInt(
Value);
2076 llvm::Value *
Result = EmitLoadOfLValue(E);
2082 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2083 if (llvm::GetElementPtrInst *GEP =
2084 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2085 if (llvm::Instruction *
Pointer =
2086 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2098Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2099 TestAndClearIgnoreResultAssign();
2107 return EmitLoadOfLValue(E);
2115 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2118 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2121Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2122 MatrixSingleSubscriptExpr *E) {
2123 TestAndClearIgnoreResultAssign();
2126 unsigned NumRows = MatrixTy->getNumRows();
2127 unsigned NumColumns = MatrixTy->getNumColumns();
2131 llvm::MatrixBuilder MB(Builder);
2135 MB.CreateIndexAssumption(RowIdx, NumRows);
2139 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2140 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2142 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2143 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2144 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2145 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2146 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2147 IsMatrixRowMajor,
"matrix_row_idx");
2149 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2150 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2151 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2157Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2158 TestAndClearIgnoreResultAssign();
2166 llvm::MatrixBuilder MB(Builder);
2169 unsigned NumCols = MatrixTy->getNumColumns();
2170 unsigned NumRows = MatrixTy->getNumRows();
2171 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2172 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2173 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2176 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2181 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2186 int MV = SVI->getMaskValue(Idx);
2193 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2194 "Index operand too large for shufflevector mask!");
2195 return C->getZExtValue();
2198Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2199 bool Ignore = TestAndClearIgnoreResultAssign();
2202 assert((Ignore ==
false ||
2204 "init list ignored");
2221 llvm::VectorType *VType =
2222 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2225 if (NumInitElements == 0) {
2227 return EmitNullValue(E->
getType());
2234 if (NumInitElements == 0) {
2236 return EmitNullValue(E->
getType());
2239 if (NumInitElements == 1) {
2240 Expr *InitVector = E->
getInit(0);
2245 return Visit(InitVector);
2248 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2258 unsigned CurIdx = 0;
2259 bool VIsPoisonShuffle =
false;
2260 llvm::Value *
V = llvm::PoisonValue::get(VType);
2261 for (
unsigned i = 0; i != NumInitElements; ++i) {
2264 SmallVector<int, 16> Args;
2266 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2276 ->getNumElements() == ResElts) {
2278 Value *LHS =
nullptr, *RHS =
nullptr;
2283 Args.resize(ResElts, -1);
2285 LHS = EI->getVectorOperand();
2287 VIsPoisonShuffle =
true;
2288 }
else if (VIsPoisonShuffle) {
2291 for (
unsigned j = 0; j != CurIdx; ++j)
2293 Args.push_back(ResElts +
C->getZExtValue());
2294 Args.resize(ResElts, -1);
2297 RHS = EI->getVectorOperand();
2298 VIsPoisonShuffle =
false;
2300 if (!Args.empty()) {
2301 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2307 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2309 VIsPoisonShuffle =
false;
2319 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2322 Value *SVOp = SVI->getOperand(0);
2325 if (OpTy->getNumElements() == ResElts) {
2326 for (
unsigned j = 0; j != CurIdx; ++j) {
2329 if (VIsPoisonShuffle) {
2335 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2337 Args.resize(ResElts, -1);
2339 if (VIsPoisonShuffle)
2349 for (
unsigned j = 0; j != InitElts; ++j)
2351 Args.resize(ResElts, -1);
2352 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2355 for (
unsigned j = 0; j != CurIdx; ++j)
2357 for (
unsigned j = 0; j != InitElts; ++j)
2358 Args.push_back(j + Offset);
2359 Args.resize(ResElts, -1);
2366 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2373 llvm::Type *EltTy = VType->getElementType();
2376 for (; CurIdx < ResElts; ++CurIdx) {
2377 Value *Idx = Builder.getInt32(CurIdx);
2378 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2379 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2391 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2395 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2398 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2417 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2421 if (
const auto *CE = dyn_cast<CastExpr>(E))
2422 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2423 CE->getCastKind() == CK_ArrayToPointerDecay)
2434 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2444 if (ICE->isGLValue())
2459 assert(LoadList.size() >= VecTy->getNumElements() &&
2460 "Flattened type on RHS must have the same number or more elements "
2461 "than vector on LHS.");
2465 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2468 "All flattened source values should be scalars.");
2471 VecTy->getElementType(), Loc);
2472 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2477 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2478 "Flattened type on RHS must have the same number or more elements "
2479 "than vector on LHS.");
2484 for (
unsigned I = 0, E = MatTy->getNumElementsFlattened(); I < E; I++) {
2485 unsigned ColMajorIndex =
2486 (I % MatTy->getNumRows()) * MatTy->getNumColumns() +
2487 (I / MatTy->getNumRows());
2490 "All flattened source values should be scalars.");
2492 RVal.
getScalarVal(), LoadList[ColMajorIndex].getType(),
2493 MatTy->getElementType(), Loc);
2494 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2500 "Destination type must be a vector, matrix, or builtin type.");
2502 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2511 llvm::scope_exit RestoreCurCast(
2512 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2516 QualType DestTy = CE->
getType();
2518 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2522 bool Ignored = TestAndClearIgnoreResultAssign();
2528 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2529 case CK_BuiltinFnToFnPtr:
2530 llvm_unreachable(
"builtin functions are handled elsewhere");
2532 case CK_LValueBitCast:
2533 case CK_ObjCObjectLValueCast: {
2534 Address
Addr = EmitLValue(E).getAddress();
2537 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2540 case CK_LValueToRValueBitCast: {
2546 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2549 case CK_CPointerToObjCPointerCast:
2550 case CK_BlockPointerToObjCPointerCast:
2551 case CK_AnyPointerToBlockPointerCast:
2553 Value *Src = Visit(E);
2554 llvm::Type *SrcTy = Src->
getType();
2555 llvm::Type *DstTy = ConvertType(DestTy);
2566 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2571 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2572 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2573 "Address-space cast must be used to convert address spaces");
2575 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2576 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2578 PT->getPointeeType(),
2589 const QualType SrcType = E->
getType();
2594 Src = Builder.CreateLaunderInvariantGroup(Src);
2602 Src = Builder.CreateStripInvariantGroup(Src);
2607 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2611 if (!PointeeType.
isNull())
2620 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2621 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2624 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2625 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2626 ScalableDstTy = llvm::ScalableVectorType::get(
2627 FixedSrcTy->getElementType(),
2629 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2631 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2632 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2633 llvm::Value *
Result = Builder.CreateInsertVector(
2634 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2636 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2637 if (
Result->getType() != ScalableDstTy)
2639 if (
Result->getType() != DstTy)
2649 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2650 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2653 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2654 FixedDstTy->getElementType()->isIntegerTy(8)) {
2655 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2656 ScalableSrcTy = llvm::ScalableVectorType::get(
2657 ScalableSrcTy->getElementType(),
2659 ScalableSrcTy->getElementCount().getKnownMinValue()));
2660 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2661 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2665 ScalableSrcTy = llvm::ScalableVectorType::get(
2666 FixedDstTy->getElementType(),
2667 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2668 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2670 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2671 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2692 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2695 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2698 case CK_AddressSpaceConversion: {
2701 Result.Val.isNullPointer()) {
2705 if (
Result.HasSideEffects)
2708 ConvertType(DestTy)), DestTy);
2714 ConvertType(DestTy));
2716 case CK_AtomicToNonAtomic:
2717 case CK_NonAtomicToAtomic:
2718 case CK_UserDefinedConversion:
2725 case CK_BaseToDerived: {
2727 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2741 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2749 case CK_UncheckedDerivedToBase:
2750 case CK_DerivedToBase: {
2763 case CK_ArrayToPointerDecay:
2766 case CK_FunctionToPointerDecay:
2767 return EmitLValue(E).getPointer(CGF);
2769 case CK_NullToPointer:
2770 if (MustVisitNullValue(E))
2776 case CK_NullToMemberPointer: {
2777 if (MustVisitNullValue(E))
2780 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2784 case CK_ReinterpretMemberPointer:
2785 case CK_BaseToDerivedMemberPointer:
2786 case CK_DerivedToBaseMemberPointer: {
2787 Value *Src = Visit(E);
2798 case CK_ARCProduceObject:
2800 case CK_ARCConsumeObject:
2802 case CK_ARCReclaimReturnedObject:
2804 case CK_ARCExtendBlockObject:
2807 case CK_CopyAndAutoreleaseBlockObject:
2810 case CK_FloatingRealToComplex:
2811 case CK_FloatingComplexCast:
2812 case CK_IntegralRealToComplex:
2813 case CK_IntegralComplexCast:
2814 case CK_IntegralComplexToFloatingComplex:
2815 case CK_FloatingComplexToIntegralComplex:
2816 case CK_ConstructorConversion:
2818 case CK_HLSLArrayRValue:
2819 llvm_unreachable(
"scalar cast to non-scalar value");
2821 case CK_LValueToRValue:
2823 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2826 case CK_IntegralToPointer: {
2827 Value *Src = Visit(E);
2831 auto DestLLVMTy = ConvertType(DestTy);
2834 llvm::Value* IntResult =
2835 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2837 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2843 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2849 case CK_PointerToIntegral: {
2850 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2851 auto *PtrExpr = Visit(E);
2854 const QualType SrcType = E->
getType();
2859 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2863 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2869 case CK_MatrixCast: {
2870 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2877 case CK_HLSLAggregateSplatCast:
2878 case CK_VectorSplat: {
2879 llvm::Type *DstTy = ConvertType(DestTy);
2880 Value *Elt = Visit(E);
2882 llvm::ElementCount NumElements =
2884 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2887 case CK_FixedPointCast:
2888 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2891 case CK_FixedPointToBoolean:
2893 "Expected src type to be fixed point type");
2894 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2895 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2898 case CK_FixedPointToIntegral:
2900 "Expected src type to be fixed point type");
2901 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2902 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2905 case CK_IntegralToFixedPoint:
2907 "Expected src type to be an integer");
2909 "Expected dest type to be fixed point type");
2910 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2913 case CK_IntegralCast: {
2915 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2916 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2920 ScalarConversionOpts Opts;
2921 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2922 if (!ICE->isPartOfExplicitCast())
2923 Opts = ScalarConversionOpts(CGF.
SanOpts);
2925 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2928 case CK_IntegralToFloating: {
2931 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2933 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2934 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2936 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2937 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2940 case CK_FloatingToIntegral: {
2943 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2945 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2946 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2948 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2949 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2952 case CK_FloatingCast: {
2955 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2956 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2957 if (DstElTy->
castAs<BuiltinType>()->getKind() <
2958 SrcElTy->
castAs<BuiltinType>()->getKind())
2959 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2960 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2962 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2963 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2966 case CK_FixedPointToFloating:
2967 case CK_FloatingToFixedPoint: {
2968 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2969 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2972 case CK_BooleanToSignedIntegral: {
2973 ScalarConversionOpts Opts;
2974 Opts.TreatBooleanAsSigned =
true;
2975 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2978 case CK_IntegralToBoolean:
2979 return EmitIntToBoolConversion(Visit(E));
2980 case CK_PointerToBoolean:
2981 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2982 case CK_FloatingToBoolean: {
2983 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2984 return EmitFloatToBoolConversion(Visit(E));
2986 case CK_MemberPointerToBoolean: {
2987 llvm::Value *MemPtr = Visit(E);
2988 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
2992 case CK_FloatingComplexToReal:
2993 case CK_IntegralComplexToReal:
2996 case CK_FloatingComplexToBoolean:
2997 case CK_IntegralComplexToBoolean: {
3001 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3005 case CK_ZeroToOCLOpaqueType: {
3008 "CK_ZeroToOCLEvent cast on non-event type");
3009 return llvm::Constant::getNullValue(ConvertType(DestTy));
3012 case CK_IntToOCLSampler:
3015 case CK_HLSLVectorTruncation: {
3017 "Destination type must be a vector or builtin type.");
3018 Value *Vec = Visit(E);
3019 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3020 SmallVector<int> Mask;
3021 unsigned NumElts = VecTy->getNumElements();
3022 for (
unsigned I = 0; I != NumElts; ++I)
3025 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3027 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3028 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3030 case CK_HLSLMatrixTruncation: {
3032 "Destination type must be a matrix or builtin type.");
3033 Value *Mat = Visit(E);
3034 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3035 SmallVector<int> Mask;
3036 unsigned NumCols = MatTy->getNumColumns();
3037 unsigned NumRows = MatTy->getNumRows();
3038 unsigned ColOffset = NumCols;
3039 if (
auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>())
3040 ColOffset = SrcMatTy->getNumColumns();
3041 for (
unsigned R = 0; R < NumRows; R++) {
3042 for (
unsigned C = 0;
C < NumCols;
C++) {
3043 unsigned I = R * ColOffset +
C;
3048 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3050 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3051 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3053 case CK_HLSLElementwiseCast: {
3073 llvm_unreachable(
"unknown scalar cast");
3076Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3077 CodeGenFunction::StmtExprEvaluation eval(CGF);
3086Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3087 CodeGenFunction::RunCleanupsScope Scope(CGF);
3091 Scope.ForceCleanup({&
V});
3100 llvm::Value *InVal,
bool IsInc,
3104 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3106 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3107 BinOp.FPFeatures = FPFeatures;
3112llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3113 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3114 llvm::Value *Amount =
3115 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3116 StringRef Name = IsInc ?
"inc" :
"dec";
3117 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3118 case LangOptions::SOB_Defined:
3119 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3120 return Builder.CreateAdd(InVal, Amount, Name);
3122 case LangOptions::SOB_Undefined:
3123 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3124 return Builder.CreateNSWAdd(InVal, Amount, Name);
3126 case LangOptions::SOB_Trapping:
3130 return Builder.CreateNSWAdd(InVal, Amount, Name);
3131 return EmitOverflowCheckedBinOp(Info);
3133 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3158class OMPLastprivateConditionalUpdateRAII {
3160 CodeGenFunction &CGF;
3161 const UnaryOperator *E;
3164 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3165 const UnaryOperator *E)
3167 ~OMPLastprivateConditionalUpdateRAII() {
3176ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3177 bool isInc,
bool isPre) {
3179 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3181 llvm::PHINode *atomicPHI =
nullptr;
3185 QualType SrcType = E->
getType();
3187 int amount = (isInc ? 1 : -1);
3188 bool isSubtraction = !isInc;
3190 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3191 type = atomicTy->getValueType();
3192 if (isInc &&
type->isBooleanType()) {
3195 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3196 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3197 return Builder.getTrue();
3201 return Builder.CreateAtomicRMW(
3202 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3203 llvm::AtomicOrdering::SequentiallyConsistent);
3208 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3209 !(
type->isUnsignedIntegerType() &&
3210 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3212 LangOptions::SOB_Trapping) {
3213 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3214 llvm::AtomicRMWInst::Sub;
3215 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3216 llvm::Instruction::Sub;
3218 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3220 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3221 llvm::AtomicOrdering::SequentiallyConsistent);
3222 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3226 if (
type->isFloatingType()) {
3227 llvm::Type *Ty = ConvertType(
type);
3228 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3229 llvm::AtomicRMWInst::BinOp aop =
3230 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3231 llvm::Instruction::BinaryOps op =
3232 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3233 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3234 llvm::AtomicRMWInst *old =
3236 llvm::AtomicOrdering::SequentiallyConsistent);
3238 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3241 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3244 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3247 Builder.CreateBr(opBB);
3248 Builder.SetInsertPoint(opBB);
3249 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3250 atomicPHI->addIncoming(value, startBB);
3253 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3264 if (isInc &&
type->isBooleanType()) {
3265 value = Builder.getTrue();
3268 }
else if (
type->isIntegerType()) {
3269 QualType promotedType;
3270 bool canPerformLossyDemotionCheck =
false;
3272 bool excludeOverflowPattern =
3277 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3278 canPerformLossyDemotionCheck =
true;
3279 canPerformLossyDemotionCheck &=
3282 canPerformLossyDemotionCheck &=
3284 type, promotedType);
3285 assert((!canPerformLossyDemotionCheck ||
3286 type->isSignedIntegerOrEnumerationType() ||
3288 ConvertType(
type)->getScalarSizeInBits() ==
3289 ConvertType(promotedType)->getScalarSizeInBits()) &&
3290 "The following check expects that if we do promotion to different "
3291 "underlying canonical type, at least one of the types (either "
3292 "base or promoted) will be signed, or the bitwidths will match.");
3295 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3296 SanitizerKind::ImplicitBitfieldConversion) &&
3297 canPerformLossyDemotionCheck) {
3311 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3312 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3313 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3317 ScalarConversionOpts Opts;
3318 if (!LV.isBitField())
3319 Opts = ScalarConversionOpts(CGF.
SanOpts);
3320 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3322 SrcType = promotedType;
3325 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3331 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3332 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3334 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3335 !excludeOverflowPattern &&
3337 SanitizerKind::UnsignedIntegerOverflow, E->
getType())) {
3344 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3345 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3349 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3350 QualType
type = ptr->getPointeeType();
3353 if (
const VariableArrayType *vla
3356 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3359 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3362 elemTy, value, numElts,
false, isSubtraction,
3366 }
else if (
type->isFunctionType()) {
3367 llvm::Value *amt = Builder.getInt32(amount);
3370 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3374 false, isSubtraction,
3379 llvm::Value *amt = Builder.getInt32(amount);
3382 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3385 elemTy, value, amt,
false, isSubtraction,
3390 }
else if (
type->isVectorType()) {
3391 if (
type->hasIntegerRepresentation()) {
3392 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3394 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3396 value = Builder.CreateFAdd(
3398 llvm::ConstantFP::get(value->getType(), amount),
3399 isInc ?
"inc" :
"dec");
3403 }
else if (
type->isRealFloatingType()) {
3406 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3412 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3415 if (value->getType()->isFloatTy())
3416 amt = llvm::ConstantFP::get(VMContext,
3417 llvm::APFloat(
static_cast<float>(amount)));
3418 else if (value->getType()->isDoubleTy())
3419 amt = llvm::ConstantFP::get(VMContext,
3420 llvm::APFloat(
static_cast<double>(amount)));
3424 llvm::APFloat F(
static_cast<float>(amount));
3426 const llvm::fltSemantics *FS;
3429 if (value->getType()->isFP128Ty())
3431 else if (value->getType()->isHalfTy())
3433 else if (value->getType()->isBFloatTy())
3435 else if (value->getType()->isPPC_FP128Ty())
3439 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3440 amt = llvm::ConstantFP::get(VMContext, F);
3442 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3445 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3446 value = Builder.CreateBitCast(value, input->getType());
3450 }
else if (
type->isFixedPointType()) {
3457 Info.Opcode = isInc ? BO_Add : BO_Sub;
3459 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3462 if (
type->isSignedFixedPointType()) {
3463 Info.Opcode = isInc ? BO_Sub : BO_Add;
3464 Info.RHS = Builder.CreateNeg(Info.RHS);
3469 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3471 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3472 value = EmitFixedPointBinOp(Info);
3476 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3479 if (!isInc) size = -size;
3480 llvm::Value *sizeValue =
3481 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3484 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3487 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3489 value = Builder.CreateBitCast(value, input->getType());
3493 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3498 llvm::Value *
success = Pair.second;
3499 atomicPHI->addIncoming(old, curBlock);
3500 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3501 Builder.SetInsertPoint(contBB);
3502 return isPre ? value : input;
3506 if (LV.isBitField()) {
3516 return isPre ? value : input;
3520Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3521 QualType PromotionType) {
3522 QualType promotionTy = PromotionType.
isNull()
3525 Value *result = VisitPlus(E, promotionTy);
3526 if (result && !promotionTy.
isNull())
3527 result = EmitUnPromotedValue(result, E->
getType());
3531Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3532 QualType PromotionType) {
3534 TestAndClearIgnoreResultAssign();
3535 if (!PromotionType.
isNull())
3540Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3541 QualType PromotionType) {
3542 QualType promotionTy = PromotionType.
isNull()
3545 Value *result = VisitMinus(E, promotionTy);
3546 if (result && !promotionTy.
isNull())
3547 result = EmitUnPromotedValue(result, E->
getType());
3551Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3552 QualType PromotionType) {
3553 TestAndClearIgnoreResultAssign();
3555 if (!PromotionType.
isNull())
3561 if (Op->
getType()->isFPOrFPVectorTy())
3562 return Builder.CreateFNeg(Op,
"fneg");
3567 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3569 BinOp.Opcode = BO_Sub;
3572 return EmitSub(BinOp);
3575Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3576 TestAndClearIgnoreResultAssign();
3578 return Builder.CreateNot(Op,
"not");
3581Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3585 VectorKind::Generic) {
3589 if (Oper->
getType()->isFPOrFPVectorTy()) {
3590 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3592 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3594 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3595 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3604 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3607 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3610Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3612 Expr::EvalResult EVResult;
3615 return Builder.getInt(
Value);
3620 llvm::Type* ResultType = ConvertType(E->
getType());
3621 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3623 for (
unsigned i = 0; i != n; ++i) {
3625 llvm::Value *Offset =
nullptr;
3632 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3639 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3643 Offset = Builder.CreateMul(Idx, ElemSize);
3648 FieldDecl *MemberDecl = ON.
getField();
3656 FieldEnd = RD->field_end();
3657 Field != FieldEnd; ++Field, ++i) {
3658 if (*Field == MemberDecl)
3661 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3666 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3669 CurrentType = MemberDecl->
getType();
3674 llvm_unreachable(
"dependent __builtin_offsetof");
3691 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3703ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3704 const UnaryExprOrTypeTraitExpr *E) {
3707 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3708 if (
const VariableArrayType *VAT =
3713 bool EvaluateExtent =
true;
3714 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3716 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3718 if (EvaluateExtent) {
3729 if (Kind == UETT_CountOf)
3738 if (!eltSize.
isOne())
3741 return VlaSize.NumElts;
3744 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3750 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3751 }
else if (E->
getKind() == UETT_VectorElements) {
3753 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3761Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3762 QualType PromotionType) {
3763 QualType promotionTy = PromotionType.
isNull()
3766 Value *result = VisitReal(E, promotionTy);
3767 if (result && !promotionTy.
isNull())
3768 result = EmitUnPromotedValue(result, E->
getType());
3772Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3773 QualType PromotionType) {
3780 if (!PromotionType.
isNull()) {
3782 Op, IgnoreResultAssign,
true);
3797 if (!PromotionType.
isNull())
3802Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3803 QualType PromotionType) {
3804 QualType promotionTy = PromotionType.
isNull()
3807 Value *result = VisitImag(E, promotionTy);
3808 if (result && !promotionTy.
isNull())
3809 result = EmitUnPromotedValue(result, E->
getType());
3813Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3814 QualType PromotionType) {
3821 if (!PromotionType.
isNull()) {
3823 Op,
true, IgnoreResultAssign);
3827 return result.second
3843 else if (!PromotionType.
isNull())
3847 if (!PromotionType.
isNull())
3848 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3849 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3856Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3857 QualType PromotionType) {
3858 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3861Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3862 QualType ExprType) {
3863 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3866Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3868 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3870#define HANDLE_BINOP(OP) \
3872 return Emit##OP(EmitBinOps(BO, PromotionType));
3881 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3884 return VisitImag(UO, PromotionType);
3886 return VisitReal(UO, PromotionType);
3888 return VisitMinus(UO, PromotionType);
3890 return VisitPlus(UO, PromotionType);
3895 auto result = Visit(
const_cast<Expr *
>(E));
3897 if (!PromotionType.
isNull())
3898 return EmitPromotedValue(result, PromotionType);
3900 return EmitUnPromotedValue(result, E->
getType());
3905BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3906 QualType PromotionType) {
3907 TestAndClearIgnoreResultAssign();
3911 if (!PromotionType.
isNull())
3912 Result.Ty = PromotionType;
3921LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3922 const CompoundAssignOperator *E,
3923 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3934 QualType PromotionTypeCR;
3936 if (PromotionTypeCR.
isNull())
3939 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3940 if (!PromotionTypeRHS.
isNull())
3943 OpInfo.RHS = Visit(E->
getRHS());
3944 OpInfo.Ty = PromotionTypeCR;
3951 llvm::PHINode *atomicPHI =
nullptr;
3952 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3953 QualType
type = atomicTy->getValueType();
3954 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3955 !(
type->isUnsignedIntegerType() &&
3956 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3958 LangOptions::SOB_Trapping) {
3959 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3960 llvm::Instruction::BinaryOps Op;
3961 switch (OpInfo.Opcode) {
3963 case BO_MulAssign:
case BO_DivAssign:
3969 AtomicOp = llvm::AtomicRMWInst::Add;
3970 Op = llvm::Instruction::Add;
3973 AtomicOp = llvm::AtomicRMWInst::Sub;
3974 Op = llvm::Instruction::Sub;
3977 AtomicOp = llvm::AtomicRMWInst::And;
3978 Op = llvm::Instruction::And;
3981 AtomicOp = llvm::AtomicRMWInst::Xor;
3982 Op = llvm::Instruction::Xor;
3985 AtomicOp = llvm::AtomicRMWInst::Or;
3986 Op = llvm::Instruction::Or;
3989 llvm_unreachable(
"Invalid compound assignment type");
3991 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3993 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3997 llvm::AtomicRMWInst *OldVal =
4002 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4008 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4010 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4012 Builder.CreateBr(opBB);
4013 Builder.SetInsertPoint(opBB);
4014 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4015 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4016 OpInfo.LHS = atomicPHI;
4019 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4021 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4023 if (!PromotionTypeLHS.
isNull())
4024 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4027 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4038 if (LHSLV.isBitField()) {
4040 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4042 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4043 ScalarConversionOpts(CGF.
SanOpts));
4046 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4050 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4051 llvm::Value *
success = Pair.second;
4052 atomicPHI->addIncoming(old, curBlock);
4053 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4054 Builder.SetInsertPoint(contBB);
4062 if (LHSLV.isBitField()) {
4078Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4079 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4080 bool Ignore = TestAndClearIgnoreResultAssign();
4081 Value *RHS =
nullptr;
4082 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4093 if (!LHS.isVolatileQualified())
4097 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4100void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4101 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4102 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4105 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4106 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4107 SanitizerKind::SO_IntegerDivideByZero));
4111 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4112 Ops.Ty->hasSignedIntegerRepresentation() &&
4114 Ops.mayHaveIntegerOverflow()) {
4117 llvm::Value *IntMin =
4118 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4119 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4121 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4122 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4123 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4125 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4128 if (Checks.size() > 0)
4129 EmitBinOpCheck(Checks, Ops);
4132Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4134 SanitizerDebugLocation SanScope(&CGF,
4135 {SanitizerKind::SO_IntegerDivideByZero,
4136 SanitizerKind::SO_SignedIntegerOverflow,
4137 SanitizerKind::SO_FloatDivideByZero},
4138 SanitizerHandler::DivremOverflow);
4139 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4140 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4141 Ops.Ty->isIntegerType() &&
4142 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4143 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4144 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4145 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4146 Ops.Ty->isRealFloatingType() &&
4147 Ops.mayHaveFloatDivisionByZero()) {
4148 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4149 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4151 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4155 if (Ops.Ty->isConstantMatrixType()) {
4156 llvm::MatrixBuilder MB(Builder);
4163 "first operand must be a matrix");
4165 "second operand must be an arithmetic type");
4166 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4167 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4168 Ops.Ty->hasUnsignedIntegerRepresentation());
4171 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4173 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4174 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4178 else if (Ops.isFixedPointOp())
4179 return EmitFixedPointBinOp(Ops);
4180 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4181 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4183 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4186Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4188 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4189 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4190 Ops.Ty->isIntegerType() &&
4191 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4192 SanitizerDebugLocation SanScope(&CGF,
4193 {SanitizerKind::SO_IntegerDivideByZero,
4194 SanitizerKind::SO_SignedIntegerOverflow},
4195 SanitizerHandler::DivremOverflow);
4196 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4197 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4200 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4201 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4203 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4204 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4206 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4209Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4214 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4215 switch (Ops.Opcode) {
4219 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4220 llvm::Intrinsic::uadd_with_overflow;
4221 OverflowKind = SanitizerHandler::AddOverflow;
4226 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4227 llvm::Intrinsic::usub_with_overflow;
4228 OverflowKind = SanitizerHandler::SubOverflow;
4233 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4234 llvm::Intrinsic::umul_with_overflow;
4235 OverflowKind = SanitizerHandler::MulOverflow;
4238 llvm_unreachable(
"Unsupported operation for overflow detection");
4244 SanitizerDebugLocation SanScope(&CGF,
4245 {SanitizerKind::SO_SignedIntegerOverflow,
4246 SanitizerKind::SO_UnsignedIntegerOverflow},
4252 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4253 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4254 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4257 const std::string *handlerName =
4259 if (handlerName->empty()) {
4262 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4263 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4265 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4266 : SanitizerKind::SO_UnsignedIntegerOverflow;
4267 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4269 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4274 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4275 llvm::BasicBlock *continueBB =
4279 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4283 Builder.SetInsertPoint(overflowBB);
4286 llvm::Type *Int8Ty = CGF.
Int8Ty;
4287 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4288 llvm::FunctionType *handlerTy =
4289 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4290 llvm::FunctionCallee handler =
4295 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4296 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4300 llvm::Value *handlerArgs[] = {
4303 Builder.getInt8(OpID),
4306 llvm::Value *handlerResult =
4310 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4311 Builder.CreateBr(continueBB);
4313 Builder.SetInsertPoint(continueBB);
4314 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4315 phi->addIncoming(result, initialBB);
4316 phi->addIncoming(handlerResult, overflowBB);
4325 bool isSubtraction) {
4330 Value *pointer = op.LHS;
4331 Expr *pointerOperand =
expr->getLHS();
4333 Expr *indexOperand =
expr->getRHS();
4336 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4337 std::swap(pointer,
index);
4338 std::swap(pointerOperand, indexOperand);
4342 index, isSubtraction);
4348 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4352 auto &DL =
CGM.getDataLayout();
4375 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4377 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4378 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4379 PtrTy->getPointerAddressSpace()))
4382 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4383 auto CheckHandler = SanitizerHandler::PointerOverflow;
4385 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4387 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4388 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4390 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4391 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4396 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4407 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4417 llvm::Value *objectSize =
4423 return Builder.CreateBitCast(result, pointer->getType());
4428 getContext().getAsVariableArrayType(elementType)) {
4430 llvm::Value *numElements =
getVLASize(vla).NumElts;
4439 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4459 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4472 bool negMul,
bool negAdd) {
4473 Value *MulOp0 = MulOp->getOperand(0);
4474 Value *MulOp1 = MulOp->getOperand(1);
4476 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4478 Addend = Builder.CreateFNeg(Addend,
"neg");
4480 Value *FMulAdd =
nullptr;
4481 if (Builder.getIsFPConstrained()) {
4483 "Only constrained operation should be created when Builder is in FP "
4484 "constrained mode");
4485 FMulAdd = Builder.CreateConstrainedFPCall(
4486 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4488 {MulOp0, MulOp1, Addend});
4490 FMulAdd = Builder.CreateCall(
4492 {MulOp0, MulOp1, Addend});
4494 MulOp->eraseFromParent();
4509 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4510 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4511 "Only fadd/fsub can be the root of an fmuladd.");
4514 if (!op.FPFeatures.allowFPContractWithinStatement())
4517 Value *LHS = op.LHS;
4518 Value *RHS = op.RHS;
4522 bool NegLHS =
false;
4523 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4524 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4525 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4526 LHS = LHSUnOp->getOperand(0);
4531 bool NegRHS =
false;
4532 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4533 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4534 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4535 RHS = RHSUnOp->getOperand(0);
4543 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4544 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4545 (LHSBinOp->use_empty() || NegLHS)) {
4549 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4552 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4553 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4554 (RHSBinOp->use_empty() || NegRHS)) {
4558 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4562 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4563 if (LHSBinOp->getIntrinsicID() ==
4564 llvm::Intrinsic::experimental_constrained_fmul &&
4565 (LHSBinOp->use_empty() || NegLHS)) {
4569 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4572 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4573 if (RHSBinOp->getIntrinsicID() ==
4574 llvm::Intrinsic::experimental_constrained_fmul &&
4575 (RHSBinOp->use_empty() || NegRHS)) {
4579 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4586Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4587 if (op.LHS->getType()->isPointerTy() ||
4588 op.RHS->getType()->isPointerTy())
4591 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4592 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4593 case LangOptions::SOB_Defined:
4594 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4595 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4597 case LangOptions::SOB_Undefined:
4598 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4599 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4601 case LangOptions::SOB_Trapping:
4602 if (CanElideOverflowCheck(CGF.
getContext(), op))
4603 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4604 return EmitOverflowCheckedBinOp(op);
4609 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4610 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4616 if (op.Ty->isConstantMatrixType()) {
4617 llvm::MatrixBuilder MB(Builder);
4618 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4619 return MB.CreateAdd(op.LHS, op.RHS);
4622 if (op.Ty->isUnsignedIntegerType() &&
4623 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4624 !CanElideOverflowCheck(CGF.
getContext(), op))
4625 return EmitOverflowCheckedBinOp(op);
4627 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4628 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4629 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4632 if (op.isFixedPointOp())
4633 return EmitFixedPointBinOp(op);
4635 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4640Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4642 using llvm::ConstantInt;
4648 QualType ResultTy = op.Ty;
4649 QualType LHSTy, RHSTy;
4650 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4651 RHSTy = BinOp->getRHS()->getType();
4652 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4657 LHSTy = CAO->getComputationLHSType();
4658 ResultTy = CAO->getComputationResultType();
4660 LHSTy = BinOp->getLHS()->getType();
4661 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4662 LHSTy = UnOp->getSubExpr()->getType();
4663 RHSTy = UnOp->getSubExpr()->getType();
4666 Value *LHS = op.LHS;
4667 Value *RHS = op.RHS;
4672 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4676 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4677 switch (op.Opcode) {
4680 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4684 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4688 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4692 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4696 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4700 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4703 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4705 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4707 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4709 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4714 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4716 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4720 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4733 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4739 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4744Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4746 if (!op.LHS->getType()->isPointerTy()) {
4747 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4748 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4749 case LangOptions::SOB_Defined:
4750 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4751 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4753 case LangOptions::SOB_Undefined:
4754 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4755 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4757 case LangOptions::SOB_Trapping:
4758 if (CanElideOverflowCheck(CGF.
getContext(), op))
4759 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4760 return EmitOverflowCheckedBinOp(op);
4765 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4766 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4772 if (op.Ty->isConstantMatrixType()) {
4773 llvm::MatrixBuilder MB(Builder);
4774 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4775 return MB.CreateSub(op.LHS, op.RHS);
4778 if (op.Ty->isUnsignedIntegerType() &&
4779 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4780 !CanElideOverflowCheck(CGF.
getContext(), op))
4781 return EmitOverflowCheckedBinOp(op);
4783 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4784 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4785 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4788 if (op.isFixedPointOp())
4789 return EmitFixedPointBinOp(op);
4791 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4796 if (!op.RHS->getType()->isPointerTy())
4803 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4805 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4806 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4810 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4812 llvm::Value *divisor =
nullptr;
4815 if (
const VariableArrayType *vla
4818 elementType = VlaSize.Type;
4819 divisor = VlaSize.NumElts;
4823 if (!eltSize.
isOne())
4830 CharUnits elementSize;
4839 if (elementSize.
isOne())
4848 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4851Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4853 llvm::IntegerType *Ty;
4854 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4862 llvm::Type *RHSTy = RHS->
getType();
4863 llvm::APInt RHSMax =
4864 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4865 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4866 if (RHSMax.ult(Ty->getBitWidth()))
4867 return llvm::ConstantInt::get(RHSTy, RHSMax);
4868 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4872 const Twine &Name) {
4873 llvm::IntegerType *Ty;
4874 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4879 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4880 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4882 return Builder.CreateURem(
4883 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4886Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4888 if (Ops.isFixedPointOp())
4889 return EmitFixedPointBinOp(Ops);
4893 Value *RHS = Ops.RHS;
4894 if (Ops.LHS->getType() != RHS->
getType())
4895 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4897 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4898 Ops.Ty->hasSignedIntegerRepresentation() &&
4901 bool SanitizeUnsignedBase =
4902 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4903 Ops.Ty->hasUnsignedIntegerRepresentation();
4904 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4905 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4908 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4909 else if ((SanitizeBase || SanitizeExponent) &&
4911 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4912 if (SanitizeSignedBase)
4913 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4914 if (SanitizeUnsignedBase)
4915 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4916 if (SanitizeExponent)
4917 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4919 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4920 SanitizerHandler::ShiftOutOfBounds);
4921 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4922 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4923 llvm::Value *WidthMinusOne =
4924 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4925 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4927 if (SanitizeExponent) {
4929 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4936 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4939 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4940 llvm::Value *PromotedWidthMinusOne =
4941 (RHS == Ops.RHS) ? WidthMinusOne
4942 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4944 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4945 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4954 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4955 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4957 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4958 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4960 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4961 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4962 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4963 Checks.push_back(std::make_pair(
4964 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4965 : SanitizerKind::SO_UnsignedShiftBase));
4968 assert(!Checks.empty());
4969 EmitBinOpCheck(Checks, Ops);
4972 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4975Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4977 if (Ops.isFixedPointOp())
4978 return EmitFixedPointBinOp(Ops);
4982 Value *RHS = Ops.RHS;
4983 if (Ops.LHS->getType() != RHS->
getType())
4984 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4988 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4989 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4991 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4992 SanitizerHandler::ShiftOutOfBounds);
4993 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4994 llvm::Value *
Valid = Builder.CreateICmpULE(
4995 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4996 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4999 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5000 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5001 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5009 default: llvm_unreachable(
"unexpected element type");
5010 case BuiltinType::Char_U:
5011 case BuiltinType::UChar:
5012 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5013 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5014 case BuiltinType::Char_S:
5015 case BuiltinType::SChar:
5016 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5017 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5018 case BuiltinType::UShort:
5019 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5020 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5021 case BuiltinType::Short:
5022 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5023 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5024 case BuiltinType::UInt:
5025 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5026 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5027 case BuiltinType::Int:
5028 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5029 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5030 case BuiltinType::ULong:
5031 case BuiltinType::ULongLong:
5032 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5033 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5034 case BuiltinType::Long:
5035 case BuiltinType::LongLong:
5036 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5037 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5038 case BuiltinType::Float:
5039 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5040 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5041 case BuiltinType::Double:
5042 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5043 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5044 case BuiltinType::UInt128:
5045 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5046 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5047 case BuiltinType::Int128:
5048 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5049 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5053Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5054 llvm::CmpInst::Predicate UICmpOpc,
5055 llvm::CmpInst::Predicate SICmpOpc,
5056 llvm::CmpInst::Predicate FCmpOpc,
5058 TestAndClearIgnoreResultAssign();
5062 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5068 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5070 BinOpInfo BOInfo = EmitBinOps(E);
5071 Value *LHS = BOInfo.LHS;
5072 Value *RHS = BOInfo.RHS;
5078 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5080 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5083 Value *FirstVecArg = LHS,
5084 *SecondVecArg = RHS;
5086 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5090 default: llvm_unreachable(
"is not a comparison operation");
5102 std::swap(FirstVecArg, SecondVecArg);
5109 if (ElementKind == BuiltinType::Float) {
5111 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5112 std::swap(FirstVecArg, SecondVecArg);
5120 if (ElementKind == BuiltinType::Float) {
5122 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5127 std::swap(FirstVecArg, SecondVecArg);
5132 Value *CR6Param = Builder.getInt32(CR6);
5134 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5142 if (ResultTy->getBitWidth() > 1 &&
5144 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5149 if (BOInfo.isFixedPointOp()) {
5150 Result = EmitFixedPointBinOp(BOInfo);
5151 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5152 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5154 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5156 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5158 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5173 LHS = Builder.CreateStripInvariantGroup(LHS);
5175 RHS = Builder.CreateStripInvariantGroup(RHS);
5178 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5184 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5190 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5192 CETy = CTy->getElementType();
5194 LHS.first = Visit(E->
getLHS());
5195 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5198 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5201 CTy->getElementType()) &&
5202 "The element types must always match.");
5205 RHS.first = Visit(E->
getRHS());
5206 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5208 "The element types must always match.");
5211 Value *ResultR, *ResultI;
5215 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5216 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5220 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5221 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5225 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5228 "Complex comparison other than == or != ?");
5229 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5241 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5242 CastKind Kind = ICE->getCastKind();
5243 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5244 *SrcType = ICE->getSubExpr()->getType();
5257 bool Ignore = TestAndClearIgnoreResultAssign();
5291 RHS = Visit(E->
getRHS());
5307 RHS = Visit(E->
getRHS());
5347 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5350Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5358 if (LHS->
getType()->isFPOrFPVectorTy()) {
5359 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5361 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5362 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5364 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5365 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5367 Value *
And = Builder.CreateAnd(LHS, RHS);
5368 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5372 llvm::Type *ResTy = ConvertType(E->
getType());
5391 if (InstrumentRegions &&
5396 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5409 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5415 return llvm::Constant::getNullValue(ResTy);
5426 CodeGenFunction::ConditionalEvaluation eval(CGF);
5435 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5437 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5439 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5448 RHSBlock = Builder.GetInsertBlock();
5453 if (InstrumentRegions &&
5457 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5461 PN->addIncoming(RHSCond, RHSBlockCnt);
5471 PN->addIncoming(RHSCond, RHSBlock);
5480 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5484 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5487Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5495 if (LHS->
getType()->isFPOrFPVectorTy()) {
5496 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5498 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5499 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5501 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5502 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5504 Value *
Or = Builder.CreateOr(LHS, RHS);
5505 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5509 llvm::Type *ResTy = ConvertType(E->
getType());
5528 if (InstrumentRegions &&
5533 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5546 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5552 return llvm::ConstantInt::get(ResTy, 1);
5563 CodeGenFunction::ConditionalEvaluation eval(CGF);
5573 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5575 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5577 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5589 RHSBlock = Builder.GetInsertBlock();
5594 if (InstrumentRegions &&
5598 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5602 PN->addIncoming(RHSCond, RHSBlockCnt);
5608 PN->addIncoming(RHSCond, RHSBlock);
5615 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5618Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5621 return Visit(E->
getRHS());
5646Value *ScalarExprEmitter::
5647VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5648 TestAndClearIgnoreResultAssign();
5651 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5653 Expr *condExpr = E->
getCond();
5661 Expr *live = lhsExpr, *dead = rhsExpr;
5662 if (!CondExprBool) std::swap(live, dead);
5689 llvm::Value *LHS = Visit(lhsExpr);
5690 llvm::Value *RHS = Visit(rhsExpr);
5692 llvm::Type *condType = ConvertType(condExpr->
getType());
5695 unsigned numElem = vecTy->getNumElements();
5696 llvm::Type *elemType = vecTy->getElementType();
5698 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5699 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5700 llvm::Value *tmp = Builder.CreateSExt(
5701 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5702 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5705 llvm::Value *RHSTmp = RHS;
5706 llvm::Value *LHSTmp = LHS;
5707 bool wasCast =
false;
5709 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5710 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5711 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5715 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5716 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5717 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5719 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5729 llvm::Value *LHS = Visit(lhsExpr);
5730 llvm::Value *RHS = Visit(rhsExpr);
5732 llvm::Type *CondType = ConvertType(condExpr->
getType());
5735 if (VecTy->getElementType()->isIntegerTy(1))
5736 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5739 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5741 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5743 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5744 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5754 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5758 llvm::Value *LHS = Visit(lhsExpr);
5759 llvm::Value *RHS = Visit(rhsExpr);
5762 assert(!RHS &&
"LHS and RHS types must match");
5765 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5776 CodeGenFunction::ConditionalEvaluation eval(CGF);
5790 Value *LHS = Visit(lhsExpr);
5793 LHSBlock = Builder.GetInsertBlock();
5794 Builder.CreateBr(ContBlock);
5806 Value *RHS = Visit(rhsExpr);
5809 RHSBlock = Builder.GetInsertBlock();
5819 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5820 PN->addIncoming(LHS, LHSBlock);
5821 PN->addIncoming(RHS, RHSBlock);
5826Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5830Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5832 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5837Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5843 Value *Src,
unsigned NumElementsDst) {
5844 static constexpr int Mask[] = {0, 1, 2, -1};
5845 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5865 const llvm::DataLayout &DL,
5866 Value *Src, llvm::Type *DstTy,
5867 StringRef Name =
"") {
5871 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5872 return Builder.CreateBitCast(Src, DstTy, Name);
5875 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5876 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5879 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5881 if (!DstTy->isIntegerTy())
5882 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5884 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5888 if (!SrcTy->isIntegerTy())
5889 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5891 return Builder.CreateIntToPtr(Src, DstTy, Name);
5894Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5896 llvm::Type *DstTy = ConvertType(E->
getType());
5898 llvm::Type *SrcTy = Src->
getType();
5899 unsigned NumElementsSrc =
5903 unsigned NumElementsDst =
5914 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5919 Src->setName(
"astype");
5926 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5927 auto *Vec4Ty = llvm::FixedVectorType::get(
5933 Src->setName(
"astype");
5938 Src, DstTy,
"astype");
5941Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5953 "Invalid scalar expression to emit");
5955 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5956 .Visit(
const_cast<Expr *
>(E));
5965 "Invalid scalar expression to emit");
5966 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5976 "Invalid complex -> scalar conversion");
5977 return ScalarExprEmitter(*
this)
5978 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5985 if (!PromotionType.
isNull())
5986 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5988 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5994 bool isInc,
bool isPre) {
5995 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6005 llvm::Type *BaseTy =
6021 ScalarExprEmitter Scalar(*
this);
6024#define COMPOUND_OP(Op) \
6025 case BO_##Op##Assign: \
6026 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6063 llvm_unreachable(
"Not valid compound assignment operators");
6066 llvm_unreachable(
"Unhandled compound assignment operator");
6081 llvm::LLVMContext &VMContext,
6087 llvm::Value *TotalOffset =
nullptr;
6093 Value *BasePtr_int =
6094 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6096 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6097 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6098 return {TotalOffset, Builder.getFalse()};
6102 assert(GEP->getPointerOperand() == BasePtr &&
6103 "BasePtr must be the base of the GEP.");
6104 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6106 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6109 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6110 auto *SAddIntrinsic =
6111 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6112 auto *SMulIntrinsic =
6113 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6116 llvm::Value *OffsetOverflows = Builder.getFalse();
6120 llvm::Value *RHS) -> llvm::Value * {
6121 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6124 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6125 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6127 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6130 OffsetOverflows = Builder.getTrue();
6131 return llvm::ConstantInt::get(VMContext, N);
6136 auto *ResultAndOverflow = Builder.CreateCall(
6137 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6138 OffsetOverflows = Builder.CreateOr(
6139 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6140 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6144 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6145 GTI != GTE; ++GTI) {
6146 llvm::Value *LocalOffset;
6147 auto *Index = GTI.getOperand();
6149 if (
auto *STy = GTI.getStructTypeOrNull()) {
6153 LocalOffset = llvm::ConstantInt::get(
6154 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6159 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6160 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6161 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6166 if (!TotalOffset || TotalOffset ==
Zero)
6167 TotalOffset = LocalOffset;
6169 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6172 return {TotalOffset, OffsetOverflows};
6177 ArrayRef<Value *> IdxList,
6178 bool SignedIndices,
bool IsSubtraction,
6179 SourceLocation Loc,
const Twine &Name) {
6180 llvm::Type *PtrTy = Ptr->
getType();
6182 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6183 if (!SignedIndices && !IsSubtraction)
6184 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6186 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6189 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6193 bool PerformNullCheck = !NullPointerIsDefined(
6194 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6197 bool PerformOverflowCheck =
6200 if (!(PerformNullCheck || PerformOverflowCheck))
6203 const auto &DL = CGM.getDataLayout();
6205 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6206 auto CheckHandler = SanitizerHandler::PointerOverflow;
6207 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6208 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6210 GEPOffsetAndOverflow EvaluatedGEP =
6215 "If the offset got constant-folded, we don't expect that there was an "
6218 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6226 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6227 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6229 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6233 if (PerformNullCheck) {
6241 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6242 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6243 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6244 Checks.emplace_back(
Valid, CheckOrdinal);
6247 if (PerformOverflowCheck) {
6252 llvm::Value *ValidGEP;
6253 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6254 if (SignedIndices) {
6260 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6261 auto *PosOrZeroOffset =
6263 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6265 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6266 }
else if (!IsSubtraction) {
6271 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6277 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6279 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6280 Checks.emplace_back(ValidGEP, CheckOrdinal);
6283 assert(!Checks.empty() &&
"Should have produced some checks.");
6285 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6287 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6288 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6294 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6295 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6296 const Twine &Name) {
6297 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6298 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6299 if (!SignedIndices && !IsSubtraction)
6300 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6302 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6306 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6307 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6308 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc, bool isPre, ASTContext &Ctx)
For the purposes of overflow pattern exclusion, does this match the "while(i--)" pattern?
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
ParentMapContext & getParentMapContext()
Returns the dynamic AST node parent map context.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
@ UseSkipPath
Skip (false)
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isMCDCDecisionExpr(const Expr *E) const
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
const Qualifiers & getQuals() const
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
@ PostDecrInWhile
while (count–)
bool isSignedOverflowDefined() const
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
specific_decl_iterator< FieldDecl > field_iterator
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether conversions to and from __fp16 should go through an integer bitcast with i16.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool BitCast(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Result
The result type of a method or function.
const FunctionProtoType * T
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::Type * HalfTy
half, bfloat, float, double
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.