35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
196static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
198 "Expected a unary or binary operator");
202 if (!Op.mayHaveIntegerOverflow())
205 if (Op.Ty->isSignedIntegerType() &&
211 if (Op.Ty->isUnsignedIntegerType() &&
232 if (BO->hasExcludedOverflowPattern())
248 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
254 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
255 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
259class ScalarExprEmitter
261 CodeGenFunction &CGF;
262 CGBuilderTy &Builder;
263 bool IgnoreResultAssign;
264 llvm::LLVMContext &VMContext;
267 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
268 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
269 VMContext(cgf.getLLVMContext()) {
276 bool TestAndClearIgnoreResultAssign() {
277 bool I = IgnoreResultAssign;
278 IgnoreResultAssign =
false;
282 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
283 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
289 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
290 const BinOpInfo &Info);
292 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
296 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
297 const AlignValueAttr *AVAttr =
nullptr;
298 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
299 const ValueDecl *VD = DRE->getDecl();
302 if (
const auto *TTy =
304 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
314 AVAttr = VD->
getAttr<AlignValueAttr>();
319 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
320 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
333 Value *EmitLoadOfLValue(
const Expr *E) {
337 EmitLValueAlignmentAssumption(E,
V);
343 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
347 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
348 Value *Src, QualType SrcType, QualType DstType,
349 llvm::Type *DstTy, SourceLocation Loc);
354 enum ImplicitConversionCheckKind :
unsigned char {
355 ICCK_IntegerTruncation = 0,
356 ICCK_UnsignedIntegerTruncation = 1,
357 ICCK_SignedIntegerTruncation = 2,
358 ICCK_IntegerSignChange = 3,
359 ICCK_SignedIntegerTruncationOrSignChange = 4,
364 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
365 QualType DstType, SourceLocation Loc);
370 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
371 QualType DstType, SourceLocation Loc);
375 struct ScalarConversionOpts {
376 bool TreatBooleanAsSigned;
377 bool EmitImplicitIntegerTruncationChecks;
378 bool EmitImplicitIntegerSignChangeChecks;
380 ScalarConversionOpts()
381 : TreatBooleanAsSigned(
false),
382 EmitImplicitIntegerTruncationChecks(
false),
383 EmitImplicitIntegerSignChangeChecks(
false) {}
385 ScalarConversionOpts(clang::SanitizerSet SanOpts)
386 : TreatBooleanAsSigned(
false),
387 EmitImplicitIntegerTruncationChecks(
388 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
389 EmitImplicitIntegerSignChangeChecks(
390 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
392 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
393 llvm::Type *SrcTy, llvm::Type *DstTy,
394 ScalarConversionOpts Opts);
396 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
398 ScalarConversionOpts Opts = ScalarConversionOpts());
402 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
408 QualType SrcTy, QualType DstTy,
412 Value *EmitNullValue(QualType Ty);
417 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
418 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
422 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
425 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
432 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
433 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
439 ZI->eraseFromParent();
444 return Builder.CreateIsNotNull(
V,
"tobool");
451 Value *Visit(Expr *E) {
452 ApplyDebugLocation DL(CGF, E);
453 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
456 Value *VisitStmt(Stmt *S) {
458 llvm_unreachable(
"Stmt can't have complex result type!");
460 Value *VisitExpr(Expr *S);
462 Value *VisitConstantExpr(ConstantExpr *E) {
468 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
483 Value *VisitParenExpr(ParenExpr *PE) {
486 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
489 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
490 return Visit(
GE->getResultExpr());
492 Value *VisitCoawaitExpr(CoawaitExpr *S) {
495 Value *VisitCoyieldExpr(CoyieldExpr *S) {
498 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
503 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
504 return Builder.getInt(E->
getValue());
506 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
507 return Builder.getInt(E->
getValue());
509 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
510 return llvm::ConstantFP::get(VMContext, E->
getValue());
512 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
513 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
515 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
516 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
518 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
519 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
521 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
525 return EmitNullValue(E->
getType());
527 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
528 return EmitNullValue(E->
getType());
530 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
531 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
532 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
534 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
537 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
541 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
545 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
546 Value *VisitEmbedExpr(EmbedExpr *E);
548 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
557 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
558 llvm_unreachable(
"Codegen for this isn't defined/implemented");
562 Value *VisitDeclRefExpr(DeclRefExpr *E) {
565 return EmitLoadOfLValue(E);
568 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
571 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
574 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
575 return EmitLoadOfLValue(E);
577 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
580 return EmitLoadOfLValue(E);
584 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
590 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
596 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
601 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
602 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
603 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
604 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
605 Value *VisitMemberExpr(MemberExpr *E);
606 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
607 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
613 return EmitLoadOfLValue(E);
616 Value *VisitInitListExpr(InitListExpr *E);
618 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
620 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
624 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
625 return EmitNullValue(E->
getType());
627 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
629 return VisitCastExpr(E);
633 Value *VisitCallExpr(
const CallExpr *E) {
635 return EmitLoadOfLValue(E);
639 EmitLValueAlignmentAssumption(E,
V);
643 Value *VisitStmtExpr(
const StmtExpr *E);
646 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
648 return EmitScalarPrePostIncDec(E, LV,
false,
false);
650 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
652 return EmitScalarPrePostIncDec(E, LV,
true,
false);
654 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
656 return EmitScalarPrePostIncDec(E, LV,
false,
true);
658 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
660 return EmitScalarPrePostIncDec(E, LV,
true,
true);
663 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
667 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
668 bool isInc,
bool isPre);
671 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
675 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
677 Value *VisitUnaryDeref(
const UnaryOperator *E) {
680 return EmitLoadOfLValue(E);
683 Value *VisitUnaryPlus(
const UnaryOperator *E,
684 QualType PromotionType = QualType());
685 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
686 Value *VisitUnaryMinus(
const UnaryOperator *E,
687 QualType PromotionType = QualType());
688 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
690 Value *VisitUnaryNot (
const UnaryOperator *E);
691 Value *VisitUnaryLNot (
const UnaryOperator *E);
692 Value *VisitUnaryReal(
const UnaryOperator *E,
693 QualType PromotionType = QualType());
694 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
695 Value *VisitUnaryImag(
const UnaryOperator *E,
696 QualType PromotionType = QualType());
697 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
698 Value *VisitUnaryExtension(
const UnaryOperator *E) {
703 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
704 return EmitLoadOfLValue(E);
706 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
714 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
715 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
718 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
719 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
722 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
726 Value *VisitExprWithCleanups(ExprWithCleanups *E);
727 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
730 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
735 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
737 return llvm::ConstantInt::get(ConvertType(E->
getType()),
740 return llvm::ConstantInt::get(ConvertType(E->
getType()),
744 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
752 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
753 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
756 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
757 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
760 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
770 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
771 return EmitNullValue(E->
getType());
774 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
779 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
780 return Builder.getInt1(E->
getValue());
784 Value *EmitMul(
const BinOpInfo &Ops) {
785 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
786 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
787 case LangOptions::SOB_Defined:
788 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
789 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
791 case LangOptions::SOB_Undefined:
792 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
793 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
795 case LangOptions::SOB_Trapping:
796 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
797 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
798 return EmitOverflowCheckedBinOp(Ops);
802 if (Ops.Ty->isConstantMatrixType()) {
803 llvm::MatrixBuilder MB(Builder);
807 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
808 BO->getLHS()->getType().getCanonicalType());
809 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
810 BO->getRHS()->getType().getCanonicalType());
811 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
812 if (LHSMatTy && RHSMatTy)
813 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
814 LHSMatTy->getNumColumns(),
815 RHSMatTy->getNumColumns());
816 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
819 if (Ops.Ty->isUnsignedIntegerType() &&
820 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
821 !CanElideOverflowCheck(CGF.
getContext(), Ops))
822 return EmitOverflowCheckedBinOp(Ops);
824 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
826 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
827 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
829 if (Ops.isFixedPointOp())
830 return EmitFixedPointBinOp(Ops);
831 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
835 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
838 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
839 llvm::Value *
Zero,
bool isDiv);
841 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
847 Value *EmitDiv(
const BinOpInfo &Ops);
848 Value *EmitRem(
const BinOpInfo &Ops);
849 Value *EmitAdd(
const BinOpInfo &Ops);
850 Value *EmitSub(
const BinOpInfo &Ops);
851 Value *EmitShl(
const BinOpInfo &Ops);
852 Value *EmitShr(
const BinOpInfo &Ops);
853 Value *EmitAnd(
const BinOpInfo &Ops) {
854 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
856 Value *EmitXor(
const BinOpInfo &Ops) {
857 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
859 Value *EmitOr (
const BinOpInfo &Ops) {
860 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
864 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
866 BinOpInfo EmitBinOps(
const BinaryOperator *E,
867 QualType PromotionTy = QualType());
869 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
870 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
871 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
873 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
874 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
877 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
878 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
880 QualType getPromotionType(QualType Ty) {
882 if (
auto *CT = Ty->
getAs<ComplexType>()) {
883 QualType ElementType = CT->getElementType();
889 if (
auto *VT = Ty->
getAs<VectorType>()) {
890 unsigned NumElements = VT->getNumElements();
900#define HANDLEBINOP(OP) \
901 Value *VisitBin##OP(const BinaryOperator *E) { \
902 QualType promotionTy = getPromotionType(E->getType()); \
903 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
904 if (result && !promotionTy.isNull()) \
905 result = EmitUnPromotedValue(result, E->getType()); \
908 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
909 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
910 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
926 llvm::CmpInst::Predicate SICmpOpc,
927 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
928#define VISITCOMP(CODE, UI, SI, FP, SIG) \
929 Value *VisitBin##CODE(const BinaryOperator *E) { \
930 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
931 llvm::FCmpInst::FP, SIG); }
932 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
946 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
947 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
949 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
954 Value *VisitBlockExpr(
const BlockExpr *BE);
955 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
956 Value *VisitChooseExpr(ChooseExpr *CE);
957 Value *VisitVAArgExpr(VAArgExpr *VE);
958 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
961 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
964 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
967 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
970 Value *VisitAsTypeExpr(AsTypeExpr *CE);
971 Value *VisitAtomicExpr(AtomicExpr *AE);
972 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
985 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
988 return EmitFloatToBoolConversion(Src);
990 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
994 "Unknown scalar type to convert");
997 return EmitIntToBoolConversion(Src);
1000 return EmitPointerToBoolConversion(Src, SrcType);
1003void ScalarExprEmitter::EmitFloatConversionCheck(
1004 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1005 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1006 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1010 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1011 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1012 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1013 using llvm::APFloat;
1016 llvm::Value *Check =
nullptr;
1017 const llvm::fltSemantics &SrcSema =
1027 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1028 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1029 APFloat::opOverflow)
1032 MinSrc = APFloat::getInf(SrcSema,
true);
1036 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1039 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1040 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1041 APFloat::opOverflow)
1044 MaxSrc = APFloat::getInf(SrcSema,
false);
1048 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1053 const llvm::fltSemantics &Sema =
1056 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1057 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1061 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1063 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1064 Check = Builder.CreateAnd(GE, LE);
1069 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1075static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1076 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1079 llvm::Type *SrcTy = Src->
getType();
1080 llvm::Type *DstTy = Dst->
getType();
1085 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1087 "non-integer llvm type");
1094 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1096 if (!SrcSigned && !DstSigned) {
1097 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1098 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1100 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1101 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1104 llvm::Value *Check =
nullptr;
1106 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1108 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1110 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1118void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1119 Value *Dst, QualType DstType,
1120 SourceLocation Loc) {
1130 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1131 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1133 if (SrcBits <= DstBits)
1136 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1143 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1144 (!SrcSigned && DstSigned))
1147 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1148 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1151 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1156 SanitizerDebugLocation SanScope(
1158 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1159 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1170 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1177 llvm::Constant *StaticArgs[] = {
1180 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1181 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1183 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1190 llvm::Type *VTy =
V->getType();
1193 return llvm::ConstantInt::getFalse(VTy->getContext());
1195 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1196 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1197 llvm::Twine(Name) +
"." +
V->getName() +
1198 ".negativitycheck");
1203static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1204 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1207 llvm::Type *SrcTy = Src->
getType();
1208 llvm::Type *DstTy = Dst->
getType();
1211 "non-integer llvm type");
1217 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1218 unsigned DstBits = DstTy->getScalarSizeInBits();
1222 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1223 "either the widths should be different, or the signednesses.");
1226 llvm::Value *SrcIsNegative =
1229 llvm::Value *DstIsNegative =
1235 llvm::Value *Check =
nullptr;
1236 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1238 return std::make_pair(
1239 ScalarExprEmitter::ICCK_IntegerSignChange,
1240 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1243void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1244 Value *Dst, QualType DstType,
1245 SourceLocation Loc) {
1246 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1249 llvm::Type *SrcTy = Src->
getType();
1250 llvm::Type *DstTy = Dst->
getType();
1260 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1261 unsigned DstBits = DstTy->getScalarSizeInBits();
1268 if (SrcSigned == DstSigned && SrcBits == DstBits)
1272 if (!SrcSigned && !DstSigned)
1277 if ((DstBits > SrcBits) && DstSigned)
1279 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1280 (SrcBits > DstBits) && SrcSigned) {
1289 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1293 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1297 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1298 SanitizerDebugLocation SanScope(
1300 {SanitizerKind::SO_ImplicitIntegerSignChange,
1301 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1302 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1305 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1306 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1310 ImplicitConversionCheckKind CheckKind;
1311 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1318 CheckKind = Check.first;
1319 Checks.emplace_back(Check.second);
1321 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1322 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1328 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1329 Checks.emplace_back(Check.second);
1333 llvm::Constant *StaticArgs[] = {
1336 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1337 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1339 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1344static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1345 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1351 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1352 if (!SrcSigned && !DstSigned)
1353 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1355 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1357 llvm::Value *Check =
nullptr;
1359 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1361 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1364 return std::make_pair(
1366 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1371static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1372 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1376 llvm::Value *SrcIsNegative =
1379 llvm::Value *DstIsNegative =
1385 llvm::Value *Check =
nullptr;
1387 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1389 return std::make_pair(
1390 ScalarExprEmitter::ICCK_IntegerSignChange,
1391 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1399 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1417 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1418 unsigned DstBits = Info.
Size;
1423 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1425 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1427 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1428 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1432 bool EmitTruncation = DstBits < SrcBits;
1436 bool EmitTruncationFromUnsignedToSigned =
1437 EmitTruncation && DstSigned && !SrcSigned;
1439 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1440 bool BothUnsigned = !SrcSigned && !DstSigned;
1441 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1448 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1453 else if (EmitSignChange) {
1454 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1455 "either the widths should be different, or the signednesses.");
1461 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1462 if (EmitTruncationFromUnsignedToSigned)
1463 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1465 llvm::Constant *StaticArgs[] = {
1468 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1469 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1471 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1475 QualType DstType, llvm::Type *SrcTy,
1477 ScalarConversionOpts Opts) {
1479 llvm::Type *SrcElementTy;
1480 llvm::Type *DstElementTy;
1490 "cannot cast between matrix and non-matrix types");
1491 SrcElementTy = SrcTy;
1492 DstElementTy = DstTy;
1493 SrcElementType = SrcType;
1494 DstElementType = DstType;
1499 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1504 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1506 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1507 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1511 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1518 llvm::Intrinsic::ID IID =
1519 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1520 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1524 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1525 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1528 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1529 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1530 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1532 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1533 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1534 return Builder.CreateFPExt(Src, DstTy,
"conv");
1539Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1542 ScalarConversionOpts Opts) {
1557 return Builder.CreateIsNotNull(Src,
"tobool");
1560 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1563 "Unhandled scalar conversion from a fixed point type to another type.");
1567 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1570 "Unhandled scalar conversion to a fixed point type from another type.");
1573 QualType NoncanonicalSrcType = SrcType;
1574 QualType NoncanonicalDstType = DstType;
1578 if (SrcType == DstType)
return Src;
1582 llvm::Value *OrigSrc = Src;
1583 QualType OrigSrcType = SrcType;
1584 llvm::Type *SrcTy = Src->
getType();
1588 return EmitConversionToBool(Src, SrcType);
1590 llvm::Type *DstTy = ConvertType(DstType);
1595 if (DstTy->isFloatingPointTy()) {
1597 return Builder.CreateCall(
1605 Src = Builder.CreateCall(
1610 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1618 if (SrcTy == DstTy) {
1619 if (Opts.EmitImplicitIntegerSignChangeChecks)
1620 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1621 NoncanonicalDstType, Loc);
1629 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1634 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1639 llvm::Value* IntResult =
1640 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1642 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1648 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1655 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1657 "Splatted expr doesn't match with vector element type?");
1661 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1665 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1669 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1670 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1671 if (SrcSize == DstSize)
1672 return Builder.CreateBitCast(Src, DstTy,
"conv");
1685 assert(((SrcElementTy->isIntegerTy() &&
1686 DstElementTy->isIntegerTy()) ||
1687 (SrcElementTy->isFloatingPointTy() &&
1688 DstElementTy->isFloatingPointTy())) &&
1689 "unexpected conversion between a floating-point vector and an "
1693 if (SrcElementTy->isIntegerTy())
1694 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1697 if (SrcSize > DstSize)
1698 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1701 return Builder.CreateFPExt(Src, DstTy,
"conv");
1705 Value *Res =
nullptr;
1706 llvm::Type *ResTy = DstTy;
1713 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1715 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1721 if (SrcTy->isFloatingPointTy()) {
1725 return Builder.CreateCall(
1728 return Builder.CreateFPTrunc(Src, DstTy);
1733 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1735 if (DstTy != ResTy) {
1737 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1738 Res = Builder.CreateCall(
1742 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1746 if (Opts.EmitImplicitIntegerTruncationChecks)
1747 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1748 NoncanonicalDstType, Loc);
1750 if (Opts.EmitImplicitIntegerSignChangeChecks)
1751 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1752 NoncanonicalDstType, Loc);
1757Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1759 SourceLocation Loc) {
1760 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1763 Result = FPBuilder.CreateFloatingToFixed(Src,
1766 Result = FPBuilder.CreateFixedToFloating(Src,
1768 ConvertType(DstTy));
1774 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1775 DstFPSema.getWidth(),
1776 DstFPSema.isSigned());
1778 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1781 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1788Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1790 SourceLocation Loc) {
1792 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1797 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1798 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1799 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1806 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1809Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1817void ScalarExprEmitter::EmitBinOpCheck(
1818 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1819 const BinOpInfo &Info) {
1822 SmallVector<llvm::Constant *, 4> StaticData;
1823 SmallVector<llvm::Value *, 2> DynamicData;
1831 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1832 if (UO && UO->
getOpcode() == UO_Minus) {
1833 Check = SanitizerHandler::NegateOverflow;
1835 DynamicData.push_back(Info.RHS);
1839 Check = SanitizerHandler::ShiftOutOfBounds;
1841 StaticData.push_back(
1843 StaticData.push_back(
1845 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1847 Check = SanitizerHandler::DivremOverflow;
1851 int ArithOverflowKind = 0;
1854 Check = SanitizerHandler::AddOverflow;
1855 ArithOverflowKind = diag::UBSanArithKind::Add;
1859 Check = SanitizerHandler::SubOverflow;
1860 ArithOverflowKind = diag::UBSanArithKind::Sub;
1864 Check = SanitizerHandler::MulOverflow;
1865 ArithOverflowKind = diag::UBSanArithKind::Mul;
1869 llvm_unreachable(
"unexpected opcode for bin op check");
1873 SanitizerKind::UnsignedIntegerOverflow) ||
1875 SanitizerKind::SignedIntegerOverflow)) {
1879 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1883 DynamicData.push_back(Info.LHS);
1884 DynamicData.push_back(Info.RHS);
1887 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1894Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1902ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1904 unsigned AddrSpace =
1906 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1909 llvm::Type *ExprTy = ConvertType(E->
getType());
1910 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1914Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1916 auto It = E->
begin();
1917 return Builder.getInt((*It)->getValue());
1920Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1928 unsigned LHSElts = LTy->getNumElements();
1936 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1937 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1945 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1946 MTy->getNumElements());
1947 Value* NewV = llvm::PoisonValue::get(RTy);
1948 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1949 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1950 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1952 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1953 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1961 SmallVector<int, 32> Indices;
1965 if (Idx.isSigned() && Idx.isAllOnes())
1966 Indices.push_back(-1);
1968 Indices.push_back(Idx.getZExtValue());
1971 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1974Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1982 if (SrcType == DstType)
return Src;
1985 "ConvertVector source type must be a vector");
1987 "ConvertVector destination type must be a vector");
1989 llvm::Type *SrcTy = Src->
getType();
1990 llvm::Type *DstTy = ConvertType(DstType);
1996 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
1997 DstEltType = DstType->
castAs<VectorType>()->getElementType();
1999 assert(SrcTy->isVectorTy() &&
2000 "ConvertVector source IR type must be a vector");
2001 assert(DstTy->isVectorTy() &&
2002 "ConvertVector destination IR type must be a vector");
2007 if (DstEltType->isBooleanType()) {
2008 assert((SrcEltTy->isFloatingPointTy() ||
2011 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2012 if (SrcEltTy->isFloatingPointTy()) {
2013 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2014 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2016 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2021 Value *Res =
nullptr;
2026 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2028 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2030 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2032 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2035 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2036 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2037 if (DstEltType->isSignedIntegerOrEnumerationType())
2038 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2040 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2042 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2043 "Unknown real conversion");
2044 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2045 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2046 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2048 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2054Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2063 return Builder.getInt(
Value);
2067 llvm::Value *
Result = EmitLoadOfLValue(E);
2073 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2074 if (llvm::GetElementPtrInst *GEP =
2075 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2076 if (llvm::Instruction *
Pointer =
2077 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2089Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2090 TestAndClearIgnoreResultAssign();
2098 return EmitLoadOfLValue(E);
2106 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2109 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2112Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2113 TestAndClearIgnoreResultAssign();
2121 unsigned NumRows = MatrixTy->getNumRows();
2122 llvm::MatrixBuilder MB(Builder);
2123 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2125 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2130 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2135 int MV = SVI->getMaskValue(Idx);
2142 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2143 "Index operand too large for shufflevector mask!");
2144 return C->getZExtValue();
2147Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2148 bool Ignore = TestAndClearIgnoreResultAssign();
2151 assert((Ignore ==
false ||
2153 "init list ignored");
2170 llvm::VectorType *VType =
2171 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2174 if (NumInitElements == 0) {
2176 return EmitNullValue(E->
getType());
2183 if (NumInitElements == 0) {
2185 return EmitNullValue(E->
getType());
2188 if (NumInitElements == 1) {
2189 Expr *InitVector = E->
getInit(0);
2194 return Visit(InitVector);
2197 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2207 unsigned CurIdx = 0;
2208 bool VIsPoisonShuffle =
false;
2209 llvm::Value *
V = llvm::PoisonValue::get(VType);
2210 for (
unsigned i = 0; i != NumInitElements; ++i) {
2213 SmallVector<int, 16> Args;
2215 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2225 ->getNumElements() == ResElts) {
2227 Value *LHS =
nullptr, *RHS =
nullptr;
2232 Args.resize(ResElts, -1);
2234 LHS = EI->getVectorOperand();
2236 VIsPoisonShuffle =
true;
2237 }
else if (VIsPoisonShuffle) {
2240 for (
unsigned j = 0; j != CurIdx; ++j)
2242 Args.push_back(ResElts +
C->getZExtValue());
2243 Args.resize(ResElts, -1);
2246 RHS = EI->getVectorOperand();
2247 VIsPoisonShuffle =
false;
2249 if (!Args.empty()) {
2250 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2256 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2258 VIsPoisonShuffle =
false;
2268 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2271 Value *SVOp = SVI->getOperand(0);
2274 if (OpTy->getNumElements() == ResElts) {
2275 for (
unsigned j = 0; j != CurIdx; ++j) {
2278 if (VIsPoisonShuffle) {
2284 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2286 Args.resize(ResElts, -1);
2288 if (VIsPoisonShuffle)
2298 for (
unsigned j = 0; j != InitElts; ++j)
2300 Args.resize(ResElts, -1);
2301 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2304 for (
unsigned j = 0; j != CurIdx; ++j)
2306 for (
unsigned j = 0; j != InitElts; ++j)
2307 Args.push_back(j + Offset);
2308 Args.resize(ResElts, -1);
2315 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2322 llvm::Type *EltTy = VType->getElementType();
2325 for (; CurIdx < ResElts; ++CurIdx) {
2326 Value *Idx = Builder.getInt32(CurIdx);
2327 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2328 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2340 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2344 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2347 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2366 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2370 if (
const auto *CE = dyn_cast<CastExpr>(E))
2371 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2372 CE->getCastKind() == CK_ArrayToPointerDecay)
2383 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2393 if (ICE->isGLValue())
2408 assert(LoadList.size() >= VecTy->getNumElements() &&
2409 "Flattened type on RHS must have the same number or more elements "
2410 "than vector on LHS.");
2414 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2417 "All flattened source values should be scalars.");
2420 VecTy->getElementType(), Loc);
2421 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2427 "Destination type must be a vector or builtin type.");
2429 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2438 auto RestoreCurCast =
2439 llvm::make_scope_exit([
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2443 QualType DestTy = CE->
getType();
2445 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2449 bool Ignored = TestAndClearIgnoreResultAssign();
2455 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2456 case CK_BuiltinFnToFnPtr:
2457 llvm_unreachable(
"builtin functions are handled elsewhere");
2459 case CK_LValueBitCast:
2460 case CK_ObjCObjectLValueCast: {
2461 Address
Addr = EmitLValue(E).getAddress();
2464 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2467 case CK_LValueToRValueBitCast: {
2473 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2476 case CK_CPointerToObjCPointerCast:
2477 case CK_BlockPointerToObjCPointerCast:
2478 case CK_AnyPointerToBlockPointerCast:
2480 Value *Src = Visit(E);
2481 llvm::Type *SrcTy = Src->
getType();
2482 llvm::Type *DstTy = ConvertType(DestTy);
2493 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2498 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2499 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2500 "Address-space cast must be used to convert address spaces");
2502 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2503 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2505 PT->getPointeeType(),
2516 const QualType SrcType = E->
getType();
2521 Src = Builder.CreateLaunderInvariantGroup(Src);
2529 Src = Builder.CreateStripInvariantGroup(Src);
2534 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2538 if (!PointeeType.
isNull())
2547 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2548 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2551 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2552 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2553 ScalableDstTy = llvm::ScalableVectorType::get(
2554 FixedSrcTy->getElementType(),
2556 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2558 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2559 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2560 llvm::Value *
Result = Builder.CreateInsertVector(
2561 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2563 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2564 if (
Result->getType() != ScalableDstTy)
2566 if (
Result->getType() != DstTy)
2576 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2577 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2580 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2581 FixedDstTy->getElementType()->isIntegerTy(8)) {
2582 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2583 ScalableSrcTy = llvm::ScalableVectorType::get(
2584 ScalableSrcTy->getElementType(),
2586 ScalableSrcTy->getElementCount().getKnownMinValue()));
2587 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2588 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2592 ScalableSrcTy = llvm::ScalableVectorType::get(
2593 FixedDstTy->getElementType(),
2594 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2595 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2597 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2598 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2619 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2622 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2625 case CK_AddressSpaceConversion: {
2628 Result.Val.isNullPointer()) {
2632 if (
Result.HasSideEffects)
2635 ConvertType(DestTy)), DestTy);
2641 ConvertType(DestTy));
2643 case CK_AtomicToNonAtomic:
2644 case CK_NonAtomicToAtomic:
2645 case CK_UserDefinedConversion:
2652 case CK_BaseToDerived: {
2654 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2668 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2676 case CK_UncheckedDerivedToBase:
2677 case CK_DerivedToBase: {
2690 case CK_ArrayToPointerDecay:
2693 case CK_FunctionToPointerDecay:
2694 return EmitLValue(E).getPointer(CGF);
2696 case CK_NullToPointer:
2697 if (MustVisitNullValue(E))
2703 case CK_NullToMemberPointer: {
2704 if (MustVisitNullValue(E))
2707 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2711 case CK_ReinterpretMemberPointer:
2712 case CK_BaseToDerivedMemberPointer:
2713 case CK_DerivedToBaseMemberPointer: {
2714 Value *Src = Visit(E);
2725 case CK_ARCProduceObject:
2727 case CK_ARCConsumeObject:
2729 case CK_ARCReclaimReturnedObject:
2731 case CK_ARCExtendBlockObject:
2734 case CK_CopyAndAutoreleaseBlockObject:
2737 case CK_FloatingRealToComplex:
2738 case CK_FloatingComplexCast:
2739 case CK_IntegralRealToComplex:
2740 case CK_IntegralComplexCast:
2741 case CK_IntegralComplexToFloatingComplex:
2742 case CK_FloatingComplexToIntegralComplex:
2743 case CK_ConstructorConversion:
2745 case CK_HLSLArrayRValue:
2746 llvm_unreachable(
"scalar cast to non-scalar value");
2748 case CK_LValueToRValue:
2750 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2753 case CK_IntegralToPointer: {
2754 Value *Src = Visit(E);
2758 auto DestLLVMTy = ConvertType(DestTy);
2761 llvm::Value* IntResult =
2762 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2764 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2770 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2776 case CK_PointerToIntegral: {
2777 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2778 auto *PtrExpr = Visit(E);
2781 const QualType SrcType = E->
getType();
2786 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2790 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2796 case CK_MatrixCast: {
2797 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2804 case CK_HLSLAggregateSplatCast:
2805 case CK_VectorSplat: {
2806 llvm::Type *DstTy = ConvertType(DestTy);
2807 Value *Elt = Visit(E);
2809 llvm::ElementCount NumElements =
2811 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2814 case CK_FixedPointCast:
2815 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2818 case CK_FixedPointToBoolean:
2820 "Expected src type to be fixed point type");
2821 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2822 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2825 case CK_FixedPointToIntegral:
2827 "Expected src type to be fixed point type");
2828 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2829 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2832 case CK_IntegralToFixedPoint:
2834 "Expected src type to be an integer");
2836 "Expected dest type to be fixed point type");
2837 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2840 case CK_IntegralCast: {
2842 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2843 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2847 ScalarConversionOpts Opts;
2848 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2849 if (!ICE->isPartOfExplicitCast())
2850 Opts = ScalarConversionOpts(CGF.
SanOpts);
2852 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2855 case CK_IntegralToFloating: {
2858 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2860 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2861 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2863 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2864 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2867 case CK_FloatingToIntegral: {
2870 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2872 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2873 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2875 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2876 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2879 case CK_FloatingCast: {
2882 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2883 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2884 if (DstElTy->
castAs<BuiltinType>()->getKind() <
2885 SrcElTy->
castAs<BuiltinType>()->getKind())
2886 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2887 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2889 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2890 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2893 case CK_FixedPointToFloating:
2894 case CK_FloatingToFixedPoint: {
2895 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2896 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2899 case CK_BooleanToSignedIntegral: {
2900 ScalarConversionOpts Opts;
2901 Opts.TreatBooleanAsSigned =
true;
2902 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2905 case CK_IntegralToBoolean:
2906 return EmitIntToBoolConversion(Visit(E));
2907 case CK_PointerToBoolean:
2908 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2909 case CK_FloatingToBoolean: {
2910 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2911 return EmitFloatToBoolConversion(Visit(E));
2913 case CK_MemberPointerToBoolean: {
2914 llvm::Value *MemPtr = Visit(E);
2915 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
2919 case CK_FloatingComplexToReal:
2920 case CK_IntegralComplexToReal:
2923 case CK_FloatingComplexToBoolean:
2924 case CK_IntegralComplexToBoolean: {
2928 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2932 case CK_ZeroToOCLOpaqueType: {
2935 "CK_ZeroToOCLEvent cast on non-event type");
2936 return llvm::Constant::getNullValue(ConvertType(DestTy));
2939 case CK_IntToOCLSampler:
2942 case CK_HLSLVectorTruncation: {
2944 "Destination type must be a vector or builtin type.");
2945 Value *Vec = Visit(E);
2946 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
2947 SmallVector<int> Mask;
2948 unsigned NumElts = VecTy->getNumElements();
2949 for (
unsigned I = 0; I != NumElts; ++I)
2952 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2954 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
2955 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
2957 case CK_HLSLElementwiseCast: {
2961 assert(RV.
isAggregate() &&
"Not a valid HLSL Elementwise Cast.");
2968 llvm_unreachable(
"unknown scalar cast");
2971Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
2972 CodeGenFunction::StmtExprEvaluation eval(CGF);
2981Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
2982 CodeGenFunction::RunCleanupsScope Scope(CGF);
2986 Scope.ForceCleanup({&
V});
2995 llvm::Value *InVal,
bool IsInc,
2999 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3001 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3002 BinOp.FPFeatures = FPFeatures;
3007llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3008 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3009 llvm::Value *Amount =
3010 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3011 StringRef Name = IsInc ?
"inc" :
"dec";
3012 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3013 case LangOptions::SOB_Defined:
3014 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3015 return Builder.CreateAdd(InVal, Amount, Name);
3017 case LangOptions::SOB_Undefined:
3018 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3019 return Builder.CreateNSWAdd(InVal, Amount, Name);
3021 case LangOptions::SOB_Trapping:
3025 return Builder.CreateNSWAdd(InVal, Amount, Name);
3026 return EmitOverflowCheckedBinOp(Info);
3028 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3053class OMPLastprivateConditionalUpdateRAII {
3055 CodeGenFunction &CGF;
3056 const UnaryOperator *E;
3059 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3060 const UnaryOperator *E)
3062 ~OMPLastprivateConditionalUpdateRAII() {
3071ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3072 bool isInc,
bool isPre) {
3074 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3076 llvm::PHINode *atomicPHI =
nullptr;
3080 QualType SrcType = E->
getType();
3082 int amount = (isInc ? 1 : -1);
3083 bool isSubtraction = !isInc;
3085 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3086 type = atomicTy->getValueType();
3087 if (isInc &&
type->isBooleanType()) {
3090 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3091 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3092 return Builder.getTrue();
3096 return Builder.CreateAtomicRMW(
3097 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3098 llvm::AtomicOrdering::SequentiallyConsistent);
3103 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3104 !(
type->isUnsignedIntegerType() &&
3105 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3107 LangOptions::SOB_Trapping) {
3108 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3109 llvm::AtomicRMWInst::Sub;
3110 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3111 llvm::Instruction::Sub;
3113 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3115 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3116 llvm::AtomicOrdering::SequentiallyConsistent);
3117 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3121 if (
type->isFloatingType()) {
3122 llvm::Type *Ty = ConvertType(
type);
3123 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3124 llvm::AtomicRMWInst::BinOp aop =
3125 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3126 llvm::Instruction::BinaryOps op =
3127 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3128 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3129 llvm::AtomicRMWInst *old =
3131 llvm::AtomicOrdering::SequentiallyConsistent);
3133 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3136 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3139 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3142 Builder.CreateBr(opBB);
3143 Builder.SetInsertPoint(opBB);
3144 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3145 atomicPHI->addIncoming(value, startBB);
3148 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3159 if (isInc &&
type->isBooleanType()) {
3160 value = Builder.getTrue();
3163 }
else if (
type->isIntegerType()) {
3164 QualType promotedType;
3165 bool canPerformLossyDemotionCheck =
false;
3167 bool excludeOverflowPattern =
3172 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3173 canPerformLossyDemotionCheck =
true;
3174 canPerformLossyDemotionCheck &=
3177 canPerformLossyDemotionCheck &=
3179 type, promotedType);
3180 assert((!canPerformLossyDemotionCheck ||
3181 type->isSignedIntegerOrEnumerationType() ||
3183 ConvertType(
type)->getScalarSizeInBits() ==
3184 ConvertType(promotedType)->getScalarSizeInBits()) &&
3185 "The following check expects that if we do promotion to different "
3186 "underlying canonical type, at least one of the types (either "
3187 "base or promoted) will be signed, or the bitwidths will match.");
3190 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3191 SanitizerKind::ImplicitBitfieldConversion) &&
3192 canPerformLossyDemotionCheck) {
3206 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3207 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3208 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3212 ScalarConversionOpts Opts;
3213 if (!LV.isBitField())
3214 Opts = ScalarConversionOpts(CGF.
SanOpts);
3215 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3217 SrcType = promotedType;
3220 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3226 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3227 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3229 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3230 !excludeOverflowPattern &&
3232 SanitizerKind::UnsignedIntegerOverflow, E->
getType())) {
3236 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3237 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3241 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3242 QualType
type = ptr->getPointeeType();
3245 if (
const VariableArrayType *vla
3248 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3251 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3254 elemTy, value, numElts,
false, isSubtraction,
3258 }
else if (
type->isFunctionType()) {
3259 llvm::Value *amt = Builder.getInt32(amount);
3262 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3266 false, isSubtraction,
3271 llvm::Value *amt = Builder.getInt32(amount);
3274 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3277 elemTy, value, amt,
false, isSubtraction,
3282 }
else if (
type->isVectorType()) {
3283 if (
type->hasIntegerRepresentation()) {
3284 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
3286 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3288 value = Builder.CreateFAdd(
3290 llvm::ConstantFP::get(value->getType(), amount),
3291 isInc ?
"inc" :
"dec");
3295 }
else if (
type->isRealFloatingType()) {
3298 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3303 value = Builder.CreateCall(
3306 input,
"incdec.conv");
3308 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3312 if (value->getType()->isFloatTy())
3313 amt = llvm::ConstantFP::get(VMContext,
3314 llvm::APFloat(
static_cast<float>(amount)));
3315 else if (value->getType()->isDoubleTy())
3316 amt = llvm::ConstantFP::get(VMContext,
3317 llvm::APFloat(
static_cast<double>(amount)));
3321 llvm::APFloat F(
static_cast<float>(amount));
3323 const llvm::fltSemantics *FS;
3326 if (value->getType()->isFP128Ty())
3328 else if (value->getType()->isHalfTy())
3330 else if (value->getType()->isBFloatTy())
3332 else if (value->getType()->isPPC_FP128Ty())
3336 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3337 amt = llvm::ConstantFP::get(VMContext, F);
3339 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3343 value = Builder.CreateCall(
3346 value,
"incdec.conv");
3348 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3353 }
else if (
type->isFixedPointType()) {
3360 Info.Opcode = isInc ? BO_Add : BO_Sub;
3362 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3365 if (
type->isSignedFixedPointType()) {
3366 Info.Opcode = isInc ? BO_Sub : BO_Add;
3367 Info.RHS = Builder.CreateNeg(Info.RHS);
3372 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3374 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3375 value = EmitFixedPointBinOp(Info);
3379 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3382 if (!isInc) size = -size;
3383 llvm::Value *sizeValue =
3384 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3387 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3390 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3392 value = Builder.CreateBitCast(value, input->getType());
3396 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3401 llvm::Value *
success = Pair.second;
3402 atomicPHI->addIncoming(old, curBlock);
3403 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3404 Builder.SetInsertPoint(contBB);
3405 return isPre ? value : input;
3409 if (LV.isBitField()) {
3419 return isPre ? value : input;
3423Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3424 QualType PromotionType) {
3425 QualType promotionTy = PromotionType.
isNull()
3428 Value *result = VisitPlus(E, promotionTy);
3429 if (result && !promotionTy.
isNull())
3430 result = EmitUnPromotedValue(result, E->
getType());
3434Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3435 QualType PromotionType) {
3437 TestAndClearIgnoreResultAssign();
3438 if (!PromotionType.
isNull())
3443Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3444 QualType PromotionType) {
3445 QualType promotionTy = PromotionType.
isNull()
3448 Value *result = VisitMinus(E, promotionTy);
3449 if (result && !promotionTy.
isNull())
3450 result = EmitUnPromotedValue(result, E->
getType());
3454Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3455 QualType PromotionType) {
3456 TestAndClearIgnoreResultAssign();
3458 if (!PromotionType.
isNull())
3464 if (Op->
getType()->isFPOrFPVectorTy())
3465 return Builder.CreateFNeg(Op,
"fneg");
3470 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3472 BinOp.Opcode = BO_Sub;
3475 return EmitSub(BinOp);
3478Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3479 TestAndClearIgnoreResultAssign();
3481 return Builder.CreateNot(Op,
"not");
3484Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3488 VectorKind::Generic) {
3492 if (Oper->
getType()->isFPOrFPVectorTy()) {
3493 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3495 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3497 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3498 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3507 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3510 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3513Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3515 Expr::EvalResult EVResult;
3518 return Builder.getInt(
Value);
3523 llvm::Type* ResultType = ConvertType(E->
getType());
3524 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3526 for (
unsigned i = 0; i != n; ++i) {
3528 llvm::Value *Offset =
nullptr;
3535 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3542 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3546 Offset = Builder.CreateMul(Idx, ElemSize);
3551 FieldDecl *MemberDecl = ON.
getField();
3559 FieldEnd = RD->field_end();
3560 Field != FieldEnd; ++Field, ++i) {
3561 if (*Field == MemberDecl)
3564 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3569 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3572 CurrentType = MemberDecl->
getType();
3577 llvm_unreachable(
"dependent __builtin_offsetof");
3594 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3606ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3607 const UnaryExprOrTypeTraitExpr *E) {
3610 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3611 if (
const VariableArrayType *VAT =
3616 bool EvaluateExtent =
true;
3617 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3619 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3621 if (EvaluateExtent) {
3632 if (Kind == UETT_CountOf)
3641 if (!eltSize.
isOne())
3644 return VlaSize.NumElts;
3647 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3653 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3654 }
else if (E->
getKind() == UETT_VectorElements) {
3656 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3664Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3665 QualType PromotionType) {
3666 QualType promotionTy = PromotionType.
isNull()
3669 Value *result = VisitReal(E, promotionTy);
3670 if (result && !promotionTy.
isNull())
3671 result = EmitUnPromotedValue(result, E->
getType());
3675Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3676 QualType PromotionType) {
3683 if (!PromotionType.
isNull()) {
3685 Op, IgnoreResultAssign,
true);
3700 if (!PromotionType.
isNull())
3705Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3706 QualType PromotionType) {
3707 QualType promotionTy = PromotionType.
isNull()
3710 Value *result = VisitImag(E, promotionTy);
3711 if (result && !promotionTy.
isNull())
3712 result = EmitUnPromotedValue(result, E->
getType());
3716Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3717 QualType PromotionType) {
3724 if (!PromotionType.
isNull()) {
3726 Op,
true, IgnoreResultAssign);
3730 return result.second
3746 else if (!PromotionType.
isNull())
3750 if (!PromotionType.
isNull())
3751 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3752 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3759Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3760 QualType PromotionType) {
3761 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3764Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3765 QualType ExprType) {
3766 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3769Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3771 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3773#define HANDLE_BINOP(OP) \
3775 return Emit##OP(EmitBinOps(BO, PromotionType));
3784 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3787 return VisitImag(UO, PromotionType);
3789 return VisitReal(UO, PromotionType);
3791 return VisitMinus(UO, PromotionType);
3793 return VisitPlus(UO, PromotionType);
3798 auto result = Visit(
const_cast<Expr *
>(E));
3800 if (!PromotionType.
isNull())
3801 return EmitPromotedValue(result, PromotionType);
3803 return EmitUnPromotedValue(result, E->
getType());
3808BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3809 QualType PromotionType) {
3810 TestAndClearIgnoreResultAssign();
3814 if (!PromotionType.
isNull())
3815 Result.Ty = PromotionType;
3824LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3825 const CompoundAssignOperator *E,
3826 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3837 QualType PromotionTypeCR;
3839 if (PromotionTypeCR.
isNull())
3842 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3843 if (!PromotionTypeRHS.
isNull())
3846 OpInfo.RHS = Visit(E->
getRHS());
3847 OpInfo.Ty = PromotionTypeCR;
3854 llvm::PHINode *atomicPHI =
nullptr;
3855 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3856 QualType
type = atomicTy->getValueType();
3857 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3858 !(
type->isUnsignedIntegerType() &&
3859 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3861 LangOptions::SOB_Trapping) {
3862 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3863 llvm::Instruction::BinaryOps Op;
3864 switch (OpInfo.Opcode) {
3866 case BO_MulAssign:
case BO_DivAssign:
3872 AtomicOp = llvm::AtomicRMWInst::Add;
3873 Op = llvm::Instruction::Add;
3876 AtomicOp = llvm::AtomicRMWInst::Sub;
3877 Op = llvm::Instruction::Sub;
3880 AtomicOp = llvm::AtomicRMWInst::And;
3881 Op = llvm::Instruction::And;
3884 AtomicOp = llvm::AtomicRMWInst::Xor;
3885 Op = llvm::Instruction::Xor;
3888 AtomicOp = llvm::AtomicRMWInst::Or;
3889 Op = llvm::Instruction::Or;
3892 llvm_unreachable(
"Invalid compound assignment type");
3894 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3896 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3900 llvm::AtomicRMWInst *OldVal =
3905 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3911 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3913 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3915 Builder.CreateBr(opBB);
3916 Builder.SetInsertPoint(opBB);
3917 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3918 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3919 OpInfo.LHS = atomicPHI;
3922 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3924 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3926 if (!PromotionTypeLHS.
isNull())
3927 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3930 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3941 if (LHSLV.isBitField()) {
3943 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
3945 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
3946 ScalarConversionOpts(CGF.
SanOpts));
3949 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3953 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3954 llvm::Value *
success = Pair.second;
3955 atomicPHI->addIncoming(old, curBlock);
3956 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3957 Builder.SetInsertPoint(contBB);
3965 if (LHSLV.isBitField()) {
3981Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
3982 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3983 bool Ignore = TestAndClearIgnoreResultAssign();
3984 Value *RHS =
nullptr;
3985 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3996 if (!LHS.isVolatileQualified())
4000 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4003void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4004 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4005 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4008 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4009 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4010 SanitizerKind::SO_IntegerDivideByZero));
4014 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4015 Ops.Ty->hasSignedIntegerRepresentation() &&
4017 Ops.mayHaveIntegerOverflow()) {
4020 llvm::Value *IntMin =
4021 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4022 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4024 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4025 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4026 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4028 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4031 if (Checks.size() > 0)
4032 EmitBinOpCheck(Checks, Ops);
4035Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4037 SanitizerDebugLocation SanScope(&CGF,
4038 {SanitizerKind::SO_IntegerDivideByZero,
4039 SanitizerKind::SO_SignedIntegerOverflow,
4040 SanitizerKind::SO_FloatDivideByZero},
4041 SanitizerHandler::DivremOverflow);
4042 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4043 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4044 Ops.Ty->isIntegerType() &&
4045 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4046 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4047 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4048 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4049 Ops.Ty->isRealFloatingType() &&
4050 Ops.mayHaveFloatDivisionByZero()) {
4051 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4052 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4054 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4058 if (Ops.Ty->isConstantMatrixType()) {
4059 llvm::MatrixBuilder MB(Builder);
4066 "first operand must be a matrix");
4068 "second operand must be an arithmetic type");
4069 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4070 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4071 Ops.Ty->hasUnsignedIntegerRepresentation());
4074 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4076 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4077 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4081 else if (Ops.isFixedPointOp())
4082 return EmitFixedPointBinOp(Ops);
4083 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4084 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4086 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4089Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4091 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4092 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4093 Ops.Ty->isIntegerType() &&
4094 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4095 SanitizerDebugLocation SanScope(&CGF,
4096 {SanitizerKind::SO_IntegerDivideByZero,
4097 SanitizerKind::SO_SignedIntegerOverflow},
4098 SanitizerHandler::DivremOverflow);
4099 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4100 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4103 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4104 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4106 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4107 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4109 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4112Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4117 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4118 switch (Ops.Opcode) {
4122 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4123 llvm::Intrinsic::uadd_with_overflow;
4124 OverflowKind = SanitizerHandler::AddOverflow;
4129 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4130 llvm::Intrinsic::usub_with_overflow;
4131 OverflowKind = SanitizerHandler::SubOverflow;
4136 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4137 llvm::Intrinsic::umul_with_overflow;
4138 OverflowKind = SanitizerHandler::MulOverflow;
4141 llvm_unreachable(
"Unsupported operation for overflow detection");
4147 SanitizerDebugLocation SanScope(&CGF,
4148 {SanitizerKind::SO_SignedIntegerOverflow,
4149 SanitizerKind::SO_UnsignedIntegerOverflow},
4155 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4156 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4157 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4160 const std::string *handlerName =
4162 if (handlerName->empty()) {
4165 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4166 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4168 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4169 : SanitizerKind::SO_UnsignedIntegerOverflow;
4170 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4172 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4177 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4178 llvm::BasicBlock *continueBB =
4182 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4186 Builder.SetInsertPoint(overflowBB);
4189 llvm::Type *Int8Ty = CGF.
Int8Ty;
4190 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4191 llvm::FunctionType *handlerTy =
4192 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4193 llvm::FunctionCallee handler =
4198 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4199 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4203 llvm::Value *handlerArgs[] = {
4206 Builder.getInt8(OpID),
4209 llvm::Value *handlerResult =
4213 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4214 Builder.CreateBr(continueBB);
4216 Builder.SetInsertPoint(continueBB);
4217 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4218 phi->addIncoming(result, initialBB);
4219 phi->addIncoming(handlerResult, overflowBB);
4228 bool isSubtraction) {
4233 Value *pointer = op.LHS;
4234 Expr *pointerOperand =
expr->getLHS();
4236 Expr *indexOperand =
expr->getRHS();
4239 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4240 std::swap(pointer,
index);
4241 std::swap(pointerOperand, indexOperand);
4245 index, isSubtraction);
4251 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4255 auto &DL =
CGM.getDataLayout();
4278 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4280 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4281 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4282 PtrTy->getPointerAddressSpace()))
4285 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4286 auto CheckHandler = SanitizerHandler::PointerOverflow;
4288 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4290 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4291 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4293 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4294 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4299 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4310 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4320 llvm::Value *objectSize =
4326 return Builder.CreateBitCast(result, pointer->getType());
4331 getContext().getAsVariableArrayType(elementType)) {
4333 llvm::Value *numElements =
getVLASize(vla).NumElts;
4342 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4362 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4375 bool negMul,
bool negAdd) {
4376 Value *MulOp0 = MulOp->getOperand(0);
4377 Value *MulOp1 = MulOp->getOperand(1);
4379 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4381 Addend = Builder.CreateFNeg(Addend,
"neg");
4383 Value *FMulAdd =
nullptr;
4384 if (Builder.getIsFPConstrained()) {
4386 "Only constrained operation should be created when Builder is in FP "
4387 "constrained mode");
4388 FMulAdd = Builder.CreateConstrainedFPCall(
4389 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4391 {MulOp0, MulOp1, Addend});
4393 FMulAdd = Builder.CreateCall(
4395 {MulOp0, MulOp1, Addend});
4397 MulOp->eraseFromParent();
4412 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4413 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4414 "Only fadd/fsub can be the root of an fmuladd.");
4417 if (!op.FPFeatures.allowFPContractWithinStatement())
4420 Value *LHS = op.LHS;
4421 Value *RHS = op.RHS;
4425 bool NegLHS =
false;
4426 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4427 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4428 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4429 LHS = LHSUnOp->getOperand(0);
4434 bool NegRHS =
false;
4435 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4436 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4437 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4438 RHS = RHSUnOp->getOperand(0);
4446 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4447 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4448 (LHSBinOp->use_empty() || NegLHS)) {
4452 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4455 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4456 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4457 (RHSBinOp->use_empty() || NegRHS)) {
4461 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4465 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4466 if (LHSBinOp->getIntrinsicID() ==
4467 llvm::Intrinsic::experimental_constrained_fmul &&
4468 (LHSBinOp->use_empty() || NegLHS)) {
4472 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4475 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4476 if (RHSBinOp->getIntrinsicID() ==
4477 llvm::Intrinsic::experimental_constrained_fmul &&
4478 (RHSBinOp->use_empty() || NegRHS)) {
4482 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4489Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4490 if (op.LHS->getType()->isPointerTy() ||
4491 op.RHS->getType()->isPointerTy())
4494 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4495 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4496 case LangOptions::SOB_Defined:
4497 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4498 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4500 case LangOptions::SOB_Undefined:
4501 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4502 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4504 case LangOptions::SOB_Trapping:
4505 if (CanElideOverflowCheck(CGF.
getContext(), op))
4506 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4507 return EmitOverflowCheckedBinOp(op);
4512 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4513 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4519 if (op.Ty->isConstantMatrixType()) {
4520 llvm::MatrixBuilder MB(Builder);
4521 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4522 return MB.CreateAdd(op.LHS, op.RHS);
4525 if (op.Ty->isUnsignedIntegerType() &&
4526 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4527 !CanElideOverflowCheck(CGF.
getContext(), op))
4528 return EmitOverflowCheckedBinOp(op);
4530 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4531 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4532 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4535 if (op.isFixedPointOp())
4536 return EmitFixedPointBinOp(op);
4538 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4543Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4545 using llvm::ConstantInt;
4551 QualType ResultTy = op.Ty;
4552 QualType LHSTy, RHSTy;
4553 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4554 RHSTy = BinOp->getRHS()->getType();
4555 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4560 LHSTy = CAO->getComputationLHSType();
4561 ResultTy = CAO->getComputationResultType();
4563 LHSTy = BinOp->getLHS()->getType();
4564 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4565 LHSTy = UnOp->getSubExpr()->getType();
4566 RHSTy = UnOp->getSubExpr()->getType();
4569 Value *LHS = op.LHS;
4570 Value *RHS = op.RHS;
4575 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4579 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4580 switch (op.Opcode) {
4583 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4587 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4591 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4595 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4599 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4603 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4606 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4608 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4610 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4612 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4617 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4619 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4623 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4636 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4642 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4647Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4649 if (!op.LHS->getType()->isPointerTy()) {
4650 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4651 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4652 case LangOptions::SOB_Defined:
4653 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4654 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4656 case LangOptions::SOB_Undefined:
4657 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4658 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4660 case LangOptions::SOB_Trapping:
4661 if (CanElideOverflowCheck(CGF.
getContext(), op))
4662 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4663 return EmitOverflowCheckedBinOp(op);
4668 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4669 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4675 if (op.Ty->isConstantMatrixType()) {
4676 llvm::MatrixBuilder MB(Builder);
4677 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4678 return MB.CreateSub(op.LHS, op.RHS);
4681 if (op.Ty->isUnsignedIntegerType() &&
4682 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4683 !CanElideOverflowCheck(CGF.
getContext(), op))
4684 return EmitOverflowCheckedBinOp(op);
4686 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4687 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4688 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4691 if (op.isFixedPointOp())
4692 return EmitFixedPointBinOp(op);
4694 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4699 if (!op.RHS->getType()->isPointerTy())
4706 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4708 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4709 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4713 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4715 llvm::Value *divisor =
nullptr;
4718 if (
const VariableArrayType *vla
4721 elementType = VlaSize.Type;
4722 divisor = VlaSize.NumElts;
4726 if (!eltSize.
isOne())
4733 CharUnits elementSize;
4742 if (elementSize.
isOne())
4751 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4754Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4756 llvm::IntegerType *Ty;
4757 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4765 llvm::Type *RHSTy = RHS->
getType();
4766 llvm::APInt RHSMax =
4767 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4768 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4769 if (RHSMax.ult(Ty->getBitWidth()))
4770 return llvm::ConstantInt::get(RHSTy, RHSMax);
4771 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4775 const Twine &Name) {
4776 llvm::IntegerType *Ty;
4777 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4782 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4783 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4785 return Builder.CreateURem(
4786 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4789Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4791 if (Ops.isFixedPointOp())
4792 return EmitFixedPointBinOp(Ops);
4796 Value *RHS = Ops.RHS;
4797 if (Ops.LHS->getType() != RHS->
getType())
4798 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4800 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4801 Ops.Ty->hasSignedIntegerRepresentation() &&
4804 bool SanitizeUnsignedBase =
4805 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4806 Ops.Ty->hasUnsignedIntegerRepresentation();
4807 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4808 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4811 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4812 else if ((SanitizeBase || SanitizeExponent) &&
4814 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4815 if (SanitizeSignedBase)
4816 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4817 if (SanitizeUnsignedBase)
4818 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4819 if (SanitizeExponent)
4820 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4822 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4823 SanitizerHandler::ShiftOutOfBounds);
4824 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4825 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4826 llvm::Value *WidthMinusOne =
4827 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4828 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4830 if (SanitizeExponent) {
4832 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4839 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4842 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4843 llvm::Value *PromotedWidthMinusOne =
4844 (RHS == Ops.RHS) ? WidthMinusOne
4845 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4847 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4848 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4857 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4858 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4860 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4861 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4863 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4864 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4865 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4866 Checks.push_back(std::make_pair(
4867 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4868 : SanitizerKind::SO_UnsignedShiftBase));
4871 assert(!Checks.empty());
4872 EmitBinOpCheck(Checks, Ops);
4875 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4878Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4880 if (Ops.isFixedPointOp())
4881 return EmitFixedPointBinOp(Ops);
4885 Value *RHS = Ops.RHS;
4886 if (Ops.LHS->getType() != RHS->
getType())
4887 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4891 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4892 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4894 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4895 SanitizerHandler::ShiftOutOfBounds);
4896 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4897 llvm::Value *
Valid = Builder.CreateICmpULE(
4898 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4899 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4902 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4903 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4904 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4912 default: llvm_unreachable(
"unexpected element type");
4913 case BuiltinType::Char_U:
4914 case BuiltinType::UChar:
4915 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4916 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4917 case BuiltinType::Char_S:
4918 case BuiltinType::SChar:
4919 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4920 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4921 case BuiltinType::UShort:
4922 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4923 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4924 case BuiltinType::Short:
4925 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4926 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4927 case BuiltinType::UInt:
4928 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4929 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4930 case BuiltinType::Int:
4931 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4932 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4933 case BuiltinType::ULong:
4934 case BuiltinType::ULongLong:
4935 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4936 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4937 case BuiltinType::Long:
4938 case BuiltinType::LongLong:
4939 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4940 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4941 case BuiltinType::Float:
4942 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4943 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4944 case BuiltinType::Double:
4945 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4946 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4947 case BuiltinType::UInt128:
4948 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4949 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4950 case BuiltinType::Int128:
4951 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4952 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4956Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
4957 llvm::CmpInst::Predicate UICmpOpc,
4958 llvm::CmpInst::Predicate SICmpOpc,
4959 llvm::CmpInst::Predicate FCmpOpc,
4961 TestAndClearIgnoreResultAssign();
4965 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
4971 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4973 BinOpInfo BOInfo = EmitBinOps(E);
4974 Value *LHS = BOInfo.LHS;
4975 Value *RHS = BOInfo.RHS;
4981 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4983 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4986 Value *FirstVecArg = LHS,
4987 *SecondVecArg = RHS;
4989 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
4993 default: llvm_unreachable(
"is not a comparison operation");
5005 std::swap(FirstVecArg, SecondVecArg);
5012 if (ElementKind == BuiltinType::Float) {
5014 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5015 std::swap(FirstVecArg, SecondVecArg);
5023 if (ElementKind == BuiltinType::Float) {
5025 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5030 std::swap(FirstVecArg, SecondVecArg);
5035 Value *CR6Param = Builder.getInt32(CR6);
5037 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5045 if (ResultTy->getBitWidth() > 1 &&
5047 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5052 if (BOInfo.isFixedPointOp()) {
5053 Result = EmitFixedPointBinOp(BOInfo);
5054 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5055 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5057 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5059 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5061 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5076 LHS = Builder.CreateStripInvariantGroup(LHS);
5078 RHS = Builder.CreateStripInvariantGroup(RHS);
5081 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5087 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5093 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5095 CETy = CTy->getElementType();
5097 LHS.first = Visit(E->
getLHS());
5098 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5101 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5104 CTy->getElementType()) &&
5105 "The element types must always match.");
5108 RHS.first = Visit(E->
getRHS());
5109 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5111 "The element types must always match.");
5114 Value *ResultR, *ResultI;
5118 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5119 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5123 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5124 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5128 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5131 "Complex comparison other than == or != ?");
5132 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5144 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5145 CastKind Kind = ICE->getCastKind();
5146 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5147 *SrcType = ICE->getSubExpr()->getType();
5160 bool Ignore = TestAndClearIgnoreResultAssign();
5194 RHS = Visit(E->
getRHS());
5210 RHS = Visit(E->
getRHS());
5250 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5253Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5261 if (LHS->
getType()->isFPOrFPVectorTy()) {
5262 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5264 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5265 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5267 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5268 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5270 Value *
And = Builder.CreateAnd(LHS, RHS);
5271 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5275 llvm::Type *ResTy = ConvertType(E->
getType());
5296 if (InstrumentRegions &&
5301 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5315 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5321 return llvm::Constant::getNullValue(ResTy);
5334 CodeGenFunction::ConditionalEvaluation eval(CGF);
5343 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5345 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5347 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5356 RHSBlock = Builder.GetInsertBlock();
5361 if (InstrumentRegions &&
5365 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5369 PN->addIncoming(RHSCond, RHSBlockCnt);
5379 PN->addIncoming(RHSCond, RHSBlock);
5389 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5393 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5396Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5404 if (LHS->
getType()->isFPOrFPVectorTy()) {
5405 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5407 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5408 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5410 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5411 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5413 Value *
Or = Builder.CreateOr(LHS, RHS);
5414 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5418 llvm::Type *ResTy = ConvertType(E->
getType());
5439 if (InstrumentRegions &&
5444 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5458 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5464 return llvm::ConstantInt::get(ResTy, 1);
5477 CodeGenFunction::ConditionalEvaluation eval(CGF);
5487 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5489 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5491 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5503 RHSBlock = Builder.GetInsertBlock();
5508 if (InstrumentRegions &&
5512 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5516 PN->addIncoming(RHSCond, RHSBlockCnt);
5522 PN->addIncoming(RHSCond, RHSBlock);
5530 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5533Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5536 return Visit(E->
getRHS());
5561Value *ScalarExprEmitter::
5562VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5563 TestAndClearIgnoreResultAssign();
5566 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5568 Expr *condExpr = E->
getCond();
5576 Expr *live = lhsExpr, *dead = rhsExpr;
5577 if (!CondExprBool) std::swap(live, dead);
5608 llvm::Value *LHS = Visit(lhsExpr);
5609 llvm::Value *RHS = Visit(rhsExpr);
5611 llvm::Type *condType = ConvertType(condExpr->
getType());
5614 unsigned numElem = vecTy->getNumElements();
5615 llvm::Type *elemType = vecTy->getElementType();
5617 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5618 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5619 llvm::Value *tmp = Builder.CreateSExt(
5620 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5621 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5624 llvm::Value *RHSTmp = RHS;
5625 llvm::Value *LHSTmp = LHS;
5626 bool wasCast =
false;
5628 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5629 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5630 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5634 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5635 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5636 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5638 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5648 llvm::Value *LHS = Visit(lhsExpr);
5649 llvm::Value *RHS = Visit(rhsExpr);
5651 llvm::Type *CondType = ConvertType(condExpr->
getType());
5654 if (VecTy->getElementType()->isIntegerTy(1))
5655 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5658 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5660 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5662 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5663 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5672 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5681 llvm::Value *LHS = Visit(lhsExpr);
5682 llvm::Value *RHS = Visit(rhsExpr);
5685 assert(!RHS &&
"LHS and RHS types must match");
5688 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5699 CodeGenFunction::ConditionalEvaluation eval(CGF);
5717 Value *LHS = Visit(lhsExpr);
5720 LHSBlock = Builder.GetInsertBlock();
5721 Builder.CreateBr(ContBlock);
5735 Value *RHS = Visit(rhsExpr);
5738 RHSBlock = Builder.GetInsertBlock();
5748 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5749 PN->addIncoming(LHS, LHSBlock);
5750 PN->addIncoming(RHS, RHSBlock);
5760Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5764Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5766 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5771Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5777 Value *Src,
unsigned NumElementsDst) {
5778 static constexpr int Mask[] = {0, 1, 2, -1};
5779 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5799 const llvm::DataLayout &DL,
5800 Value *Src, llvm::Type *DstTy,
5801 StringRef Name =
"") {
5805 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5806 return Builder.CreateBitCast(Src, DstTy, Name);
5809 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5810 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5813 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5815 if (!DstTy->isIntegerTy())
5816 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5818 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5822 if (!SrcTy->isIntegerTy())
5823 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5825 return Builder.CreateIntToPtr(Src, DstTy, Name);
5828Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5830 llvm::Type *DstTy = ConvertType(E->
getType());
5832 llvm::Type *SrcTy = Src->
getType();
5833 unsigned NumElementsSrc =
5837 unsigned NumElementsDst =
5848 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5853 Src->setName(
"astype");
5860 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5861 auto *Vec4Ty = llvm::FixedVectorType::get(
5867 Src->setName(
"astype");
5872 Src, DstTy,
"astype");
5875Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5887 "Invalid scalar expression to emit");
5889 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5890 .Visit(
const_cast<Expr *
>(E));
5899 "Invalid scalar expression to emit");
5900 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5910 "Invalid complex -> scalar conversion");
5911 return ScalarExprEmitter(*
this)
5912 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5919 if (!PromotionType.
isNull())
5920 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5922 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5928 bool isInc,
bool isPre) {
5929 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5939 llvm::Type *BaseTy =
5955 ScalarExprEmitter Scalar(*
this);
5958#define COMPOUND_OP(Op) \
5959 case BO_##Op##Assign: \
5960 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5997 llvm_unreachable(
"Not valid compound assignment operators");
6000 llvm_unreachable(
"Unhandled compound assignment operator");
6015 llvm::LLVMContext &VMContext,
6021 llvm::Value *TotalOffset =
nullptr;
6027 Value *BasePtr_int =
6028 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6030 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6031 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6032 return {TotalOffset, Builder.getFalse()};
6036 assert(GEP->getPointerOperand() == BasePtr &&
6037 "BasePtr must be the base of the GEP.");
6038 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6040 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6043 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6044 auto *SAddIntrinsic =
6045 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6046 auto *SMulIntrinsic =
6047 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6050 llvm::Value *OffsetOverflows = Builder.getFalse();
6054 llvm::Value *RHS) -> llvm::Value * {
6055 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6058 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6059 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6061 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6064 OffsetOverflows = Builder.getTrue();
6065 return llvm::ConstantInt::get(VMContext, N);
6070 auto *ResultAndOverflow = Builder.CreateCall(
6071 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6072 OffsetOverflows = Builder.CreateOr(
6073 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6074 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6078 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6079 GTI != GTE; ++GTI) {
6080 llvm::Value *LocalOffset;
6081 auto *Index = GTI.getOperand();
6083 if (
auto *STy = GTI.getStructTypeOrNull()) {
6087 LocalOffset = llvm::ConstantInt::get(
6088 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6093 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6094 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6095 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6100 if (!TotalOffset || TotalOffset ==
Zero)
6101 TotalOffset = LocalOffset;
6103 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6106 return {TotalOffset, OffsetOverflows};
6111 ArrayRef<Value *> IdxList,
6112 bool SignedIndices,
bool IsSubtraction,
6113 SourceLocation Loc,
const Twine &Name) {
6114 llvm::Type *PtrTy = Ptr->
getType();
6116 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6117 if (!SignedIndices && !IsSubtraction)
6118 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6120 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6123 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6127 bool PerformNullCheck = !NullPointerIsDefined(
6128 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6131 bool PerformOverflowCheck =
6134 if (!(PerformNullCheck || PerformOverflowCheck))
6137 const auto &DL = CGM.getDataLayout();
6139 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6140 auto CheckHandler = SanitizerHandler::PointerOverflow;
6141 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6142 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6144 GEPOffsetAndOverflow EvaluatedGEP =
6149 "If the offset got constant-folded, we don't expect that there was an "
6152 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6160 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6161 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6163 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6167 if (PerformNullCheck) {
6175 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6176 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6177 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6178 Checks.emplace_back(
Valid, CheckOrdinal);
6181 if (PerformOverflowCheck) {
6186 llvm::Value *ValidGEP;
6187 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6188 if (SignedIndices) {
6194 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6195 auto *PosOrZeroOffset =
6197 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6199 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6200 }
else if (!IsSubtraction) {
6205 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6211 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6213 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6214 Checks.emplace_back(ValidGEP, CheckOrdinal);
6217 assert(!Checks.empty() &&
"Should have produced some checks.");
6219 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6221 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6222 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6228 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6229 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6230 const Twine &Name) {
6231 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6232 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6233 if (!SignedIndices && !IsSubtraction)
6234 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6236 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6240 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6241 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6242 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc, bool isPre, ASTContext &Ctx)
For the purposes of overflow pattern exclusion, does this match the "while(i--)" pattern?
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
ParentMapContext & getParentMapContext()
Returns the dynamic AST node parent map context.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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 FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void 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
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
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.