35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/IR/Argument.h"
37#include "llvm/IR/CFG.h"
38#include "llvm/IR/Constants.h"
39#include "llvm/IR/DataLayout.h"
40#include "llvm/IR/DerivedTypes.h"
41#include "llvm/IR/FixedPointBuilder.h"
42#include "llvm/IR/Function.h"
43#include "llvm/IR/GEPNoWrapFlags.h"
44#include "llvm/IR/GetElementPtrTypeIterator.h"
45#include "llvm/IR/GlobalVariable.h"
46#include "llvm/IR/Intrinsics.h"
47#include "llvm/IR/IntrinsicsPowerPC.h"
48#include "llvm/IR/MatrixBuilder.h"
49#include "llvm/IR/Module.h"
50#include "llvm/Support/TypeSize.h"
73bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
75 llvm::APInt &Result) {
78 const auto &LHSAP = LHS->getValue();
79 const auto &RHSAP = RHS->getValue();
80 if (Opcode == BO_Add) {
81 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
82 : LHSAP.uadd_ov(RHSAP, Overflow);
83 }
else if (Opcode == BO_Sub) {
84 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
85 : LHSAP.usub_ov(RHSAP, Overflow);
86 }
else if (Opcode == BO_Mul) {
87 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
88 : LHSAP.umul_ov(RHSAP, Overflow);
89 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
90 if (
Signed && !RHS->isZero())
91 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
103 FPOptions FPFeatures;
107 bool mayHaveIntegerOverflow()
const {
109 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
110 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
111 if (!LHSCI || !RHSCI)
115 return ::mayHaveIntegerOverflow(
120 bool isDivremOp()
const {
126 bool mayHaveIntegerDivisionByZero()
const {
128 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
134 bool mayHaveFloatDivisionByZero()
const {
136 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
137 return CFP->isZero();
144 bool isFixedPointOp()
const {
147 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
148 QualType LHSType = BinOp->getLHS()->getType();
149 QualType RHSType = BinOp->getRHS()->getType();
152 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
153 return UnOp->getSubExpr()->getType()->isFixedPointType();
158 bool rhsHasSignedIntegerRepresentation()
const {
159 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
160 QualType RHSType = BinOp->getRHS()->getType();
167static bool MustVisitNullValue(
const Expr *E) {
190static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
195static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
197 "Expected a unary or binary operator");
201 if (!Op.mayHaveIntegerOverflow())
204 if (Op.Ty->isSignedIntegerType() &&
210 if (Op.Ty->isUnsignedIntegerType() &&
231 if (BO->hasExcludedOverflowPattern())
247 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
253 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
254 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
258class ScalarExprEmitter
260 CodeGenFunction &CGF;
261 CGBuilderTy &Builder;
262 bool IgnoreResultAssign;
263 llvm::LLVMContext &VMContext;
266 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
267 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
268 VMContext(cgf.getLLVMContext()) {
275 bool TestAndClearIgnoreResultAssign() {
276 bool I = IgnoreResultAssign;
277 IgnoreResultAssign =
false;
281 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
282 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
288 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
289 const BinOpInfo &Info);
291 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
295 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
296 const AlignValueAttr *AVAttr =
nullptr;
297 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
298 const ValueDecl *VD = DRE->getDecl();
301 if (
const auto *TTy =
303 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
313 AVAttr = VD->
getAttr<AlignValueAttr>();
318 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
319 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
332 Value *EmitLoadOfLValue(
const Expr *E) {
336 EmitLValueAlignmentAssumption(E,
V);
342 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
346 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
347 Value *Src, QualType SrcType, QualType DstType,
348 llvm::Type *DstTy, SourceLocation Loc);
353 enum ImplicitConversionCheckKind :
unsigned char {
354 ICCK_IntegerTruncation = 0,
355 ICCK_UnsignedIntegerTruncation = 1,
356 ICCK_SignedIntegerTruncation = 2,
357 ICCK_IntegerSignChange = 3,
358 ICCK_SignedIntegerTruncationOrSignChange = 4,
363 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
364 QualType DstType, SourceLocation Loc);
369 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
370 QualType DstType, SourceLocation Loc);
374 struct ScalarConversionOpts {
375 bool TreatBooleanAsSigned;
376 bool EmitImplicitIntegerTruncationChecks;
377 bool EmitImplicitIntegerSignChangeChecks;
379 ScalarConversionOpts()
380 : TreatBooleanAsSigned(
false),
381 EmitImplicitIntegerTruncationChecks(
false),
382 EmitImplicitIntegerSignChangeChecks(
false) {}
384 ScalarConversionOpts(clang::SanitizerSet SanOpts)
385 : TreatBooleanAsSigned(
false),
386 EmitImplicitIntegerTruncationChecks(
387 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
388 EmitImplicitIntegerSignChangeChecks(
389 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
391 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
392 llvm::Type *SrcTy, llvm::Type *DstTy,
393 ScalarConversionOpts Opts);
395 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
397 ScalarConversionOpts Opts = ScalarConversionOpts());
401 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
407 QualType SrcTy, QualType DstTy,
411 Value *EmitNullValue(QualType Ty);
416 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
417 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
421 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
424 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
431 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
432 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
438 ZI->eraseFromParent();
443 return Builder.CreateIsNotNull(
V,
"tobool");
450 Value *Visit(Expr *E) {
451 ApplyDebugLocation DL(CGF, E);
452 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
455 Value *VisitStmt(Stmt *S) {
457 llvm_unreachable(
"Stmt can't have complex result type!");
459 Value *VisitExpr(Expr *S);
461 Value *VisitConstantExpr(ConstantExpr *E) {
467 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
477 Value *VisitParenExpr(ParenExpr *PE) {
480 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
483 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
484 return Visit(
GE->getResultExpr());
486 Value *VisitCoawaitExpr(CoawaitExpr *S) {
489 Value *VisitCoyieldExpr(CoyieldExpr *S) {
492 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
497 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
498 return Builder.getInt(E->
getValue());
500 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
501 return Builder.getInt(E->
getValue());
503 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
504 return llvm::ConstantFP::get(VMContext, E->
getValue());
506 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
507 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
509 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
510 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
512 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
513 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
515 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
519 return EmitNullValue(E->
getType());
521 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
522 return EmitNullValue(E->
getType());
524 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
525 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
526 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
528 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
531 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
535 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
539 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
540 Value *VisitEmbedExpr(EmbedExpr *E);
542 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
551 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
552 llvm_unreachable(
"Codegen for this isn't defined/implemented");
556 Value *VisitDeclRefExpr(DeclRefExpr *E) {
559 return EmitLoadOfLValue(E);
562 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
565 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
568 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
569 return EmitLoadOfLValue(E);
571 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
574 return EmitLoadOfLValue(E);
578 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
584 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
590 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
595 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
596 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
597 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
598 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
599 Value *VisitMemberExpr(MemberExpr *E);
600 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
601 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
607 return EmitLoadOfLValue(E);
610 Value *VisitInitListExpr(InitListExpr *E);
612 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
614 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
618 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
619 return EmitNullValue(E->
getType());
621 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
623 return VisitCastExpr(E);
627 Value *VisitCallExpr(
const CallExpr *E) {
629 return EmitLoadOfLValue(E);
633 EmitLValueAlignmentAssumption(E,
V);
637 Value *VisitStmtExpr(
const StmtExpr *E);
640 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
642 return EmitScalarPrePostIncDec(E, LV,
false,
false);
644 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
646 return EmitScalarPrePostIncDec(E, LV,
true,
false);
648 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
650 return EmitScalarPrePostIncDec(E, LV,
false,
true);
652 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
654 return EmitScalarPrePostIncDec(E, LV,
true,
true);
657 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
661 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
662 bool isInc,
bool isPre);
665 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
669 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
671 Value *VisitUnaryDeref(
const UnaryOperator *E) {
674 return EmitLoadOfLValue(E);
677 Value *VisitUnaryPlus(
const UnaryOperator *E,
678 QualType PromotionType = QualType());
679 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
680 Value *VisitUnaryMinus(
const UnaryOperator *E,
681 QualType PromotionType = QualType());
682 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
684 Value *VisitUnaryNot (
const UnaryOperator *E);
685 Value *VisitUnaryLNot (
const UnaryOperator *E);
686 Value *VisitUnaryReal(
const UnaryOperator *E,
687 QualType PromotionType = QualType());
688 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
689 Value *VisitUnaryImag(
const UnaryOperator *E,
690 QualType PromotionType = QualType());
691 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
692 Value *VisitUnaryExtension(
const UnaryOperator *E) {
697 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
698 return EmitLoadOfLValue(E);
700 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
708 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
709 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
712 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
713 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
716 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
720 Value *VisitExprWithCleanups(ExprWithCleanups *E);
721 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
724 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
729 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
731 return llvm::ConstantInt::get(ConvertType(E->
getType()),
734 return llvm::ConstantInt::get(ConvertType(E->
getType()),
738 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
746 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
747 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
750 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
751 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
754 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
764 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
765 return EmitNullValue(E->
getType());
768 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
773 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
774 return Builder.getInt1(E->
getValue());
778 Value *EmitMul(
const BinOpInfo &Ops) {
779 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
780 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
781 case LangOptions::SOB_Defined:
782 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
783 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
785 case LangOptions::SOB_Undefined:
786 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
787 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
789 case LangOptions::SOB_Trapping:
790 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
791 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
792 return EmitOverflowCheckedBinOp(Ops);
796 if (Ops.Ty->isConstantMatrixType()) {
797 llvm::MatrixBuilder MB(Builder);
801 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
802 BO->getLHS()->getType().getCanonicalType());
803 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
804 BO->getRHS()->getType().getCanonicalType());
805 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
806 if (LHSMatTy && RHSMatTy)
807 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
808 LHSMatTy->getNumColumns(),
809 RHSMatTy->getNumColumns());
810 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
813 if (Ops.Ty->isUnsignedIntegerType() &&
814 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
815 !CanElideOverflowCheck(CGF.
getContext(), Ops))
816 return EmitOverflowCheckedBinOp(Ops);
818 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
820 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
821 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
823 if (Ops.isFixedPointOp())
824 return EmitFixedPointBinOp(Ops);
825 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
829 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
832 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
833 llvm::Value *
Zero,
bool isDiv);
835 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
841 Value *EmitDiv(
const BinOpInfo &Ops);
842 Value *EmitRem(
const BinOpInfo &Ops);
843 Value *EmitAdd(
const BinOpInfo &Ops);
844 Value *EmitSub(
const BinOpInfo &Ops);
845 Value *EmitShl(
const BinOpInfo &Ops);
846 Value *EmitShr(
const BinOpInfo &Ops);
847 Value *EmitAnd(
const BinOpInfo &Ops) {
848 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
850 Value *EmitXor(
const BinOpInfo &Ops) {
851 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
853 Value *EmitOr (
const BinOpInfo &Ops) {
854 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
858 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
860 BinOpInfo EmitBinOps(
const BinaryOperator *E,
861 QualType PromotionTy = QualType());
863 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
864 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
865 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
867 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
868 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
871 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
872 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
874 QualType getPromotionType(QualType Ty) {
876 if (
auto *CT = Ty->
getAs<ComplexType>()) {
877 QualType ElementType = CT->getElementType();
883 if (
auto *VT = Ty->
getAs<VectorType>()) {
884 unsigned NumElements = VT->getNumElements();
894#define HANDLEBINOP(OP) \
895 Value *VisitBin##OP(const BinaryOperator *E) { \
896 QualType promotionTy = getPromotionType(E->getType()); \
897 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
898 if (result && !promotionTy.isNull()) \
899 result = EmitUnPromotedValue(result, E->getType()); \
902 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
903 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
904 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
920 llvm::CmpInst::Predicate SICmpOpc,
921 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
922#define VISITCOMP(CODE, UI, SI, FP, SIG) \
923 Value *VisitBin##CODE(const BinaryOperator *E) { \
924 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
925 llvm::FCmpInst::FP, SIG); }
926 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
940 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
941 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
943 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
948 Value *VisitBlockExpr(
const BlockExpr *BE);
949 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
950 Value *VisitChooseExpr(ChooseExpr *CE);
951 Value *VisitVAArgExpr(VAArgExpr *VE);
952 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
955 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
958 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
961 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
964 Value *VisitAsTypeExpr(AsTypeExpr *CE);
965 Value *VisitAtomicExpr(AtomicExpr *AE);
966 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
979 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
982 return EmitFloatToBoolConversion(Src);
984 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
988 "Unknown scalar type to convert");
991 return EmitIntToBoolConversion(Src);
994 return EmitPointerToBoolConversion(Src, SrcType);
997void ScalarExprEmitter::EmitFloatConversionCheck(
998 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
999 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1000 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1004 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1005 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1006 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1007 using llvm::APFloat;
1010 llvm::Value *Check =
nullptr;
1011 const llvm::fltSemantics &SrcSema =
1021 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1022 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1023 APFloat::opOverflow)
1026 MinSrc = APFloat::getInf(SrcSema,
true);
1030 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1033 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1034 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1035 APFloat::opOverflow)
1038 MaxSrc = APFloat::getInf(SrcSema,
false);
1042 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1047 const llvm::fltSemantics &Sema =
1050 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1051 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1055 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1057 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1058 Check = Builder.CreateAnd(GE, LE);
1063 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1069static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1070 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1073 llvm::Type *SrcTy = Src->
getType();
1074 llvm::Type *DstTy = Dst->
getType();
1079 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1081 "non-integer llvm type");
1088 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1090 if (!SrcSigned && !DstSigned) {
1091 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1092 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1094 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1095 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1098 llvm::Value *Check =
nullptr;
1100 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1102 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1104 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1112void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1113 Value *Dst, QualType DstType,
1114 SourceLocation Loc) {
1124 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1125 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1127 if (SrcBits <= DstBits)
1130 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1137 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1138 (!SrcSigned && DstSigned))
1141 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1142 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1145 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1150 SanitizerDebugLocation SanScope(
1152 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1153 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1164 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1171 llvm::Constant *StaticArgs[] = {
1174 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1175 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1177 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1184 llvm::Type *VTy =
V->getType();
1187 return llvm::ConstantInt::getFalse(VTy->getContext());
1189 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1190 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1191 llvm::Twine(Name) +
"." +
V->getName() +
1192 ".negativitycheck");
1197static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1198 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1201 llvm::Type *SrcTy = Src->
getType();
1202 llvm::Type *DstTy = Dst->
getType();
1205 "non-integer llvm type");
1211 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1212 unsigned DstBits = DstTy->getScalarSizeInBits();
1216 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1217 "either the widths should be different, or the signednesses.");
1220 llvm::Value *SrcIsNegative =
1223 llvm::Value *DstIsNegative =
1229 llvm::Value *Check =
nullptr;
1230 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1232 return std::make_pair(
1233 ScalarExprEmitter::ICCK_IntegerSignChange,
1234 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1237void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1238 Value *Dst, QualType DstType,
1239 SourceLocation Loc) {
1240 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1243 llvm::Type *SrcTy = Src->
getType();
1244 llvm::Type *DstTy = Dst->
getType();
1254 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1255 unsigned DstBits = DstTy->getScalarSizeInBits();
1262 if (SrcSigned == DstSigned && SrcBits == DstBits)
1266 if (!SrcSigned && !DstSigned)
1271 if ((DstBits > SrcBits) && DstSigned)
1273 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1274 (SrcBits > DstBits) && SrcSigned) {
1283 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1287 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1291 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1292 SanitizerDebugLocation SanScope(
1294 {SanitizerKind::SO_ImplicitIntegerSignChange,
1295 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1296 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1299 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1300 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1304 ImplicitConversionCheckKind CheckKind;
1305 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1312 CheckKind = Check.first;
1313 Checks.emplace_back(Check.second);
1315 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1316 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1322 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1323 Checks.emplace_back(Check.second);
1327 llvm::Constant *StaticArgs[] = {
1330 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1331 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1333 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1338static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1339 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1345 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1346 if (!SrcSigned && !DstSigned)
1347 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1349 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1351 llvm::Value *Check =
nullptr;
1353 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1355 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1358 return std::make_pair(
1360 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1365static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1366 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1370 llvm::Value *SrcIsNegative =
1373 llvm::Value *DstIsNegative =
1379 llvm::Value *Check =
nullptr;
1381 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1383 return std::make_pair(
1384 ScalarExprEmitter::ICCK_IntegerSignChange,
1385 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1393 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1411 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1412 unsigned DstBits = Info.
Size;
1417 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1419 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1421 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1422 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1426 bool EmitTruncation = DstBits < SrcBits;
1430 bool EmitTruncationFromUnsignedToSigned =
1431 EmitTruncation && DstSigned && !SrcSigned;
1433 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1434 bool BothUnsigned = !SrcSigned && !DstSigned;
1435 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1442 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1447 else if (EmitSignChange) {
1448 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1449 "either the widths should be different, or the signednesses.");
1455 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1456 if (EmitTruncationFromUnsignedToSigned)
1457 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1459 llvm::Constant *StaticArgs[] = {
1462 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1463 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1465 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1469 QualType DstType, llvm::Type *SrcTy,
1471 ScalarConversionOpts Opts) {
1473 llvm::Type *SrcElementTy;
1474 llvm::Type *DstElementTy;
1484 "cannot cast between matrix and non-matrix types");
1485 SrcElementTy = SrcTy;
1486 DstElementTy = DstTy;
1487 SrcElementType = SrcType;
1488 DstElementType = DstType;
1493 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1498 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1500 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1501 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1505 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1512 llvm::Intrinsic::ID IID =
1513 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1514 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1518 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1519 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1522 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1523 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1524 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1526 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1527 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1528 return Builder.CreateFPExt(Src, DstTy,
"conv");
1533Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1536 ScalarConversionOpts Opts) {
1551 return Builder.CreateIsNotNull(Src,
"tobool");
1554 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1557 "Unhandled scalar conversion from a fixed point type to another type.");
1561 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1564 "Unhandled scalar conversion to a fixed point type from another type.");
1567 QualType NoncanonicalSrcType = SrcType;
1568 QualType NoncanonicalDstType = DstType;
1572 if (SrcType == DstType)
return Src;
1576 llvm::Value *OrigSrc = Src;
1577 QualType OrigSrcType = SrcType;
1578 llvm::Type *SrcTy = Src->
getType();
1582 return EmitConversionToBool(Src, SrcType);
1584 llvm::Type *DstTy = ConvertType(DstType);
1589 if (DstTy->isFloatingPointTy()) {
1591 return Builder.CreateCall(
1599 Src = Builder.CreateCall(
1604 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1612 if (SrcTy == DstTy) {
1613 if (Opts.EmitImplicitIntegerSignChangeChecks)
1614 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1615 NoncanonicalDstType, Loc);
1623 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1628 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1633 llvm::Value* IntResult =
1634 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1636 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1642 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1649 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1651 "Splatted expr doesn't match with vector element type?");
1655 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1659 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1663 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1664 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1665 if (SrcSize == DstSize)
1666 return Builder.CreateBitCast(Src, DstTy,
"conv");
1679 assert(((SrcElementTy->isIntegerTy() &&
1680 DstElementTy->isIntegerTy()) ||
1681 (SrcElementTy->isFloatingPointTy() &&
1682 DstElementTy->isFloatingPointTy())) &&
1683 "unexpected conversion between a floating-point vector and an "
1687 if (SrcElementTy->isIntegerTy())
1688 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1691 if (SrcSize > DstSize)
1692 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1695 return Builder.CreateFPExt(Src, DstTy,
"conv");
1699 Value *Res =
nullptr;
1700 llvm::Type *ResTy = DstTy;
1707 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1709 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1715 if (SrcTy->isFloatingPointTy()) {
1719 return Builder.CreateCall(
1722 return Builder.CreateFPTrunc(Src, DstTy);
1727 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1729 if (DstTy != ResTy) {
1731 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1732 Res = Builder.CreateCall(
1736 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1740 if (Opts.EmitImplicitIntegerTruncationChecks)
1741 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1742 NoncanonicalDstType, Loc);
1744 if (Opts.EmitImplicitIntegerSignChangeChecks)
1745 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1746 NoncanonicalDstType, Loc);
1751Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1753 SourceLocation Loc) {
1754 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1757 Result = FPBuilder.CreateFloatingToFixed(Src,
1760 Result = FPBuilder.CreateFixedToFloating(Src,
1762 ConvertType(DstTy));
1768 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1769 DstFPSema.getWidth(),
1770 DstFPSema.isSigned());
1772 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1775 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1782Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1784 SourceLocation Loc) {
1786 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1791 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1792 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1793 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1800 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1803Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1811void ScalarExprEmitter::EmitBinOpCheck(
1812 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1813 const BinOpInfo &Info) {
1816 SmallVector<llvm::Constant *, 4> StaticData;
1817 SmallVector<llvm::Value *, 2> DynamicData;
1825 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1826 if (UO && UO->
getOpcode() == UO_Minus) {
1827 Check = SanitizerHandler::NegateOverflow;
1829 DynamicData.push_back(Info.RHS);
1833 Check = SanitizerHandler::ShiftOutOfBounds;
1835 StaticData.push_back(
1837 StaticData.push_back(
1839 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1841 Check = SanitizerHandler::DivremOverflow;
1845 int ArithOverflowKind = 0;
1848 Check = SanitizerHandler::AddOverflow;
1849 ArithOverflowKind = diag::UBSanArithKind::Add;
1853 Check = SanitizerHandler::SubOverflow;
1854 ArithOverflowKind = diag::UBSanArithKind::Sub;
1858 Check = SanitizerHandler::MulOverflow;
1859 ArithOverflowKind = diag::UBSanArithKind::Mul;
1863 llvm_unreachable(
"unexpected opcode for bin op check");
1867 SanitizerKind::UnsignedIntegerOverflow) ||
1869 SanitizerKind::SignedIntegerOverflow)) {
1873 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1877 DynamicData.push_back(Info.LHS);
1878 DynamicData.push_back(Info.RHS);
1881 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1888Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1896ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1898 unsigned AddrSpace =
1900 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1903 llvm::Type *ExprTy = ConvertType(E->
getType());
1904 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1908Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1910 auto It = E->
begin();
1911 return Builder.getInt((*It)->getValue());
1914Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1922 unsigned LHSElts = LTy->getNumElements();
1930 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1931 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1939 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1940 MTy->getNumElements());
1941 Value* NewV = llvm::PoisonValue::get(RTy);
1942 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1943 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1944 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1946 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1947 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1955 SmallVector<int, 32> Indices;
1959 if (Idx.isSigned() && Idx.isAllOnes())
1960 Indices.push_back(-1);
1962 Indices.push_back(Idx.getZExtValue());
1965 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1968Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1976 if (SrcType == DstType)
return Src;
1979 "ConvertVector source type must be a vector");
1981 "ConvertVector destination type must be a vector");
1983 llvm::Type *SrcTy = Src->
getType();
1984 llvm::Type *DstTy = ConvertType(DstType);
1990 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
1991 DstEltType = DstType->
castAs<VectorType>()->getElementType();
1993 assert(SrcTy->isVectorTy() &&
1994 "ConvertVector source IR type must be a vector");
1995 assert(DstTy->isVectorTy() &&
1996 "ConvertVector destination IR type must be a vector");
2001 if (DstEltType->isBooleanType()) {
2002 assert((SrcEltTy->isFloatingPointTy() ||
2005 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2006 if (SrcEltTy->isFloatingPointTy()) {
2007 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2008 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2010 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2015 Value *Res =
nullptr;
2020 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2022 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2024 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2026 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2029 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2030 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2031 if (DstEltType->isSignedIntegerOrEnumerationType())
2032 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2034 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2036 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2037 "Unknown real conversion");
2038 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2039 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2040 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2042 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2048Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2057 return Builder.getInt(
Value);
2061 llvm::Value *
Result = EmitLoadOfLValue(E);
2067 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2068 if (llvm::GetElementPtrInst *GEP =
2069 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2070 if (llvm::Instruction *
Pointer =
2071 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2083Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2084 TestAndClearIgnoreResultAssign();
2092 return EmitLoadOfLValue(E);
2100 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2103 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2106Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2107 TestAndClearIgnoreResultAssign();
2115 unsigned NumRows = MatrixTy->getNumRows();
2116 llvm::MatrixBuilder MB(Builder);
2117 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2119 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2124 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2129 int MV = SVI->getMaskValue(Idx);
2136 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2137 "Index operand too large for shufflevector mask!");
2138 return C->getZExtValue();
2141Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2142 bool Ignore = TestAndClearIgnoreResultAssign();
2145 assert(Ignore ==
false ||
2147 "init list ignored");
2164 llvm::VectorType *VType =
2165 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2168 if (NumInitElements == 0) {
2170 return EmitNullValue(E->
getType());
2177 if (NumInitElements == 0) {
2179 return EmitNullValue(E->
getType());
2182 if (NumInitElements == 1) {
2183 Expr *InitVector = E->
getInit(0);
2188 return Visit(InitVector);
2191 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2201 unsigned CurIdx = 0;
2202 bool VIsPoisonShuffle =
false;
2203 llvm::Value *
V = llvm::PoisonValue::get(VType);
2204 for (
unsigned i = 0; i != NumInitElements; ++i) {
2207 SmallVector<int, 16> Args;
2209 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2219 ->getNumElements() == ResElts) {
2221 Value *LHS =
nullptr, *RHS =
nullptr;
2226 Args.resize(ResElts, -1);
2228 LHS = EI->getVectorOperand();
2230 VIsPoisonShuffle =
true;
2231 }
else if (VIsPoisonShuffle) {
2234 for (
unsigned j = 0; j != CurIdx; ++j)
2236 Args.push_back(ResElts +
C->getZExtValue());
2237 Args.resize(ResElts, -1);
2240 RHS = EI->getVectorOperand();
2241 VIsPoisonShuffle =
false;
2243 if (!Args.empty()) {
2244 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2250 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2252 VIsPoisonShuffle =
false;
2262 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2265 Value *SVOp = SVI->getOperand(0);
2268 if (OpTy->getNumElements() == ResElts) {
2269 for (
unsigned j = 0; j != CurIdx; ++j) {
2272 if (VIsPoisonShuffle) {
2278 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2280 Args.resize(ResElts, -1);
2282 if (VIsPoisonShuffle)
2292 for (
unsigned j = 0; j != InitElts; ++j)
2294 Args.resize(ResElts, -1);
2295 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2298 for (
unsigned j = 0; j != CurIdx; ++j)
2300 for (
unsigned j = 0; j != InitElts; ++j)
2301 Args.push_back(j + Offset);
2302 Args.resize(ResElts, -1);
2309 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2316 llvm::Type *EltTy = VType->getElementType();
2319 for (; CurIdx < ResElts; ++CurIdx) {
2320 Value *Idx = Builder.getInt32(CurIdx);
2321 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2322 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2334 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2338 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2341 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2360 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2364 if (
const auto *CE = dyn_cast<CastExpr>(E))
2365 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2366 CE->getCastKind() == CK_ArrayToPointerDecay)
2377 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2387 if (ICE->isGLValue())
2404 assert(SrcTypes.size() >= VecTy->getNumElements() &&
2405 "Flattened type on RHS must have more elements than vector on LHS.");
2409 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2411 llvm::Value *Idx = LoadGEPList[I].second;
2412 Load = Idx ? CGF.
Builder.CreateExtractElement(Load, Idx,
"vec.extract")
2415 Load, SrcTypes[I], VecTy->getElementType(), Loc);
2416 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2422 "Destination type must be a vector or builtin type.");
2424 llvm::Value *Idx = LoadGEPList[0].second;
2426 Idx ? CGF.
Builder.CreateExtractElement(Load, Idx,
"vec.extract") : Load;
2435 QualType DestTy = CE->
getType();
2437 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2441 bool Ignored = TestAndClearIgnoreResultAssign();
2447 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2448 case CK_BuiltinFnToFnPtr:
2449 llvm_unreachable(
"builtin functions are handled elsewhere");
2451 case CK_LValueBitCast:
2452 case CK_ObjCObjectLValueCast: {
2453 Address
Addr = EmitLValue(E).getAddress();
2456 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2459 case CK_LValueToRValueBitCast: {
2465 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2468 case CK_CPointerToObjCPointerCast:
2469 case CK_BlockPointerToObjCPointerCast:
2470 case CK_AnyPointerToBlockPointerCast:
2472 Value *Src = Visit(E);
2473 llvm::Type *SrcTy = Src->
getType();
2474 llvm::Type *DstTy = ConvertType(DestTy);
2485 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2490 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2491 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2492 "Address-space cast must be used to convert address spaces");
2494 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2495 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2497 PT->getPointeeType(),
2508 const QualType SrcType = E->
getType();
2513 Src = Builder.CreateLaunderInvariantGroup(Src);
2521 Src = Builder.CreateStripInvariantGroup(Src);
2526 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2530 if (!PointeeType.
isNull())
2539 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2540 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2543 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2544 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2545 ScalableDstTy = llvm::ScalableVectorType::get(
2546 FixedSrcTy->getElementType(),
2548 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2550 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2551 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2552 llvm::Value *
Result = Builder.CreateInsertVector(
2553 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2555 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2556 if (
Result->getType() != ScalableDstTy)
2558 if (
Result->getType() != DstTy)
2568 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2569 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2572 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2573 FixedDstTy->getElementType()->isIntegerTy(8)) {
2574 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2575 ScalableSrcTy = llvm::ScalableVectorType::get(
2576 ScalableSrcTy->getElementType(),
2578 ScalableSrcTy->getElementCount().getKnownMinValue()));
2579 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2580 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2584 ScalableSrcTy = llvm::ScalableVectorType::get(
2585 FixedDstTy->getElementType(),
2586 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2587 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2589 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2590 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2611 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2614 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2617 case CK_AddressSpaceConversion: {
2620 Result.Val.isNullPointer()) {
2624 if (
Result.HasSideEffects)
2627 ConvertType(DestTy)), DestTy);
2633 ConvertType(DestTy));
2635 case CK_AtomicToNonAtomic:
2636 case CK_NonAtomicToAtomic:
2637 case CK_UserDefinedConversion:
2644 case CK_BaseToDerived: {
2646 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2660 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2668 case CK_UncheckedDerivedToBase:
2669 case CK_DerivedToBase: {
2682 case CK_ArrayToPointerDecay:
2685 case CK_FunctionToPointerDecay:
2686 return EmitLValue(E).getPointer(CGF);
2688 case CK_NullToPointer:
2689 if (MustVisitNullValue(E))
2695 case CK_NullToMemberPointer: {
2696 if (MustVisitNullValue(E))
2699 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2703 case CK_ReinterpretMemberPointer:
2704 case CK_BaseToDerivedMemberPointer:
2705 case CK_DerivedToBaseMemberPointer: {
2706 Value *Src = Visit(E);
2717 case CK_ARCProduceObject:
2719 case CK_ARCConsumeObject:
2721 case CK_ARCReclaimReturnedObject:
2723 case CK_ARCExtendBlockObject:
2726 case CK_CopyAndAutoreleaseBlockObject:
2729 case CK_FloatingRealToComplex:
2730 case CK_FloatingComplexCast:
2731 case CK_IntegralRealToComplex:
2732 case CK_IntegralComplexCast:
2733 case CK_IntegralComplexToFloatingComplex:
2734 case CK_FloatingComplexToIntegralComplex:
2735 case CK_ConstructorConversion:
2737 case CK_HLSLArrayRValue:
2738 llvm_unreachable(
"scalar cast to non-scalar value");
2740 case CK_LValueToRValue:
2742 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2745 case CK_IntegralToPointer: {
2746 Value *Src = Visit(E);
2750 auto DestLLVMTy = ConvertType(DestTy);
2753 llvm::Value* IntResult =
2754 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2756 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2762 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2768 case CK_PointerToIntegral: {
2769 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2770 auto *PtrExpr = Visit(E);
2773 const QualType SrcType = E->
getType();
2778 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2782 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2788 case CK_MatrixCast: {
2789 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2796 case CK_HLSLAggregateSplatCast:
2797 case CK_VectorSplat: {
2798 llvm::Type *DstTy = ConvertType(DestTy);
2799 Value *Elt = Visit(E);
2801 llvm::ElementCount NumElements =
2803 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2806 case CK_FixedPointCast:
2807 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2810 case CK_FixedPointToBoolean:
2812 "Expected src type to be fixed point type");
2813 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2814 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2817 case CK_FixedPointToIntegral:
2819 "Expected src type to be fixed point type");
2820 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2821 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2824 case CK_IntegralToFixedPoint:
2826 "Expected src type to be an integer");
2828 "Expected dest type to be fixed point type");
2829 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2832 case CK_IntegralCast: {
2834 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2835 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2839 ScalarConversionOpts Opts;
2840 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2841 if (!ICE->isPartOfExplicitCast())
2842 Opts = ScalarConversionOpts(CGF.
SanOpts);
2844 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2847 case CK_IntegralToFloating: {
2850 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2852 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2853 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2855 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2856 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2859 case CK_FloatingToIntegral: {
2862 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2864 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2865 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2867 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2868 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2871 case CK_FloatingCast: {
2874 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2875 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2876 if (DstElTy->
castAs<BuiltinType>()->getKind() <
2877 SrcElTy->
castAs<BuiltinType>()->getKind())
2878 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2879 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2881 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2882 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2885 case CK_FixedPointToFloating:
2886 case CK_FloatingToFixedPoint: {
2887 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2888 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2891 case CK_BooleanToSignedIntegral: {
2892 ScalarConversionOpts Opts;
2893 Opts.TreatBooleanAsSigned =
true;
2894 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2897 case CK_IntegralToBoolean:
2898 return EmitIntToBoolConversion(Visit(E));
2899 case CK_PointerToBoolean:
2900 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2901 case CK_FloatingToBoolean: {
2902 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2903 return EmitFloatToBoolConversion(Visit(E));
2905 case CK_MemberPointerToBoolean: {
2906 llvm::Value *MemPtr = Visit(E);
2907 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
2911 case CK_FloatingComplexToReal:
2912 case CK_IntegralComplexToReal:
2915 case CK_FloatingComplexToBoolean:
2916 case CK_IntegralComplexToBoolean: {
2920 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2924 case CK_ZeroToOCLOpaqueType: {
2927 "CK_ZeroToOCLEvent cast on non-event type");
2928 return llvm::Constant::getNullValue(ConvertType(DestTy));
2931 case CK_IntToOCLSampler:
2934 case CK_HLSLVectorTruncation: {
2936 "Destination type must be a vector or builtin type.");
2937 Value *Vec = Visit(E);
2938 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
2939 SmallVector<int> Mask;
2940 unsigned NumElts = VecTy->getNumElements();
2941 for (
unsigned I = 0; I != NumElts; ++I)
2944 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2946 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
2947 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
2949 case CK_HLSLElementwiseCast: {
2952 QualType SrcTy = E->
getType();
2954 assert(RV.
isAggregate() &&
"Not a valid HLSL Elementwise Cast.");
2961 llvm_unreachable(
"unknown scalar cast");
2964Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
2965 CodeGenFunction::StmtExprEvaluation eval(CGF);
2974Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
2975 CodeGenFunction::RunCleanupsScope Scope(CGF);
2979 Scope.ForceCleanup({&
V});
2988 llvm::Value *InVal,
bool IsInc,
2992 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2994 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2995 BinOp.FPFeatures = FPFeatures;
3000llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3001 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3002 llvm::Value *Amount =
3003 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3004 StringRef Name = IsInc ?
"inc" :
"dec";
3005 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3006 case LangOptions::SOB_Defined:
3007 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3008 return Builder.CreateAdd(InVal, Amount, Name);
3010 case LangOptions::SOB_Undefined:
3011 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3012 return Builder.CreateNSWAdd(InVal, Amount, Name);
3014 case LangOptions::SOB_Trapping:
3018 return Builder.CreateNSWAdd(InVal, Amount, Name);
3019 return EmitOverflowCheckedBinOp(Info);
3021 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3046class OMPLastprivateConditionalUpdateRAII {
3048 CodeGenFunction &CGF;
3049 const UnaryOperator *E;
3052 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3053 const UnaryOperator *E)
3055 ~OMPLastprivateConditionalUpdateRAII() {
3064ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3065 bool isInc,
bool isPre) {
3067 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3069 llvm::PHINode *atomicPHI =
nullptr;
3073 QualType SrcType = E->
getType();
3075 int amount = (isInc ? 1 : -1);
3076 bool isSubtraction = !isInc;
3078 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3079 type = atomicTy->getValueType();
3080 if (isInc &&
type->isBooleanType()) {
3083 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3084 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3085 return Builder.getTrue();
3089 return Builder.CreateAtomicRMW(
3090 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3091 llvm::AtomicOrdering::SequentiallyConsistent);
3096 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3097 !(
type->isUnsignedIntegerType() &&
3098 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3100 LangOptions::SOB_Trapping) {
3101 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3102 llvm::AtomicRMWInst::Sub;
3103 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3104 llvm::Instruction::Sub;
3106 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3108 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3109 llvm::AtomicOrdering::SequentiallyConsistent);
3110 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3114 if (
type->isFloatingType()) {
3115 llvm::Type *Ty = ConvertType(
type);
3116 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3117 llvm::AtomicRMWInst::BinOp aop =
3118 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3119 llvm::Instruction::BinaryOps op =
3120 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3121 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3122 llvm::AtomicRMWInst *old =
3124 llvm::AtomicOrdering::SequentiallyConsistent);
3126 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3129 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3132 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3135 Builder.CreateBr(opBB);
3136 Builder.SetInsertPoint(opBB);
3137 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3138 atomicPHI->addIncoming(value, startBB);
3141 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3152 if (isInc &&
type->isBooleanType()) {
3153 value = Builder.getTrue();
3156 }
else if (
type->isIntegerType()) {
3157 QualType promotedType;
3158 bool canPerformLossyDemotionCheck =
false;
3160 bool excludeOverflowPattern =
3165 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3166 canPerformLossyDemotionCheck =
true;
3167 canPerformLossyDemotionCheck &=
3170 canPerformLossyDemotionCheck &=
3172 type, promotedType);
3173 assert((!canPerformLossyDemotionCheck ||
3174 type->isSignedIntegerOrEnumerationType() ||
3176 ConvertType(
type)->getScalarSizeInBits() ==
3177 ConvertType(promotedType)->getScalarSizeInBits()) &&
3178 "The following check expects that if we do promotion to different "
3179 "underlying canonical type, at least one of the types (either "
3180 "base or promoted) will be signed, or the bitwidths will match.");
3183 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3184 SanitizerKind::ImplicitBitfieldConversion) &&
3185 canPerformLossyDemotionCheck) {
3199 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3200 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3201 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3205 ScalarConversionOpts Opts;
3206 if (!LV.isBitField())
3207 Opts = ScalarConversionOpts(CGF.
SanOpts);
3208 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3210 SrcType = promotedType;
3213 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3219 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3220 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3222 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3223 !excludeOverflowPattern &&
3225 SanitizerKind::UnsignedIntegerOverflow, E->
getType())) {
3229 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3230 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3234 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3235 QualType
type = ptr->getPointeeType();
3238 if (
const VariableArrayType *vla
3241 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3244 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3247 elemTy, value, numElts,
false, isSubtraction,
3251 }
else if (
type->isFunctionType()) {
3252 llvm::Value *amt = Builder.getInt32(amount);
3255 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3259 false, isSubtraction,
3264 llvm::Value *amt = Builder.getInt32(amount);
3267 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3270 elemTy, value, amt,
false, isSubtraction,
3275 }
else if (
type->isVectorType()) {
3276 if (
type->hasIntegerRepresentation()) {
3277 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
3279 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3281 value = Builder.CreateFAdd(
3283 llvm::ConstantFP::get(value->getType(), amount),
3284 isInc ?
"inc" :
"dec");
3288 }
else if (
type->isRealFloatingType()) {
3291 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3296 value = Builder.CreateCall(
3299 input,
"incdec.conv");
3301 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3305 if (value->getType()->isFloatTy())
3306 amt = llvm::ConstantFP::get(VMContext,
3307 llvm::APFloat(
static_cast<float>(amount)));
3308 else if (value->getType()->isDoubleTy())
3309 amt = llvm::ConstantFP::get(VMContext,
3310 llvm::APFloat(
static_cast<double>(amount)));
3314 llvm::APFloat F(
static_cast<float>(amount));
3316 const llvm::fltSemantics *FS;
3319 if (value->getType()->isFP128Ty())
3321 else if (value->getType()->isHalfTy())
3323 else if (value->getType()->isBFloatTy())
3325 else if (value->getType()->isPPC_FP128Ty())
3329 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3330 amt = llvm::ConstantFP::get(VMContext, F);
3332 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3336 value = Builder.CreateCall(
3339 value,
"incdec.conv");
3341 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3346 }
else if (
type->isFixedPointType()) {
3353 Info.Opcode = isInc ? BO_Add : BO_Sub;
3355 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3358 if (
type->isSignedFixedPointType()) {
3359 Info.Opcode = isInc ? BO_Sub : BO_Add;
3360 Info.RHS = Builder.CreateNeg(Info.RHS);
3365 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3367 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3368 value = EmitFixedPointBinOp(Info);
3372 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3375 if (!isInc) size = -size;
3376 llvm::Value *sizeValue =
3377 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3380 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3383 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3385 value = Builder.CreateBitCast(value, input->getType());
3389 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3394 llvm::Value *
success = Pair.second;
3395 atomicPHI->addIncoming(old, curBlock);
3396 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3397 Builder.SetInsertPoint(contBB);
3398 return isPre ? value : input;
3402 if (LV.isBitField()) {
3412 return isPre ? value : input;
3416Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3417 QualType PromotionType) {
3418 QualType promotionTy = PromotionType.
isNull()
3421 Value *result = VisitPlus(E, promotionTy);
3422 if (result && !promotionTy.
isNull())
3423 result = EmitUnPromotedValue(result, E->
getType());
3427Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3428 QualType PromotionType) {
3430 TestAndClearIgnoreResultAssign();
3431 if (!PromotionType.
isNull())
3436Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3437 QualType PromotionType) {
3438 QualType promotionTy = PromotionType.
isNull()
3441 Value *result = VisitMinus(E, promotionTy);
3442 if (result && !promotionTy.
isNull())
3443 result = EmitUnPromotedValue(result, E->
getType());
3447Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3448 QualType PromotionType) {
3449 TestAndClearIgnoreResultAssign();
3451 if (!PromotionType.
isNull())
3457 if (Op->
getType()->isFPOrFPVectorTy())
3458 return Builder.CreateFNeg(Op,
"fneg");
3463 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3465 BinOp.Opcode = BO_Sub;
3468 return EmitSub(BinOp);
3471Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3472 TestAndClearIgnoreResultAssign();
3474 return Builder.CreateNot(Op,
"not");
3477Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3481 VectorKind::Generic) {
3485 if (Oper->
getType()->isFPOrFPVectorTy()) {
3486 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3488 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3490 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3491 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3500 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3503 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3506Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3508 Expr::EvalResult EVResult;
3511 return Builder.getInt(
Value);
3516 llvm::Type* ResultType = ConvertType(E->
getType());
3517 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3519 for (
unsigned i = 0; i != n; ++i) {
3521 llvm::Value *Offset =
nullptr;
3528 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3535 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3539 Offset = Builder.CreateMul(Idx, ElemSize);
3544 FieldDecl *MemberDecl = ON.
getField();
3552 FieldEnd = RD->field_end();
3553 Field != FieldEnd; ++Field, ++i) {
3554 if (*Field == MemberDecl)
3557 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3562 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3565 CurrentType = MemberDecl->
getType();
3570 llvm_unreachable(
"dependent __builtin_offsetof");
3587 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3599ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3600 const UnaryExprOrTypeTraitExpr *E) {
3603 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3604 if (
const VariableArrayType *VAT =
3609 bool EvaluateExtent =
true;
3610 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3612 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3614 if (EvaluateExtent) {
3625 if (Kind == UETT_CountOf)
3634 if (!eltSize.
isOne())
3637 return VlaSize.NumElts;
3640 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3646 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3647 }
else if (E->
getKind() == UETT_VectorElements) {
3649 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3657Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3658 QualType PromotionType) {
3659 QualType promotionTy = PromotionType.
isNull()
3662 Value *result = VisitReal(E, promotionTy);
3663 if (result && !promotionTy.
isNull())
3664 result = EmitUnPromotedValue(result, E->
getType());
3668Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3669 QualType PromotionType) {
3676 if (!PromotionType.
isNull()) {
3678 Op, IgnoreResultAssign,
true);
3681 return result.first;
3691 if (!PromotionType.
isNull())
3696Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3697 QualType PromotionType) {
3698 QualType promotionTy = PromotionType.
isNull()
3701 Value *result = VisitImag(E, promotionTy);
3702 if (result && !promotionTy.
isNull())
3703 result = EmitUnPromotedValue(result, E->
getType());
3707Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3708 QualType PromotionType) {
3715 if (!PromotionType.
isNull()) {
3717 Op,
true, IgnoreResultAssign);
3720 return result.second;
3734 else if (!PromotionType.
isNull())
3738 if (!PromotionType.
isNull())
3739 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3740 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3747Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3748 QualType PromotionType) {
3749 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3752Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3753 QualType ExprType) {
3754 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3757Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3759 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3761#define HANDLE_BINOP(OP) \
3763 return Emit##OP(EmitBinOps(BO, PromotionType));
3772 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3775 return VisitImag(UO, PromotionType);
3777 return VisitReal(UO, PromotionType);
3779 return VisitMinus(UO, PromotionType);
3781 return VisitPlus(UO, PromotionType);
3786 auto result = Visit(
const_cast<Expr *
>(E));
3788 if (!PromotionType.
isNull())
3789 return EmitPromotedValue(result, PromotionType);
3791 return EmitUnPromotedValue(result, E->
getType());
3796BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3797 QualType PromotionType) {
3798 TestAndClearIgnoreResultAssign();
3802 if (!PromotionType.
isNull())
3803 Result.Ty = PromotionType;
3812LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3813 const CompoundAssignOperator *E,
3814 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3825 QualType PromotionTypeCR;
3827 if (PromotionTypeCR.
isNull())
3830 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3831 if (!PromotionTypeRHS.
isNull())
3834 OpInfo.RHS = Visit(E->
getRHS());
3835 OpInfo.Ty = PromotionTypeCR;
3842 llvm::PHINode *atomicPHI =
nullptr;
3843 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3844 QualType
type = atomicTy->getValueType();
3845 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3846 !(
type->isUnsignedIntegerType() &&
3847 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3849 LangOptions::SOB_Trapping) {
3850 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3851 llvm::Instruction::BinaryOps Op;
3852 switch (OpInfo.Opcode) {
3854 case BO_MulAssign:
case BO_DivAssign:
3860 AtomicOp = llvm::AtomicRMWInst::Add;
3861 Op = llvm::Instruction::Add;
3864 AtomicOp = llvm::AtomicRMWInst::Sub;
3865 Op = llvm::Instruction::Sub;
3868 AtomicOp = llvm::AtomicRMWInst::And;
3869 Op = llvm::Instruction::And;
3872 AtomicOp = llvm::AtomicRMWInst::Xor;
3873 Op = llvm::Instruction::Xor;
3876 AtomicOp = llvm::AtomicRMWInst::Or;
3877 Op = llvm::Instruction::Or;
3880 llvm_unreachable(
"Invalid compound assignment type");
3882 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3884 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3888 llvm::AtomicRMWInst *OldVal =
3893 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3899 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3901 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3903 Builder.CreateBr(opBB);
3904 Builder.SetInsertPoint(opBB);
3905 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3906 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3907 OpInfo.LHS = atomicPHI;
3910 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3912 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3914 if (!PromotionTypeLHS.
isNull())
3915 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3918 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3929 if (LHSLV.isBitField()) {
3931 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
3933 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
3934 ScalarConversionOpts(CGF.
SanOpts));
3937 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3941 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3942 llvm::Value *
success = Pair.second;
3943 atomicPHI->addIncoming(old, curBlock);
3944 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3945 Builder.SetInsertPoint(contBB);
3953 if (LHSLV.isBitField()) {
3969Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
3970 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3971 bool Ignore = TestAndClearIgnoreResultAssign();
3972 Value *RHS =
nullptr;
3973 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3984 if (!LHS.isVolatileQualified())
3988 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3991void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3992 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
3993 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
3996 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3997 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
3998 SanitizerKind::SO_IntegerDivideByZero));
4002 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4003 Ops.Ty->hasSignedIntegerRepresentation() &&
4005 Ops.mayHaveIntegerOverflow()) {
4008 llvm::Value *IntMin =
4009 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4010 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4012 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4013 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4014 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4016 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4019 if (Checks.size() > 0)
4020 EmitBinOpCheck(Checks, Ops);
4023Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4025 SanitizerDebugLocation SanScope(&CGF,
4026 {SanitizerKind::SO_IntegerDivideByZero,
4027 SanitizerKind::SO_SignedIntegerOverflow,
4028 SanitizerKind::SO_FloatDivideByZero},
4029 SanitizerHandler::DivremOverflow);
4030 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4031 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4032 Ops.Ty->isIntegerType() &&
4033 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4034 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4035 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4036 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4037 Ops.Ty->isRealFloatingType() &&
4038 Ops.mayHaveFloatDivisionByZero()) {
4039 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4040 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4042 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4046 if (Ops.Ty->isConstantMatrixType()) {
4047 llvm::MatrixBuilder MB(Builder);
4054 "first operand must be a matrix");
4056 "second operand must be an arithmetic type");
4057 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4058 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4059 Ops.Ty->hasUnsignedIntegerRepresentation());
4062 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4064 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4065 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4069 else if (Ops.isFixedPointOp())
4070 return EmitFixedPointBinOp(Ops);
4071 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4072 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4074 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4077Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4079 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4080 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4081 Ops.Ty->isIntegerType() &&
4082 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4083 SanitizerDebugLocation SanScope(&CGF,
4084 {SanitizerKind::SO_IntegerDivideByZero,
4085 SanitizerKind::SO_SignedIntegerOverflow},
4086 SanitizerHandler::DivremOverflow);
4087 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4088 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4091 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4092 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4094 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4095 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4097 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4100Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4105 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4106 switch (Ops.Opcode) {
4110 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4111 llvm::Intrinsic::uadd_with_overflow;
4112 OverflowKind = SanitizerHandler::AddOverflow;
4117 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4118 llvm::Intrinsic::usub_with_overflow;
4119 OverflowKind = SanitizerHandler::SubOverflow;
4124 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4125 llvm::Intrinsic::umul_with_overflow;
4126 OverflowKind = SanitizerHandler::MulOverflow;
4129 llvm_unreachable(
"Unsupported operation for overflow detection");
4135 SanitizerDebugLocation SanScope(&CGF,
4136 {SanitizerKind::SO_SignedIntegerOverflow,
4137 SanitizerKind::SO_UnsignedIntegerOverflow},
4143 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4144 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4145 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4148 const std::string *handlerName =
4150 if (handlerName->empty()) {
4153 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4154 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4156 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4157 : SanitizerKind::SO_UnsignedIntegerOverflow;
4158 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4160 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4165 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4166 llvm::BasicBlock *continueBB =
4170 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4174 Builder.SetInsertPoint(overflowBB);
4177 llvm::Type *Int8Ty = CGF.
Int8Ty;
4178 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4179 llvm::FunctionType *handlerTy =
4180 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4181 llvm::FunctionCallee handler =
4186 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4187 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4191 llvm::Value *handlerArgs[] = {
4194 Builder.getInt8(OpID),
4197 llvm::Value *handlerResult =
4201 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4202 Builder.CreateBr(continueBB);
4204 Builder.SetInsertPoint(continueBB);
4205 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4206 phi->addIncoming(result, initialBB);
4207 phi->addIncoming(handlerResult, overflowBB);
4216 bool isSubtraction) {
4221 Value *pointer = op.LHS;
4222 Expr *pointerOperand =
expr->getLHS();
4224 Expr *indexOperand =
expr->getRHS();
4227 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4228 std::swap(pointer,
index);
4229 std::swap(pointerOperand, indexOperand);
4233 index, isSubtraction);
4239 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4243 auto &DL =
CGM.getDataLayout();
4266 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4268 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4269 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4270 PtrTy->getPointerAddressSpace()))
4273 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4274 auto CheckHandler = SanitizerHandler::PointerOverflow;
4276 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4278 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4279 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4281 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4282 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4287 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4298 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4308 llvm::Value *objectSize =
4314 return Builder.CreateBitCast(result, pointer->getType());
4319 getContext().getAsVariableArrayType(elementType)) {
4321 llvm::Value *numElements =
getVLASize(vla).NumElts;
4330 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4350 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4363 bool negMul,
bool negAdd) {
4364 Value *MulOp0 = MulOp->getOperand(0);
4365 Value *MulOp1 = MulOp->getOperand(1);
4367 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4369 Addend = Builder.CreateFNeg(Addend,
"neg");
4371 Value *FMulAdd =
nullptr;
4372 if (Builder.getIsFPConstrained()) {
4374 "Only constrained operation should be created when Builder is in FP "
4375 "constrained mode");
4376 FMulAdd = Builder.CreateConstrainedFPCall(
4377 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4379 {MulOp0, MulOp1, Addend});
4381 FMulAdd = Builder.CreateCall(
4383 {MulOp0, MulOp1, Addend});
4385 MulOp->eraseFromParent();
4400 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4401 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4402 "Only fadd/fsub can be the root of an fmuladd.");
4405 if (!op.FPFeatures.allowFPContractWithinStatement())
4408 Value *LHS = op.LHS;
4409 Value *RHS = op.RHS;
4413 bool NegLHS =
false;
4414 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4415 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4416 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4417 LHS = LHSUnOp->getOperand(0);
4422 bool NegRHS =
false;
4423 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4424 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4425 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4426 RHS = RHSUnOp->getOperand(0);
4434 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4435 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4436 (LHSBinOp->use_empty() || NegLHS)) {
4440 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4443 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4444 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4445 (RHSBinOp->use_empty() || NegRHS)) {
4449 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4453 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4454 if (LHSBinOp->getIntrinsicID() ==
4455 llvm::Intrinsic::experimental_constrained_fmul &&
4456 (LHSBinOp->use_empty() || NegLHS)) {
4460 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4463 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4464 if (RHSBinOp->getIntrinsicID() ==
4465 llvm::Intrinsic::experimental_constrained_fmul &&
4466 (RHSBinOp->use_empty() || NegRHS)) {
4470 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4477Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4478 if (op.LHS->getType()->isPointerTy() ||
4479 op.RHS->getType()->isPointerTy())
4482 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4483 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4484 case LangOptions::SOB_Defined:
4485 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4486 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4488 case LangOptions::SOB_Undefined:
4489 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4490 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4492 case LangOptions::SOB_Trapping:
4493 if (CanElideOverflowCheck(CGF.
getContext(), op))
4494 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4495 return EmitOverflowCheckedBinOp(op);
4500 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4501 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4507 if (op.Ty->isConstantMatrixType()) {
4508 llvm::MatrixBuilder MB(Builder);
4509 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4510 return MB.CreateAdd(op.LHS, op.RHS);
4513 if (op.Ty->isUnsignedIntegerType() &&
4514 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4515 !CanElideOverflowCheck(CGF.
getContext(), op))
4516 return EmitOverflowCheckedBinOp(op);
4518 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4519 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4520 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4523 if (op.isFixedPointOp())
4524 return EmitFixedPointBinOp(op);
4526 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4531Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4533 using llvm::ConstantInt;
4539 QualType ResultTy = op.Ty;
4540 QualType LHSTy, RHSTy;
4541 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4542 RHSTy = BinOp->getRHS()->getType();
4543 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4548 LHSTy = CAO->getComputationLHSType();
4549 ResultTy = CAO->getComputationResultType();
4551 LHSTy = BinOp->getLHS()->getType();
4552 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4553 LHSTy = UnOp->getSubExpr()->getType();
4554 RHSTy = UnOp->getSubExpr()->getType();
4557 Value *LHS = op.LHS;
4558 Value *RHS = op.RHS;
4563 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4567 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4568 switch (op.Opcode) {
4571 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4575 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4579 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4583 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4587 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4591 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4594 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4596 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4598 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4600 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4605 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4607 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4611 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4624 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4630 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4635Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4637 if (!op.LHS->getType()->isPointerTy()) {
4638 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4639 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4640 case LangOptions::SOB_Defined:
4641 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4642 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4644 case LangOptions::SOB_Undefined:
4645 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4646 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4648 case LangOptions::SOB_Trapping:
4649 if (CanElideOverflowCheck(CGF.
getContext(), op))
4650 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4651 return EmitOverflowCheckedBinOp(op);
4656 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4657 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4663 if (op.Ty->isConstantMatrixType()) {
4664 llvm::MatrixBuilder MB(Builder);
4665 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4666 return MB.CreateSub(op.LHS, op.RHS);
4669 if (op.Ty->isUnsignedIntegerType() &&
4670 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4671 !CanElideOverflowCheck(CGF.
getContext(), op))
4672 return EmitOverflowCheckedBinOp(op);
4674 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4675 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4676 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4679 if (op.isFixedPointOp())
4680 return EmitFixedPointBinOp(op);
4682 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4687 if (!op.RHS->getType()->isPointerTy())
4694 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4696 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4697 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4701 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4703 llvm::Value *divisor =
nullptr;
4706 if (
const VariableArrayType *vla
4709 elementType = VlaSize.Type;
4710 divisor = VlaSize.NumElts;
4714 if (!eltSize.
isOne())
4721 CharUnits elementSize;
4730 if (elementSize.
isOne())
4739 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4742Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4744 llvm::IntegerType *Ty;
4745 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4753 llvm::Type *RHSTy = RHS->
getType();
4754 llvm::APInt RHSMax =
4755 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4756 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4757 if (RHSMax.ult(Ty->getBitWidth()))
4758 return llvm::ConstantInt::get(RHSTy, RHSMax);
4759 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4763 const Twine &Name) {
4764 llvm::IntegerType *Ty;
4765 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4770 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4771 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4773 return Builder.CreateURem(
4774 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4777Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4779 if (Ops.isFixedPointOp())
4780 return EmitFixedPointBinOp(Ops);
4784 Value *RHS = Ops.RHS;
4785 if (Ops.LHS->getType() != RHS->
getType())
4786 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4788 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4789 Ops.Ty->hasSignedIntegerRepresentation() &&
4792 bool SanitizeUnsignedBase =
4793 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4794 Ops.Ty->hasUnsignedIntegerRepresentation();
4795 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4796 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4799 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4800 else if ((SanitizeBase || SanitizeExponent) &&
4802 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4803 if (SanitizeSignedBase)
4804 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4805 if (SanitizeUnsignedBase)
4806 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4807 if (SanitizeExponent)
4808 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4810 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4811 SanitizerHandler::ShiftOutOfBounds);
4812 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4813 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4814 llvm::Value *WidthMinusOne =
4815 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4816 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4818 if (SanitizeExponent) {
4820 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4827 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4830 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4831 llvm::Value *PromotedWidthMinusOne =
4832 (RHS == Ops.RHS) ? WidthMinusOne
4833 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4835 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4836 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4845 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4846 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4848 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4849 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4851 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4852 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4853 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4854 Checks.push_back(std::make_pair(
4855 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4856 : SanitizerKind::SO_UnsignedShiftBase));
4859 assert(!Checks.empty());
4860 EmitBinOpCheck(Checks, Ops);
4863 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4866Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4868 if (Ops.isFixedPointOp())
4869 return EmitFixedPointBinOp(Ops);
4873 Value *RHS = Ops.RHS;
4874 if (Ops.LHS->getType() != RHS->
getType())
4875 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4879 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4880 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4882 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4883 SanitizerHandler::ShiftOutOfBounds);
4884 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4885 llvm::Value *
Valid = Builder.CreateICmpULE(
4886 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4887 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4890 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4891 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4892 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4900 default: llvm_unreachable(
"unexpected element type");
4901 case BuiltinType::Char_U:
4902 case BuiltinType::UChar:
4903 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4904 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4905 case BuiltinType::Char_S:
4906 case BuiltinType::SChar:
4907 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4908 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4909 case BuiltinType::UShort:
4910 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4911 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4912 case BuiltinType::Short:
4913 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4914 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4915 case BuiltinType::UInt:
4916 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4917 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4918 case BuiltinType::Int:
4919 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4920 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4921 case BuiltinType::ULong:
4922 case BuiltinType::ULongLong:
4923 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4924 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4925 case BuiltinType::Long:
4926 case BuiltinType::LongLong:
4927 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4928 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4929 case BuiltinType::Float:
4930 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4931 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4932 case BuiltinType::Double:
4933 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4934 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4935 case BuiltinType::UInt128:
4936 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4937 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4938 case BuiltinType::Int128:
4939 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4940 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4944Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
4945 llvm::CmpInst::Predicate UICmpOpc,
4946 llvm::CmpInst::Predicate SICmpOpc,
4947 llvm::CmpInst::Predicate FCmpOpc,
4949 TestAndClearIgnoreResultAssign();
4953 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
4959 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4961 BinOpInfo BOInfo = EmitBinOps(E);
4962 Value *LHS = BOInfo.LHS;
4963 Value *RHS = BOInfo.RHS;
4969 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4971 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4974 Value *FirstVecArg = LHS,
4975 *SecondVecArg = RHS;
4977 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
4981 default: llvm_unreachable(
"is not a comparison operation");
4993 std::swap(FirstVecArg, SecondVecArg);
5000 if (ElementKind == BuiltinType::Float) {
5002 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5003 std::swap(FirstVecArg, SecondVecArg);
5011 if (ElementKind == BuiltinType::Float) {
5013 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5018 std::swap(FirstVecArg, SecondVecArg);
5023 Value *CR6Param = Builder.getInt32(CR6);
5025 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5033 if (ResultTy->getBitWidth() > 1 &&
5035 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5040 if (BOInfo.isFixedPointOp()) {
5041 Result = EmitFixedPointBinOp(BOInfo);
5042 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5043 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5045 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5047 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5049 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5064 LHS = Builder.CreateStripInvariantGroup(LHS);
5066 RHS = Builder.CreateStripInvariantGroup(RHS);
5069 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5075 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5081 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5083 CETy = CTy->getElementType();
5085 LHS.first = Visit(E->
getLHS());
5086 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5089 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5092 CTy->getElementType()) &&
5093 "The element types must always match.");
5096 RHS.first = Visit(E->
getRHS());
5097 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5099 "The element types must always match.");
5102 Value *ResultR, *ResultI;
5106 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5107 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5111 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5112 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5116 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5119 "Complex comparison other than == or != ?");
5120 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5132 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5133 CastKind Kind = ICE->getCastKind();
5134 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5135 *SrcType = ICE->getSubExpr()->getType();
5148 bool Ignore = TestAndClearIgnoreResultAssign();
5182 RHS = Visit(E->
getRHS());
5198 RHS = Visit(E->
getRHS());
5238 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5241Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5249 if (LHS->
getType()->isFPOrFPVectorTy()) {
5250 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5252 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5253 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5255 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5256 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5258 Value *
And = Builder.CreateAnd(LHS, RHS);
5259 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5263 llvm::Type *ResTy = ConvertType(E->
getType());
5284 if (InstrumentRegions &&
5289 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5303 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5309 return llvm::Constant::getNullValue(ResTy);
5322 CodeGenFunction::ConditionalEvaluation eval(CGF);
5331 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5333 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5335 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5344 RHSBlock = Builder.GetInsertBlock();
5349 if (InstrumentRegions &&
5353 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5357 PN->addIncoming(RHSCond, RHSBlockCnt);
5367 PN->addIncoming(RHSCond, RHSBlock);
5377 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5381 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5384Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5392 if (LHS->
getType()->isFPOrFPVectorTy()) {
5393 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5395 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5396 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5398 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5399 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5401 Value *
Or = Builder.CreateOr(LHS, RHS);
5402 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5406 llvm::Type *ResTy = ConvertType(E->
getType());
5427 if (InstrumentRegions &&
5432 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5446 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5452 return llvm::ConstantInt::get(ResTy, 1);
5465 CodeGenFunction::ConditionalEvaluation eval(CGF);
5475 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5477 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5479 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5491 RHSBlock = Builder.GetInsertBlock();
5496 if (InstrumentRegions &&
5500 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5504 PN->addIncoming(RHSCond, RHSBlockCnt);
5510 PN->addIncoming(RHSCond, RHSBlock);
5518 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5521Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5524 return Visit(E->
getRHS());
5549Value *ScalarExprEmitter::
5550VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5551 TestAndClearIgnoreResultAssign();
5554 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5556 Expr *condExpr = E->
getCond();
5564 Expr *live = lhsExpr, *dead = rhsExpr;
5565 if (!CondExprBool) std::swap(live, dead);
5596 llvm::Value *LHS = Visit(lhsExpr);
5597 llvm::Value *RHS = Visit(rhsExpr);
5599 llvm::Type *condType = ConvertType(condExpr->
getType());
5602 unsigned numElem = vecTy->getNumElements();
5603 llvm::Type *elemType = vecTy->getElementType();
5605 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5606 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5607 llvm::Value *tmp = Builder.CreateSExt(
5608 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5609 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5612 llvm::Value *RHSTmp = RHS;
5613 llvm::Value *LHSTmp = LHS;
5614 bool wasCast =
false;
5616 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5617 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5618 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5622 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5623 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5624 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5626 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5636 llvm::Value *LHS = Visit(lhsExpr);
5637 llvm::Value *RHS = Visit(rhsExpr);
5639 llvm::Type *CondType = ConvertType(condExpr->
getType());
5642 if (VecTy->getElementType()->isIntegerTy(1))
5643 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5646 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5648 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5650 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5651 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5660 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5669 llvm::Value *LHS = Visit(lhsExpr);
5670 llvm::Value *RHS = Visit(rhsExpr);
5673 assert(!RHS &&
"LHS and RHS types must match");
5676 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5687 CodeGenFunction::ConditionalEvaluation eval(CGF);
5705 Value *LHS = Visit(lhsExpr);
5708 LHSBlock = Builder.GetInsertBlock();
5709 Builder.CreateBr(ContBlock);
5723 Value *RHS = Visit(rhsExpr);
5726 RHSBlock = Builder.GetInsertBlock();
5736 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5737 PN->addIncoming(LHS, LHSBlock);
5738 PN->addIncoming(RHS, RHSBlock);
5748Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5752Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5754 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5759Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5765 Value *Src,
unsigned NumElementsDst) {
5766 static constexpr int Mask[] = {0, 1, 2, -1};
5767 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5787 const llvm::DataLayout &DL,
5788 Value *Src, llvm::Type *DstTy,
5789 StringRef Name =
"") {
5793 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5794 return Builder.CreateBitCast(Src, DstTy, Name);
5797 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5798 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5801 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5803 if (!DstTy->isIntegerTy())
5804 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5806 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5810 if (!SrcTy->isIntegerTy())
5811 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5813 return Builder.CreateIntToPtr(Src, DstTy, Name);
5816Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5818 llvm::Type *DstTy = ConvertType(E->
getType());
5820 llvm::Type *SrcTy = Src->
getType();
5821 unsigned NumElementsSrc =
5825 unsigned NumElementsDst =
5836 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5841 Src->setName(
"astype");
5848 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5849 auto *Vec4Ty = llvm::FixedVectorType::get(
5855 Src->setName(
"astype");
5860 Src, DstTy,
"astype");
5863Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5875 "Invalid scalar expression to emit");
5877 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5878 .Visit(
const_cast<Expr *
>(E));
5887 "Invalid scalar expression to emit");
5888 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5898 "Invalid complex -> scalar conversion");
5899 return ScalarExprEmitter(*
this)
5900 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5907 if (!PromotionType.
isNull())
5908 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5910 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5916 bool isInc,
bool isPre) {
5917 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5927 llvm::Type *BaseTy =
5943 ScalarExprEmitter Scalar(*
this);
5946#define COMPOUND_OP(Op) \
5947 case BO_##Op##Assign: \
5948 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5985 llvm_unreachable(
"Not valid compound assignment operators");
5988 llvm_unreachable(
"Unhandled compound assignment operator");
6003 llvm::LLVMContext &VMContext,
6009 llvm::Value *TotalOffset =
nullptr;
6015 Value *BasePtr_int =
6016 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6018 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6019 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6020 return {TotalOffset, Builder.getFalse()};
6024 assert(GEP->getPointerOperand() == BasePtr &&
6025 "BasePtr must be the base of the GEP.");
6026 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6028 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6031 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6032 auto *SAddIntrinsic =
6033 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6034 auto *SMulIntrinsic =
6035 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6038 llvm::Value *OffsetOverflows = Builder.getFalse();
6042 llvm::Value *RHS) -> llvm::Value * {
6043 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6046 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6047 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6049 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6052 OffsetOverflows = Builder.getTrue();
6053 return llvm::ConstantInt::get(VMContext, N);
6058 auto *ResultAndOverflow = Builder.CreateCall(
6059 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6060 OffsetOverflows = Builder.CreateOr(
6061 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6062 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6066 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6067 GTI != GTE; ++GTI) {
6068 llvm::Value *LocalOffset;
6069 auto *Index = GTI.getOperand();
6071 if (
auto *STy = GTI.getStructTypeOrNull()) {
6075 LocalOffset = llvm::ConstantInt::get(
6076 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6081 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6082 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6083 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6088 if (!TotalOffset || TotalOffset ==
Zero)
6089 TotalOffset = LocalOffset;
6091 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6094 return {TotalOffset, OffsetOverflows};
6099 ArrayRef<Value *> IdxList,
6100 bool SignedIndices,
bool IsSubtraction,
6101 SourceLocation Loc,
const Twine &Name) {
6102 llvm::Type *PtrTy = Ptr->
getType();
6104 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6105 if (!SignedIndices && !IsSubtraction)
6106 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6108 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6111 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6115 bool PerformNullCheck = !NullPointerIsDefined(
6116 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6119 bool PerformOverflowCheck =
6122 if (!(PerformNullCheck || PerformOverflowCheck))
6125 const auto &DL = CGM.getDataLayout();
6127 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6128 auto CheckHandler = SanitizerHandler::PointerOverflow;
6129 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6130 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6132 GEPOffsetAndOverflow EvaluatedGEP =
6137 "If the offset got constant-folded, we don't expect that there was an "
6140 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6148 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6149 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6151 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6155 if (PerformNullCheck) {
6163 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6164 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6165 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6166 Checks.emplace_back(
Valid, CheckOrdinal);
6169 if (PerformOverflowCheck) {
6174 llvm::Value *ValidGEP;
6175 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6176 if (SignedIndices) {
6182 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6183 auto *PosOrZeroOffset =
6185 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6187 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6188 }
else if (!IsSubtraction) {
6193 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6199 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6201 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6202 Checks.emplace_back(ValidGEP, CheckOrdinal);
6205 assert(!Checks.empty() &&
"Should have produced some checks.");
6207 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6209 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6210 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6216 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6217 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6218 const Twine &Name) {
6219 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6220 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6221 if (!SignedIndices && !IsSubtraction)
6222 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6224 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6228 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6229 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6230 elementType, Align);
Defines the clang::ASTContext interface.
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, Address DestVal, QualType DestTy, Address SrcVal, QualType SrcTy, SourceLocation Loc)
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
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 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.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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.
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.
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)
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)
void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
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.
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...
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
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,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
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...
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 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.
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)
void FlattenAccessAndType(Address Addr, QualType AddrTy, SmallVectorImpl< std::pair< Address, llvm::Value * > > &AccessList, SmallVectorImpl< QualType > &FlatTypes)
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 emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
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
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.
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, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) 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 llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
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 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::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.