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);
3693 if (!PromotionType.
isNull())
3698Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3699 QualType PromotionType) {
3700 QualType promotionTy = PromotionType.
isNull()
3703 Value *result = VisitImag(E, promotionTy);
3704 if (result && !promotionTy.
isNull())
3705 result = EmitUnPromotedValue(result, E->
getType());
3709Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3710 QualType PromotionType) {
3717 if (!PromotionType.
isNull()) {
3719 Op,
true, IgnoreResultAssign);
3723 return result.second
3739 else if (!PromotionType.
isNull())
3743 if (!PromotionType.
isNull())
3744 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3745 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3752Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3753 QualType PromotionType) {
3754 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3757Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3758 QualType ExprType) {
3759 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3762Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3764 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3766#define HANDLE_BINOP(OP) \
3768 return Emit##OP(EmitBinOps(BO, PromotionType));
3777 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3780 return VisitImag(UO, PromotionType);
3782 return VisitReal(UO, PromotionType);
3784 return VisitMinus(UO, PromotionType);
3786 return VisitPlus(UO, PromotionType);
3791 auto result = Visit(
const_cast<Expr *
>(E));
3793 if (!PromotionType.
isNull())
3794 return EmitPromotedValue(result, PromotionType);
3796 return EmitUnPromotedValue(result, E->
getType());
3801BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3802 QualType PromotionType) {
3803 TestAndClearIgnoreResultAssign();
3807 if (!PromotionType.
isNull())
3808 Result.Ty = PromotionType;
3817LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3818 const CompoundAssignOperator *E,
3819 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3830 QualType PromotionTypeCR;
3832 if (PromotionTypeCR.
isNull())
3835 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3836 if (!PromotionTypeRHS.
isNull())
3839 OpInfo.RHS = Visit(E->
getRHS());
3840 OpInfo.Ty = PromotionTypeCR;
3847 llvm::PHINode *atomicPHI =
nullptr;
3848 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3849 QualType
type = atomicTy->getValueType();
3850 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3851 !(
type->isUnsignedIntegerType() &&
3852 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3854 LangOptions::SOB_Trapping) {
3855 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3856 llvm::Instruction::BinaryOps Op;
3857 switch (OpInfo.Opcode) {
3859 case BO_MulAssign:
case BO_DivAssign:
3865 AtomicOp = llvm::AtomicRMWInst::Add;
3866 Op = llvm::Instruction::Add;
3869 AtomicOp = llvm::AtomicRMWInst::Sub;
3870 Op = llvm::Instruction::Sub;
3873 AtomicOp = llvm::AtomicRMWInst::And;
3874 Op = llvm::Instruction::And;
3877 AtomicOp = llvm::AtomicRMWInst::Xor;
3878 Op = llvm::Instruction::Xor;
3881 AtomicOp = llvm::AtomicRMWInst::Or;
3882 Op = llvm::Instruction::Or;
3885 llvm_unreachable(
"Invalid compound assignment type");
3887 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3889 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3893 llvm::AtomicRMWInst *OldVal =
3898 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3904 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3906 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3908 Builder.CreateBr(opBB);
3909 Builder.SetInsertPoint(opBB);
3910 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3911 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3912 OpInfo.LHS = atomicPHI;
3915 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3917 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3919 if (!PromotionTypeLHS.
isNull())
3920 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3923 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3934 if (LHSLV.isBitField()) {
3936 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
3938 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
3939 ScalarConversionOpts(CGF.
SanOpts));
3942 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3946 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3947 llvm::Value *
success = Pair.second;
3948 atomicPHI->addIncoming(old, curBlock);
3949 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3950 Builder.SetInsertPoint(contBB);
3958 if (LHSLV.isBitField()) {
3974Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
3975 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3976 bool Ignore = TestAndClearIgnoreResultAssign();
3977 Value *RHS =
nullptr;
3978 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3989 if (!LHS.isVolatileQualified())
3993 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3996void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3997 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
3998 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4001 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4002 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4003 SanitizerKind::SO_IntegerDivideByZero));
4007 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4008 Ops.Ty->hasSignedIntegerRepresentation() &&
4010 Ops.mayHaveIntegerOverflow()) {
4013 llvm::Value *IntMin =
4014 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4015 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4017 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4018 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4019 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4021 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4024 if (Checks.size() > 0)
4025 EmitBinOpCheck(Checks, Ops);
4028Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4030 SanitizerDebugLocation SanScope(&CGF,
4031 {SanitizerKind::SO_IntegerDivideByZero,
4032 SanitizerKind::SO_SignedIntegerOverflow,
4033 SanitizerKind::SO_FloatDivideByZero},
4034 SanitizerHandler::DivremOverflow);
4035 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4036 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4037 Ops.Ty->isIntegerType() &&
4038 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4039 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4040 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4041 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4042 Ops.Ty->isRealFloatingType() &&
4043 Ops.mayHaveFloatDivisionByZero()) {
4044 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4045 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4047 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4051 if (Ops.Ty->isConstantMatrixType()) {
4052 llvm::MatrixBuilder MB(Builder);
4059 "first operand must be a matrix");
4061 "second operand must be an arithmetic type");
4062 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4063 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4064 Ops.Ty->hasUnsignedIntegerRepresentation());
4067 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4069 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4070 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4074 else if (Ops.isFixedPointOp())
4075 return EmitFixedPointBinOp(Ops);
4076 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4077 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4079 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4082Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4084 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4085 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4086 Ops.Ty->isIntegerType() &&
4087 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4088 SanitizerDebugLocation SanScope(&CGF,
4089 {SanitizerKind::SO_IntegerDivideByZero,
4090 SanitizerKind::SO_SignedIntegerOverflow},
4091 SanitizerHandler::DivremOverflow);
4092 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4093 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4096 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4097 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4099 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4100 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4102 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4105Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4110 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4111 switch (Ops.Opcode) {
4115 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4116 llvm::Intrinsic::uadd_with_overflow;
4117 OverflowKind = SanitizerHandler::AddOverflow;
4122 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4123 llvm::Intrinsic::usub_with_overflow;
4124 OverflowKind = SanitizerHandler::SubOverflow;
4129 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4130 llvm::Intrinsic::umul_with_overflow;
4131 OverflowKind = SanitizerHandler::MulOverflow;
4134 llvm_unreachable(
"Unsupported operation for overflow detection");
4140 SanitizerDebugLocation SanScope(&CGF,
4141 {SanitizerKind::SO_SignedIntegerOverflow,
4142 SanitizerKind::SO_UnsignedIntegerOverflow},
4148 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4149 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4150 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4153 const std::string *handlerName =
4155 if (handlerName->empty()) {
4158 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4159 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4161 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4162 : SanitizerKind::SO_UnsignedIntegerOverflow;
4163 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4165 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4170 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4171 llvm::BasicBlock *continueBB =
4175 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4179 Builder.SetInsertPoint(overflowBB);
4182 llvm::Type *Int8Ty = CGF.
Int8Ty;
4183 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4184 llvm::FunctionType *handlerTy =
4185 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4186 llvm::FunctionCallee handler =
4191 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4192 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4196 llvm::Value *handlerArgs[] = {
4199 Builder.getInt8(OpID),
4202 llvm::Value *handlerResult =
4206 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4207 Builder.CreateBr(continueBB);
4209 Builder.SetInsertPoint(continueBB);
4210 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4211 phi->addIncoming(result, initialBB);
4212 phi->addIncoming(handlerResult, overflowBB);
4221 bool isSubtraction) {
4226 Value *pointer = op.LHS;
4227 Expr *pointerOperand =
expr->getLHS();
4229 Expr *indexOperand =
expr->getRHS();
4232 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4233 std::swap(pointer,
index);
4234 std::swap(pointerOperand, indexOperand);
4238 index, isSubtraction);
4244 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4248 auto &DL =
CGM.getDataLayout();
4271 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4273 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4274 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4275 PtrTy->getPointerAddressSpace()))
4278 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4279 auto CheckHandler = SanitizerHandler::PointerOverflow;
4281 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4283 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4284 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4286 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4287 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4292 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4303 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4313 llvm::Value *objectSize =
4319 return Builder.CreateBitCast(result, pointer->getType());
4324 getContext().getAsVariableArrayType(elementType)) {
4326 llvm::Value *numElements =
getVLASize(vla).NumElts;
4335 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4355 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4368 bool negMul,
bool negAdd) {
4369 Value *MulOp0 = MulOp->getOperand(0);
4370 Value *MulOp1 = MulOp->getOperand(1);
4372 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4374 Addend = Builder.CreateFNeg(Addend,
"neg");
4376 Value *FMulAdd =
nullptr;
4377 if (Builder.getIsFPConstrained()) {
4379 "Only constrained operation should be created when Builder is in FP "
4380 "constrained mode");
4381 FMulAdd = Builder.CreateConstrainedFPCall(
4382 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4384 {MulOp0, MulOp1, Addend});
4386 FMulAdd = Builder.CreateCall(
4388 {MulOp0, MulOp1, Addend});
4390 MulOp->eraseFromParent();
4405 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4406 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4407 "Only fadd/fsub can be the root of an fmuladd.");
4410 if (!op.FPFeatures.allowFPContractWithinStatement())
4413 Value *LHS = op.LHS;
4414 Value *RHS = op.RHS;
4418 bool NegLHS =
false;
4419 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4420 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4421 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4422 LHS = LHSUnOp->getOperand(0);
4427 bool NegRHS =
false;
4428 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4429 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4430 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4431 RHS = RHSUnOp->getOperand(0);
4439 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4440 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4441 (LHSBinOp->use_empty() || NegLHS)) {
4445 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4448 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4449 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4450 (RHSBinOp->use_empty() || NegRHS)) {
4454 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4458 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4459 if (LHSBinOp->getIntrinsicID() ==
4460 llvm::Intrinsic::experimental_constrained_fmul &&
4461 (LHSBinOp->use_empty() || NegLHS)) {
4465 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4468 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4469 if (RHSBinOp->getIntrinsicID() ==
4470 llvm::Intrinsic::experimental_constrained_fmul &&
4471 (RHSBinOp->use_empty() || NegRHS)) {
4475 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4482Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4483 if (op.LHS->getType()->isPointerTy() ||
4484 op.RHS->getType()->isPointerTy())
4487 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4488 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4489 case LangOptions::SOB_Defined:
4490 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4491 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4493 case LangOptions::SOB_Undefined:
4494 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4495 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4497 case LangOptions::SOB_Trapping:
4498 if (CanElideOverflowCheck(CGF.
getContext(), op))
4499 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4500 return EmitOverflowCheckedBinOp(op);
4505 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4506 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4512 if (op.Ty->isConstantMatrixType()) {
4513 llvm::MatrixBuilder MB(Builder);
4514 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4515 return MB.CreateAdd(op.LHS, op.RHS);
4518 if (op.Ty->isUnsignedIntegerType() &&
4519 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4520 !CanElideOverflowCheck(CGF.
getContext(), op))
4521 return EmitOverflowCheckedBinOp(op);
4523 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4524 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4525 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4528 if (op.isFixedPointOp())
4529 return EmitFixedPointBinOp(op);
4531 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4536Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4538 using llvm::ConstantInt;
4544 QualType ResultTy = op.Ty;
4545 QualType LHSTy, RHSTy;
4546 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4547 RHSTy = BinOp->getRHS()->getType();
4548 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4553 LHSTy = CAO->getComputationLHSType();
4554 ResultTy = CAO->getComputationResultType();
4556 LHSTy = BinOp->getLHS()->getType();
4557 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4558 LHSTy = UnOp->getSubExpr()->getType();
4559 RHSTy = UnOp->getSubExpr()->getType();
4562 Value *LHS = op.LHS;
4563 Value *RHS = op.RHS;
4568 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4572 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4573 switch (op.Opcode) {
4576 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4580 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4584 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4588 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4592 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4596 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4599 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4601 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4603 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4605 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4610 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4612 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4616 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4629 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4635 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4640Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4642 if (!op.LHS->getType()->isPointerTy()) {
4643 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4644 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4645 case LangOptions::SOB_Defined:
4646 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4647 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4649 case LangOptions::SOB_Undefined:
4650 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4651 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4653 case LangOptions::SOB_Trapping:
4654 if (CanElideOverflowCheck(CGF.
getContext(), op))
4655 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4656 return EmitOverflowCheckedBinOp(op);
4661 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4662 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4668 if (op.Ty->isConstantMatrixType()) {
4669 llvm::MatrixBuilder MB(Builder);
4670 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4671 return MB.CreateSub(op.LHS, op.RHS);
4674 if (op.Ty->isUnsignedIntegerType() &&
4675 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4676 !CanElideOverflowCheck(CGF.
getContext(), op))
4677 return EmitOverflowCheckedBinOp(op);
4679 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4680 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4681 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4684 if (op.isFixedPointOp())
4685 return EmitFixedPointBinOp(op);
4687 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4692 if (!op.RHS->getType()->isPointerTy())
4699 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4701 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4702 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4706 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4708 llvm::Value *divisor =
nullptr;
4711 if (
const VariableArrayType *vla
4714 elementType = VlaSize.Type;
4715 divisor = VlaSize.NumElts;
4719 if (!eltSize.
isOne())
4726 CharUnits elementSize;
4735 if (elementSize.
isOne())
4744 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4747Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4749 llvm::IntegerType *Ty;
4750 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4758 llvm::Type *RHSTy = RHS->
getType();
4759 llvm::APInt RHSMax =
4760 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4761 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4762 if (RHSMax.ult(Ty->getBitWidth()))
4763 return llvm::ConstantInt::get(RHSTy, RHSMax);
4764 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4768 const Twine &Name) {
4769 llvm::IntegerType *Ty;
4770 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4775 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4776 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4778 return Builder.CreateURem(
4779 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4782Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4784 if (Ops.isFixedPointOp())
4785 return EmitFixedPointBinOp(Ops);
4789 Value *RHS = Ops.RHS;
4790 if (Ops.LHS->getType() != RHS->
getType())
4791 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4793 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4794 Ops.Ty->hasSignedIntegerRepresentation() &&
4797 bool SanitizeUnsignedBase =
4798 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4799 Ops.Ty->hasUnsignedIntegerRepresentation();
4800 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4801 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4804 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4805 else if ((SanitizeBase || SanitizeExponent) &&
4807 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4808 if (SanitizeSignedBase)
4809 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4810 if (SanitizeUnsignedBase)
4811 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4812 if (SanitizeExponent)
4813 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4815 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4816 SanitizerHandler::ShiftOutOfBounds);
4817 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4818 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4819 llvm::Value *WidthMinusOne =
4820 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4821 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4823 if (SanitizeExponent) {
4825 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4832 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4835 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4836 llvm::Value *PromotedWidthMinusOne =
4837 (RHS == Ops.RHS) ? WidthMinusOne
4838 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4840 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4841 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4850 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4851 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4853 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4854 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4856 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4857 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4858 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4859 Checks.push_back(std::make_pair(
4860 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4861 : SanitizerKind::SO_UnsignedShiftBase));
4864 assert(!Checks.empty());
4865 EmitBinOpCheck(Checks, Ops);
4868 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4871Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4873 if (Ops.isFixedPointOp())
4874 return EmitFixedPointBinOp(Ops);
4878 Value *RHS = Ops.RHS;
4879 if (Ops.LHS->getType() != RHS->
getType())
4880 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4884 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4885 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4887 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4888 SanitizerHandler::ShiftOutOfBounds);
4889 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4890 llvm::Value *
Valid = Builder.CreateICmpULE(
4891 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4892 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4895 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4896 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4897 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4905 default: llvm_unreachable(
"unexpected element type");
4906 case BuiltinType::Char_U:
4907 case BuiltinType::UChar:
4908 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4909 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4910 case BuiltinType::Char_S:
4911 case BuiltinType::SChar:
4912 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4913 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4914 case BuiltinType::UShort:
4915 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4916 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4917 case BuiltinType::Short:
4918 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4919 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4920 case BuiltinType::UInt:
4921 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4922 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4923 case BuiltinType::Int:
4924 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4925 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4926 case BuiltinType::ULong:
4927 case BuiltinType::ULongLong:
4928 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4929 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4930 case BuiltinType::Long:
4931 case BuiltinType::LongLong:
4932 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4933 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4934 case BuiltinType::Float:
4935 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4936 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4937 case BuiltinType::Double:
4938 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4939 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4940 case BuiltinType::UInt128:
4941 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4942 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4943 case BuiltinType::Int128:
4944 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4945 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4949Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
4950 llvm::CmpInst::Predicate UICmpOpc,
4951 llvm::CmpInst::Predicate SICmpOpc,
4952 llvm::CmpInst::Predicate FCmpOpc,
4954 TestAndClearIgnoreResultAssign();
4958 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
4964 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4966 BinOpInfo BOInfo = EmitBinOps(E);
4967 Value *LHS = BOInfo.LHS;
4968 Value *RHS = BOInfo.RHS;
4974 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4976 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4979 Value *FirstVecArg = LHS,
4980 *SecondVecArg = RHS;
4982 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
4986 default: llvm_unreachable(
"is not a comparison operation");
4998 std::swap(FirstVecArg, SecondVecArg);
5005 if (ElementKind == BuiltinType::Float) {
5007 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5008 std::swap(FirstVecArg, SecondVecArg);
5016 if (ElementKind == BuiltinType::Float) {
5018 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5023 std::swap(FirstVecArg, SecondVecArg);
5028 Value *CR6Param = Builder.getInt32(CR6);
5030 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5038 if (ResultTy->getBitWidth() > 1 &&
5040 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5045 if (BOInfo.isFixedPointOp()) {
5046 Result = EmitFixedPointBinOp(BOInfo);
5047 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5048 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5050 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5052 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5054 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5069 LHS = Builder.CreateStripInvariantGroup(LHS);
5071 RHS = Builder.CreateStripInvariantGroup(RHS);
5074 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5080 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5086 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5088 CETy = CTy->getElementType();
5090 LHS.first = Visit(E->
getLHS());
5091 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5094 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5097 CTy->getElementType()) &&
5098 "The element types must always match.");
5101 RHS.first = Visit(E->
getRHS());
5102 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5104 "The element types must always match.");
5107 Value *ResultR, *ResultI;
5111 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5112 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5116 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5117 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5121 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5124 "Complex comparison other than == or != ?");
5125 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5137 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5138 CastKind Kind = ICE->getCastKind();
5139 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5140 *SrcType = ICE->getSubExpr()->getType();
5153 bool Ignore = TestAndClearIgnoreResultAssign();
5187 RHS = Visit(E->
getRHS());
5203 RHS = Visit(E->
getRHS());
5243 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5246Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5254 if (LHS->
getType()->isFPOrFPVectorTy()) {
5255 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5257 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5258 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5260 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5261 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5263 Value *
And = Builder.CreateAnd(LHS, RHS);
5264 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5268 llvm::Type *ResTy = ConvertType(E->
getType());
5289 if (InstrumentRegions &&
5294 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5308 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5314 return llvm::Constant::getNullValue(ResTy);
5327 CodeGenFunction::ConditionalEvaluation eval(CGF);
5336 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5338 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5340 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5349 RHSBlock = Builder.GetInsertBlock();
5354 if (InstrumentRegions &&
5358 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5362 PN->addIncoming(RHSCond, RHSBlockCnt);
5372 PN->addIncoming(RHSCond, RHSBlock);
5382 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5386 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5389Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5397 if (LHS->
getType()->isFPOrFPVectorTy()) {
5398 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5400 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5401 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5403 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5404 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5406 Value *
Or = Builder.CreateOr(LHS, RHS);
5407 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5411 llvm::Type *ResTy = ConvertType(E->
getType());
5432 if (InstrumentRegions &&
5437 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5451 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5457 return llvm::ConstantInt::get(ResTy, 1);
5470 CodeGenFunction::ConditionalEvaluation eval(CGF);
5480 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5482 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5484 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5496 RHSBlock = Builder.GetInsertBlock();
5501 if (InstrumentRegions &&
5505 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5509 PN->addIncoming(RHSCond, RHSBlockCnt);
5515 PN->addIncoming(RHSCond, RHSBlock);
5523 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5526Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5529 return Visit(E->
getRHS());
5554Value *ScalarExprEmitter::
5555VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5556 TestAndClearIgnoreResultAssign();
5559 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5561 Expr *condExpr = E->
getCond();
5569 Expr *live = lhsExpr, *dead = rhsExpr;
5570 if (!CondExprBool) std::swap(live, dead);
5601 llvm::Value *LHS = Visit(lhsExpr);
5602 llvm::Value *RHS = Visit(rhsExpr);
5604 llvm::Type *condType = ConvertType(condExpr->
getType());
5607 unsigned numElem = vecTy->getNumElements();
5608 llvm::Type *elemType = vecTy->getElementType();
5610 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5611 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5612 llvm::Value *tmp = Builder.CreateSExt(
5613 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5614 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5617 llvm::Value *RHSTmp = RHS;
5618 llvm::Value *LHSTmp = LHS;
5619 bool wasCast =
false;
5621 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5622 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5623 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5627 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5628 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5629 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5631 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5641 llvm::Value *LHS = Visit(lhsExpr);
5642 llvm::Value *RHS = Visit(rhsExpr);
5644 llvm::Type *CondType = ConvertType(condExpr->
getType());
5647 if (VecTy->getElementType()->isIntegerTy(1))
5648 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5651 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5653 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5655 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5656 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5665 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5674 llvm::Value *LHS = Visit(lhsExpr);
5675 llvm::Value *RHS = Visit(rhsExpr);
5678 assert(!RHS &&
"LHS and RHS types must match");
5681 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5692 CodeGenFunction::ConditionalEvaluation eval(CGF);
5710 Value *LHS = Visit(lhsExpr);
5713 LHSBlock = Builder.GetInsertBlock();
5714 Builder.CreateBr(ContBlock);
5728 Value *RHS = Visit(rhsExpr);
5731 RHSBlock = Builder.GetInsertBlock();
5741 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5742 PN->addIncoming(LHS, LHSBlock);
5743 PN->addIncoming(RHS, RHSBlock);
5753Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5757Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5759 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5764Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5770 Value *Src,
unsigned NumElementsDst) {
5771 static constexpr int Mask[] = {0, 1, 2, -1};
5772 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5792 const llvm::DataLayout &DL,
5793 Value *Src, llvm::Type *DstTy,
5794 StringRef Name =
"") {
5798 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5799 return Builder.CreateBitCast(Src, DstTy, Name);
5802 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5803 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5806 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5808 if (!DstTy->isIntegerTy())
5809 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5811 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5815 if (!SrcTy->isIntegerTy())
5816 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5818 return Builder.CreateIntToPtr(Src, DstTy, Name);
5821Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5823 llvm::Type *DstTy = ConvertType(E->
getType());
5825 llvm::Type *SrcTy = Src->
getType();
5826 unsigned NumElementsSrc =
5830 unsigned NumElementsDst =
5841 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5846 Src->setName(
"astype");
5853 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5854 auto *Vec4Ty = llvm::FixedVectorType::get(
5860 Src->setName(
"astype");
5865 Src, DstTy,
"astype");
5868Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5880 "Invalid scalar expression to emit");
5882 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5883 .Visit(
const_cast<Expr *
>(E));
5892 "Invalid scalar expression to emit");
5893 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5903 "Invalid complex -> scalar conversion");
5904 return ScalarExprEmitter(*
this)
5905 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5912 if (!PromotionType.
isNull())
5913 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5915 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5921 bool isInc,
bool isPre) {
5922 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5932 llvm::Type *BaseTy =
5948 ScalarExprEmitter Scalar(*
this);
5951#define COMPOUND_OP(Op) \
5952 case BO_##Op##Assign: \
5953 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5990 llvm_unreachable(
"Not valid compound assignment operators");
5993 llvm_unreachable(
"Unhandled compound assignment operator");
6008 llvm::LLVMContext &VMContext,
6014 llvm::Value *TotalOffset =
nullptr;
6020 Value *BasePtr_int =
6021 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6023 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6024 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6025 return {TotalOffset, Builder.getFalse()};
6029 assert(GEP->getPointerOperand() == BasePtr &&
6030 "BasePtr must be the base of the GEP.");
6031 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6033 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6036 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6037 auto *SAddIntrinsic =
6038 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6039 auto *SMulIntrinsic =
6040 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6043 llvm::Value *OffsetOverflows = Builder.getFalse();
6047 llvm::Value *RHS) -> llvm::Value * {
6048 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6051 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6052 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6054 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6057 OffsetOverflows = Builder.getTrue();
6058 return llvm::ConstantInt::get(VMContext, N);
6063 auto *ResultAndOverflow = Builder.CreateCall(
6064 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6065 OffsetOverflows = Builder.CreateOr(
6066 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6067 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6071 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6072 GTI != GTE; ++GTI) {
6073 llvm::Value *LocalOffset;
6074 auto *Index = GTI.getOperand();
6076 if (
auto *STy = GTI.getStructTypeOrNull()) {
6080 LocalOffset = llvm::ConstantInt::get(
6081 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6086 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6087 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6088 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6093 if (!TotalOffset || TotalOffset ==
Zero)
6094 TotalOffset = LocalOffset;
6096 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6099 return {TotalOffset, OffsetOverflows};
6104 ArrayRef<Value *> IdxList,
6105 bool SignedIndices,
bool IsSubtraction,
6106 SourceLocation Loc,
const Twine &Name) {
6107 llvm::Type *PtrTy = Ptr->
getType();
6109 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6110 if (!SignedIndices && !IsSubtraction)
6111 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6113 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6116 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6120 bool PerformNullCheck = !NullPointerIsDefined(
6121 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6124 bool PerformOverflowCheck =
6127 if (!(PerformNullCheck || PerformOverflowCheck))
6130 const auto &DL = CGM.getDataLayout();
6132 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6133 auto CheckHandler = SanitizerHandler::PointerOverflow;
6134 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6135 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6137 GEPOffsetAndOverflow EvaluatedGEP =
6142 "If the offset got constant-folded, we don't expect that there was an "
6145 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6153 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6154 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6156 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6160 if (PerformNullCheck) {
6168 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6169 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6170 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6171 Checks.emplace_back(
Valid, CheckOrdinal);
6174 if (PerformOverflowCheck) {
6179 llvm::Value *ValidGEP;
6180 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6181 if (SignedIndices) {
6187 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6188 auto *PosOrZeroOffset =
6190 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6192 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6193 }
else if (!IsSubtraction) {
6198 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6204 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6206 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6207 Checks.emplace_back(ValidGEP, CheckOrdinal);
6210 assert(!Checks.empty() &&
"Should have produced some checks.");
6212 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6214 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6215 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6221 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6222 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6223 const Twine &Name) {
6224 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6225 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6226 if (!SignedIndices && !IsSubtraction)
6227 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6229 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6233 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6234 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6235 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) 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.