35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
196static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
198 "Expected a unary or binary operator");
202 if (!Op.mayHaveIntegerOverflow())
205 if (Op.Ty->isSignedIntegerType() &&
211 if (Op.Ty->isUnsignedIntegerType() &&
232 if (BO->hasExcludedOverflowPattern())
248 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
254 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
255 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
259class ScalarExprEmitter
261 CodeGenFunction &CGF;
262 CGBuilderTy &Builder;
263 bool IgnoreResultAssign;
264 llvm::LLVMContext &VMContext;
267 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
268 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
269 VMContext(cgf.getLLVMContext()) {
276 bool TestAndClearIgnoreResultAssign() {
277 bool I = IgnoreResultAssign;
278 IgnoreResultAssign =
false;
282 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
283 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
289 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
290 const BinOpInfo &Info);
292 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
296 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
297 const AlignValueAttr *AVAttr =
nullptr;
298 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
299 const ValueDecl *VD = DRE->getDecl();
302 if (
const auto *TTy =
304 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
314 AVAttr = VD->
getAttr<AlignValueAttr>();
319 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
320 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
333 Value *EmitLoadOfLValue(
const Expr *E) {
337 EmitLValueAlignmentAssumption(E,
V);
343 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
347 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
348 Value *Src, QualType SrcType, QualType DstType,
349 llvm::Type *DstTy, SourceLocation Loc);
354 enum ImplicitConversionCheckKind :
unsigned char {
355 ICCK_IntegerTruncation = 0,
356 ICCK_UnsignedIntegerTruncation = 1,
357 ICCK_SignedIntegerTruncation = 2,
358 ICCK_IntegerSignChange = 3,
359 ICCK_SignedIntegerTruncationOrSignChange = 4,
364 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
365 QualType DstType, SourceLocation Loc);
370 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
371 QualType DstType, SourceLocation Loc);
375 struct ScalarConversionOpts {
376 bool TreatBooleanAsSigned;
377 bool EmitImplicitIntegerTruncationChecks;
378 bool EmitImplicitIntegerSignChangeChecks;
380 ScalarConversionOpts()
381 : TreatBooleanAsSigned(
false),
382 EmitImplicitIntegerTruncationChecks(
false),
383 EmitImplicitIntegerSignChangeChecks(
false) {}
385 ScalarConversionOpts(clang::SanitizerSet SanOpts)
386 : TreatBooleanAsSigned(
false),
387 EmitImplicitIntegerTruncationChecks(
388 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
389 EmitImplicitIntegerSignChangeChecks(
390 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
392 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
393 llvm::Type *SrcTy, llvm::Type *DstTy,
394 ScalarConversionOpts Opts);
396 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
398 ScalarConversionOpts Opts = ScalarConversionOpts());
402 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
408 QualType SrcTy, QualType DstTy,
412 Value *EmitNullValue(QualType Ty);
417 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
418 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
422 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
425 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
432 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
433 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
439 ZI->eraseFromParent();
444 return Builder.CreateIsNotNull(
V,
"tobool");
451 Value *Visit(Expr *E) {
452 ApplyDebugLocation DL(CGF, E);
453 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
456 Value *VisitStmt(Stmt *S) {
458 llvm_unreachable(
"Stmt can't have complex result type!");
460 Value *VisitExpr(Expr *S);
462 Value *VisitConstantExpr(ConstantExpr *E) {
468 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
483 Value *VisitParenExpr(ParenExpr *PE) {
486 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
489 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
490 return Visit(
GE->getResultExpr());
492 Value *VisitCoawaitExpr(CoawaitExpr *S) {
495 Value *VisitCoyieldExpr(CoyieldExpr *S) {
498 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
503 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
504 return Builder.getInt(E->
getValue());
506 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
507 return Builder.getInt(E->
getValue());
509 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
510 return llvm::ConstantFP::get(VMContext, E->
getValue());
512 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
515 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
518 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
519 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
521 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
522 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
524 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
528 return EmitNullValue(E->
getType());
530 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
531 return EmitNullValue(E->
getType());
533 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
534 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
535 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
537 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
540 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
544 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
548 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
549 Value *VisitEmbedExpr(EmbedExpr *E);
551 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
560 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
561 llvm_unreachable(
"Codegen for this isn't defined/implemented");
565 Value *VisitDeclRefExpr(DeclRefExpr *E) {
568 return EmitLoadOfLValue(E);
571 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
574 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
577 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
578 return EmitLoadOfLValue(E);
580 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
583 return EmitLoadOfLValue(E);
587 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
593 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
599 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
604 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
605 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
606 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
607 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
608 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
609 Value *VisitMemberExpr(MemberExpr *E);
610 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
611 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
617 return EmitLoadOfLValue(E);
620 Value *VisitInitListExpr(InitListExpr *E);
622 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
624 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
628 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
629 return EmitNullValue(E->
getType());
631 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
633 return VisitCastExpr(E);
637 Value *VisitCallExpr(
const CallExpr *E) {
639 return EmitLoadOfLValue(E);
643 EmitLValueAlignmentAssumption(E,
V);
647 Value *VisitStmtExpr(
const StmtExpr *E);
650 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
652 return EmitScalarPrePostIncDec(E, LV,
false,
false);
654 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
656 return EmitScalarPrePostIncDec(E, LV,
true,
false);
658 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
660 return EmitScalarPrePostIncDec(E, LV,
false,
true);
662 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
664 return EmitScalarPrePostIncDec(E, LV,
true,
true);
667 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
671 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
672 bool isInc,
bool isPre);
675 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
679 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
681 Value *VisitUnaryDeref(
const UnaryOperator *E) {
684 return EmitLoadOfLValue(E);
687 Value *VisitUnaryPlus(
const UnaryOperator *E,
688 QualType PromotionType = QualType());
689 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
690 Value *VisitUnaryMinus(
const UnaryOperator *E,
691 QualType PromotionType = QualType());
692 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
694 Value *VisitUnaryNot (
const UnaryOperator *E);
695 Value *VisitUnaryLNot (
const UnaryOperator *E);
696 Value *VisitUnaryReal(
const UnaryOperator *E,
697 QualType PromotionType = QualType());
698 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
699 Value *VisitUnaryImag(
const UnaryOperator *E,
700 QualType PromotionType = QualType());
701 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
702 Value *VisitUnaryExtension(
const UnaryOperator *E) {
707 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
708 return EmitLoadOfLValue(E);
710 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
718 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
719 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
722 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
723 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
726 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
730 Value *VisitExprWithCleanups(ExprWithCleanups *E);
731 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
734 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
739 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
741 return llvm::ConstantInt::get(ConvertType(E->
getType()),
744 return llvm::ConstantInt::get(ConvertType(E->
getType()),
748 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
756 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
757 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
760 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
761 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
764 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
774 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
775 return EmitNullValue(E->
getType());
778 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
783 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
784 return Builder.getInt1(E->
getValue());
788 Value *EmitMul(
const BinOpInfo &Ops) {
789 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
790 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
791 case LangOptions::SOB_Defined:
792 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
793 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
795 case LangOptions::SOB_Undefined:
796 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
797 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
799 case LangOptions::SOB_Trapping:
800 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
801 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
802 return EmitOverflowCheckedBinOp(Ops);
806 if (Ops.Ty->isConstantMatrixType()) {
807 llvm::MatrixBuilder MB(Builder);
811 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
812 BO->getLHS()->getType().getCanonicalType());
813 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
814 BO->getRHS()->getType().getCanonicalType());
815 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
816 if (LHSMatTy && RHSMatTy)
817 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
818 LHSMatTy->getNumColumns(),
819 RHSMatTy->getNumColumns());
820 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
823 if (Ops.Ty->isUnsignedIntegerType() &&
824 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
825 !CanElideOverflowCheck(CGF.
getContext(), Ops))
826 return EmitOverflowCheckedBinOp(Ops);
828 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
830 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
831 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
833 if (Ops.isFixedPointOp())
834 return EmitFixedPointBinOp(Ops);
835 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
839 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
842 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
843 llvm::Value *
Zero,
bool isDiv);
845 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
851 Value *EmitDiv(
const BinOpInfo &Ops);
852 Value *EmitRem(
const BinOpInfo &Ops);
853 Value *EmitAdd(
const BinOpInfo &Ops);
854 Value *EmitSub(
const BinOpInfo &Ops);
855 Value *EmitShl(
const BinOpInfo &Ops);
856 Value *EmitShr(
const BinOpInfo &Ops);
857 Value *EmitAnd(
const BinOpInfo &Ops) {
858 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
860 Value *EmitXor(
const BinOpInfo &Ops) {
861 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
863 Value *EmitOr (
const BinOpInfo &Ops) {
864 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
868 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
870 BinOpInfo EmitBinOps(
const BinaryOperator *E,
871 QualType PromotionTy = QualType());
873 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
874 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
875 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
877 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
878 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
881 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
882 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
884 QualType getPromotionType(QualType Ty) {
886 if (
auto *CT = Ty->
getAs<ComplexType>()) {
887 QualType ElementType = CT->getElementType();
893 if (
auto *VT = Ty->
getAs<VectorType>()) {
894 unsigned NumElements = VT->getNumElements();
904#define HANDLEBINOP(OP) \
905 Value *VisitBin##OP(const BinaryOperator *E) { \
906 QualType promotionTy = getPromotionType(E->getType()); \
907 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
908 if (result && !promotionTy.isNull()) \
909 result = EmitUnPromotedValue(result, E->getType()); \
912 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
913 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
914 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
930 llvm::CmpInst::Predicate SICmpOpc,
931 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
932#define VISITCOMP(CODE, UI, SI, FP, SIG) \
933 Value *VisitBin##CODE(const BinaryOperator *E) { \
934 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
935 llvm::FCmpInst::FP, SIG); }
936 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
950 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
951 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
953 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
958 Value *VisitBlockExpr(
const BlockExpr *BE);
959 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
960 Value *VisitChooseExpr(ChooseExpr *CE);
961 Value *VisitVAArgExpr(VAArgExpr *VE);
962 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
965 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
968 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
971 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
974 Value *VisitAsTypeExpr(AsTypeExpr *CE);
975 Value *VisitAtomicExpr(AtomicExpr *AE);
976 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
989 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
992 return EmitFloatToBoolConversion(Src);
994 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
998 "Unknown scalar type to convert");
1001 return EmitIntToBoolConversion(Src);
1004 return EmitPointerToBoolConversion(Src, SrcType);
1007void ScalarExprEmitter::EmitFloatConversionCheck(
1008 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1009 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1010 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1014 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1015 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1016 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1017 using llvm::APFloat;
1020 llvm::Value *Check =
nullptr;
1021 const llvm::fltSemantics &SrcSema =
1031 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1032 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1033 APFloat::opOverflow)
1036 MinSrc = APFloat::getInf(SrcSema,
true);
1040 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1043 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1044 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1045 APFloat::opOverflow)
1048 MaxSrc = APFloat::getInf(SrcSema,
false);
1052 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1057 const llvm::fltSemantics &Sema =
1060 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1061 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1065 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1067 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1068 Check = Builder.CreateAnd(GE, LE);
1073 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1079static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1080 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1083 llvm::Type *SrcTy = Src->
getType();
1084 llvm::Type *DstTy = Dst->
getType();
1089 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1091 "non-integer llvm type");
1098 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1100 if (!SrcSigned && !DstSigned) {
1101 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1102 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1104 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1105 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1108 llvm::Value *Check =
nullptr;
1110 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1112 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1114 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1122void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1123 Value *Dst, QualType DstType,
1124 SourceLocation Loc) {
1134 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1135 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1137 if (SrcBits <= DstBits)
1140 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1147 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1148 (!SrcSigned && DstSigned))
1151 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1152 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1155 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1160 SanitizerDebugLocation SanScope(
1162 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1163 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1174 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1181 llvm::Constant *StaticArgs[] = {
1184 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1185 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1187 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1194 llvm::Type *VTy =
V->getType();
1197 return llvm::ConstantInt::getFalse(VTy->getContext());
1199 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1200 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1201 llvm::Twine(Name) +
"." +
V->getName() +
1202 ".negativitycheck");
1207static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1208 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1211 llvm::Type *SrcTy = Src->
getType();
1212 llvm::Type *DstTy = Dst->
getType();
1215 "non-integer llvm type");
1221 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1222 unsigned DstBits = DstTy->getScalarSizeInBits();
1226 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1227 "either the widths should be different, or the signednesses.");
1230 llvm::Value *SrcIsNegative =
1233 llvm::Value *DstIsNegative =
1239 llvm::Value *Check =
nullptr;
1240 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1242 return std::make_pair(
1243 ScalarExprEmitter::ICCK_IntegerSignChange,
1244 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1247void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1248 Value *Dst, QualType DstType,
1249 SourceLocation Loc) {
1250 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1253 llvm::Type *SrcTy = Src->
getType();
1254 llvm::Type *DstTy = Dst->
getType();
1264 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1265 unsigned DstBits = DstTy->getScalarSizeInBits();
1272 if (SrcSigned == DstSigned && SrcBits == DstBits)
1276 if (!SrcSigned && !DstSigned)
1281 if ((DstBits > SrcBits) && DstSigned)
1283 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1284 (SrcBits > DstBits) && SrcSigned) {
1293 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1297 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1301 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1302 SanitizerDebugLocation SanScope(
1304 {SanitizerKind::SO_ImplicitIntegerSignChange,
1305 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1306 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1309 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1310 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1314 ImplicitConversionCheckKind CheckKind;
1315 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1322 CheckKind = Check.first;
1323 Checks.emplace_back(Check.second);
1325 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1326 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1332 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1333 Checks.emplace_back(Check.second);
1337 llvm::Constant *StaticArgs[] = {
1340 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1341 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1343 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1348static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1349 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1355 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1356 if (!SrcSigned && !DstSigned)
1357 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1359 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1361 llvm::Value *Check =
nullptr;
1363 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1365 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1368 return std::make_pair(
1370 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1375static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1376 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1380 llvm::Value *SrcIsNegative =
1383 llvm::Value *DstIsNegative =
1389 llvm::Value *Check =
nullptr;
1391 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1393 return std::make_pair(
1394 ScalarExprEmitter::ICCK_IntegerSignChange,
1395 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1403 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1421 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1422 unsigned DstBits = Info.
Size;
1427 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1429 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1431 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1432 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1436 bool EmitTruncation = DstBits < SrcBits;
1440 bool EmitTruncationFromUnsignedToSigned =
1441 EmitTruncation && DstSigned && !SrcSigned;
1443 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1444 bool BothUnsigned = !SrcSigned && !DstSigned;
1445 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1452 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1457 else if (EmitSignChange) {
1458 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1459 "either the widths should be different, or the signednesses.");
1465 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1466 if (EmitTruncationFromUnsignedToSigned)
1467 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1469 llvm::Constant *StaticArgs[] = {
1472 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1473 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1475 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1479 QualType DstType, llvm::Type *SrcTy,
1481 ScalarConversionOpts Opts) {
1483 llvm::Type *SrcElementTy;
1484 llvm::Type *DstElementTy;
1494 "cannot cast between matrix and non-matrix types");
1495 SrcElementTy = SrcTy;
1496 DstElementTy = DstTy;
1497 SrcElementType = SrcType;
1498 DstElementType = DstType;
1503 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1508 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1510 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1511 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1515 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1522 llvm::Intrinsic::ID IID =
1523 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1524 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1528 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1529 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1532 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1533 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1534 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1536 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1537 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1538 return Builder.CreateFPExt(Src, DstTy,
"conv");
1543Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1546 ScalarConversionOpts Opts) {
1561 return Builder.CreateIsNotNull(Src,
"tobool");
1564 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1567 "Unhandled scalar conversion from a fixed point type to another type.");
1571 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1574 "Unhandled scalar conversion to a fixed point type from another type.");
1577 QualType NoncanonicalSrcType = SrcType;
1578 QualType NoncanonicalDstType = DstType;
1582 if (SrcType == DstType)
return Src;
1586 llvm::Value *OrigSrc = Src;
1587 QualType OrigSrcType = SrcType;
1588 llvm::Type *SrcTy = Src->
getType();
1592 return EmitConversionToBool(Src, SrcType);
1594 llvm::Type *DstTy = ConvertType(DstType);
1599 if (DstTy->isFloatingPointTy()) {
1601 return Builder.CreateCall(
1609 Src = Builder.CreateCall(
1614 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1622 if (SrcTy == DstTy) {
1623 if (Opts.EmitImplicitIntegerSignChangeChecks)
1624 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1625 NoncanonicalDstType, Loc);
1633 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1638 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1643 llvm::Value* IntResult =
1644 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1646 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1652 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1659 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1661 "Splatted expr doesn't match with vector element type?");
1665 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1669 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1673 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1674 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1675 if (SrcSize == DstSize)
1676 return Builder.CreateBitCast(Src, DstTy,
"conv");
1689 assert(((SrcElementTy->isIntegerTy() &&
1690 DstElementTy->isIntegerTy()) ||
1691 (SrcElementTy->isFloatingPointTy() &&
1692 DstElementTy->isFloatingPointTy())) &&
1693 "unexpected conversion between a floating-point vector and an "
1697 if (SrcElementTy->isIntegerTy())
1698 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1701 if (SrcSize > DstSize)
1702 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1705 return Builder.CreateFPExt(Src, DstTy,
"conv");
1709 Value *Res =
nullptr;
1710 llvm::Type *ResTy = DstTy;
1717 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1719 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1725 if (SrcTy->isFloatingPointTy()) {
1729 return Builder.CreateCall(
1732 return Builder.CreateFPTrunc(Src, DstTy);
1737 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1739 if (DstTy != ResTy) {
1741 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1742 Res = Builder.CreateCall(
1746 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1750 if (Opts.EmitImplicitIntegerTruncationChecks)
1751 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1752 NoncanonicalDstType, Loc);
1754 if (Opts.EmitImplicitIntegerSignChangeChecks)
1755 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1756 NoncanonicalDstType, Loc);
1761Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1763 SourceLocation Loc) {
1764 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1767 Result = FPBuilder.CreateFloatingToFixed(Src,
1770 Result = FPBuilder.CreateFixedToFloating(Src,
1772 ConvertType(DstTy));
1778 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1779 DstFPSema.getWidth(),
1780 DstFPSema.isSigned());
1782 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1785 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1792Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1794 SourceLocation Loc) {
1796 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1801 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1802 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1803 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1810 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1813Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1821void ScalarExprEmitter::EmitBinOpCheck(
1822 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1823 const BinOpInfo &Info) {
1826 SmallVector<llvm::Constant *, 4> StaticData;
1827 SmallVector<llvm::Value *, 2> DynamicData;
1835 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1836 if (UO && UO->
getOpcode() == UO_Minus) {
1837 Check = SanitizerHandler::NegateOverflow;
1839 DynamicData.push_back(Info.RHS);
1843 Check = SanitizerHandler::ShiftOutOfBounds;
1845 StaticData.push_back(
1847 StaticData.push_back(
1849 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1851 Check = SanitizerHandler::DivremOverflow;
1855 int ArithOverflowKind = 0;
1858 Check = SanitizerHandler::AddOverflow;
1859 ArithOverflowKind = diag::UBSanArithKind::Add;
1863 Check = SanitizerHandler::SubOverflow;
1864 ArithOverflowKind = diag::UBSanArithKind::Sub;
1868 Check = SanitizerHandler::MulOverflow;
1869 ArithOverflowKind = diag::UBSanArithKind::Mul;
1873 llvm_unreachable(
"unexpected opcode for bin op check");
1877 SanitizerKind::UnsignedIntegerOverflow) ||
1879 SanitizerKind::SignedIntegerOverflow)) {
1883 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1887 DynamicData.push_back(Info.LHS);
1888 DynamicData.push_back(Info.RHS);
1891 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1898Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1906ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1908 unsigned AddrSpace =
1910 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1913 llvm::Type *ExprTy = ConvertType(E->
getType());
1914 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1918Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1920 auto It = E->
begin();
1921 return Builder.getInt((*It)->getValue());
1924Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1932 unsigned LHSElts = LTy->getNumElements();
1940 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1941 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1949 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1950 MTy->getNumElements());
1951 Value* NewV = llvm::PoisonValue::get(RTy);
1952 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1953 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1954 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1956 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1957 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1965 SmallVector<int, 32> Indices;
1969 if (Idx.isSigned() && Idx.isAllOnes())
1970 Indices.push_back(-1);
1972 Indices.push_back(Idx.getZExtValue());
1975 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1978Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1986 if (SrcType == DstType)
return Src;
1989 "ConvertVector source type must be a vector");
1991 "ConvertVector destination type must be a vector");
1993 llvm::Type *SrcTy = Src->
getType();
1994 llvm::Type *DstTy = ConvertType(DstType);
2000 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2001 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2003 assert(SrcTy->isVectorTy() &&
2004 "ConvertVector source IR type must be a vector");
2005 assert(DstTy->isVectorTy() &&
2006 "ConvertVector destination IR type must be a vector");
2011 if (DstEltType->isBooleanType()) {
2012 assert((SrcEltTy->isFloatingPointTy() ||
2015 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2016 if (SrcEltTy->isFloatingPointTy()) {
2017 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2018 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2020 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2025 Value *Res =
nullptr;
2030 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2032 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2034 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2036 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2039 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2040 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2041 if (DstEltType->isSignedIntegerOrEnumerationType())
2042 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2044 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2046 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2047 "Unknown real conversion");
2048 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2049 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2050 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2052 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2058Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2067 return Builder.getInt(
Value);
2071 llvm::Value *
Result = EmitLoadOfLValue(E);
2077 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2078 if (llvm::GetElementPtrInst *GEP =
2079 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2080 if (llvm::Instruction *
Pointer =
2081 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2093Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2094 TestAndClearIgnoreResultAssign();
2102 return EmitLoadOfLValue(E);
2110 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2113 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2116Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2117 MatrixSingleSubscriptExpr *E) {
2118 TestAndClearIgnoreResultAssign();
2121 unsigned NumRows = MatrixTy->getNumRows();
2122 unsigned NumColumns = MatrixTy->getNumColumns();
2126 llvm::MatrixBuilder MB(Builder);
2130 MB.CreateIndexAssumption(RowIdx, NumRows);
2133 llvm::Type *ElemTy = CGF.
ConvertType(MatrixTy->getElementType());
2134 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2135 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2137 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2138 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2139 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows,
"matrix_row_idx");
2141 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2142 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2143 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2149Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2150 TestAndClearIgnoreResultAssign();
2158 unsigned NumRows = MatrixTy->getNumRows();
2159 llvm::MatrixBuilder MB(Builder);
2160 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2162 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2167 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2172 int MV = SVI->getMaskValue(Idx);
2179 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2180 "Index operand too large for shufflevector mask!");
2181 return C->getZExtValue();
2184Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2185 bool Ignore = TestAndClearIgnoreResultAssign();
2188 assert((Ignore ==
false ||
2190 "init list ignored");
2207 llvm::VectorType *VType =
2208 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2211 if (NumInitElements == 0) {
2213 return EmitNullValue(E->
getType());
2220 if (NumInitElements == 0) {
2222 return EmitNullValue(E->
getType());
2225 if (NumInitElements == 1) {
2226 Expr *InitVector = E->
getInit(0);
2231 return Visit(InitVector);
2234 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2244 unsigned CurIdx = 0;
2245 bool VIsPoisonShuffle =
false;
2246 llvm::Value *
V = llvm::PoisonValue::get(VType);
2247 for (
unsigned i = 0; i != NumInitElements; ++i) {
2250 SmallVector<int, 16> Args;
2252 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2262 ->getNumElements() == ResElts) {
2264 Value *LHS =
nullptr, *RHS =
nullptr;
2269 Args.resize(ResElts, -1);
2271 LHS = EI->getVectorOperand();
2273 VIsPoisonShuffle =
true;
2274 }
else if (VIsPoisonShuffle) {
2277 for (
unsigned j = 0; j != CurIdx; ++j)
2279 Args.push_back(ResElts +
C->getZExtValue());
2280 Args.resize(ResElts, -1);
2283 RHS = EI->getVectorOperand();
2284 VIsPoisonShuffle =
false;
2286 if (!Args.empty()) {
2287 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2293 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2295 VIsPoisonShuffle =
false;
2305 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2308 Value *SVOp = SVI->getOperand(0);
2311 if (OpTy->getNumElements() == ResElts) {
2312 for (
unsigned j = 0; j != CurIdx; ++j) {
2315 if (VIsPoisonShuffle) {
2321 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2323 Args.resize(ResElts, -1);
2325 if (VIsPoisonShuffle)
2335 for (
unsigned j = 0; j != InitElts; ++j)
2337 Args.resize(ResElts, -1);
2338 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2341 for (
unsigned j = 0; j != CurIdx; ++j)
2343 for (
unsigned j = 0; j != InitElts; ++j)
2344 Args.push_back(j + Offset);
2345 Args.resize(ResElts, -1);
2352 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2359 llvm::Type *EltTy = VType->getElementType();
2362 for (; CurIdx < ResElts; ++CurIdx) {
2363 Value *Idx = Builder.getInt32(CurIdx);
2364 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2365 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2377 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2381 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2384 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2403 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2407 if (
const auto *CE = dyn_cast<CastExpr>(E))
2408 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2409 CE->getCastKind() == CK_ArrayToPointerDecay)
2420 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2430 if (ICE->isGLValue())
2445 assert(LoadList.size() >= VecTy->getNumElements() &&
2446 "Flattened type on RHS must have the same number or more elements "
2447 "than vector on LHS.");
2451 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2454 "All flattened source values should be scalars.");
2457 VecTy->getElementType(), Loc);
2458 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2463 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2464 "Flattened type on RHS must have the same number or more elements "
2465 "than vector on LHS.");
2470 for (
unsigned I = 0, E = MatTy->getNumElementsFlattened(); I < E; I++) {
2471 unsigned ColMajorIndex =
2472 (I % MatTy->getNumRows()) * MatTy->getNumColumns() +
2473 (I / MatTy->getNumRows());
2476 "All flattened source values should be scalars.");
2478 RVal.
getScalarVal(), LoadList[ColMajorIndex].getType(),
2479 MatTy->getElementType(), Loc);
2480 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2486 "Destination type must be a vector, matrix, or builtin type.");
2488 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2497 auto RestoreCurCast =
2498 llvm::make_scope_exit([
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2502 QualType DestTy = CE->
getType();
2504 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2508 bool Ignored = TestAndClearIgnoreResultAssign();
2514 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2515 case CK_BuiltinFnToFnPtr:
2516 llvm_unreachable(
"builtin functions are handled elsewhere");
2518 case CK_LValueBitCast:
2519 case CK_ObjCObjectLValueCast: {
2520 Address
Addr = EmitLValue(E).getAddress();
2523 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2526 case CK_LValueToRValueBitCast: {
2532 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2535 case CK_CPointerToObjCPointerCast:
2536 case CK_BlockPointerToObjCPointerCast:
2537 case CK_AnyPointerToBlockPointerCast:
2539 Value *Src = Visit(E);
2540 llvm::Type *SrcTy = Src->
getType();
2541 llvm::Type *DstTy = ConvertType(DestTy);
2552 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2557 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2558 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2559 "Address-space cast must be used to convert address spaces");
2561 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2562 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2564 PT->getPointeeType(),
2575 const QualType SrcType = E->
getType();
2580 Src = Builder.CreateLaunderInvariantGroup(Src);
2588 Src = Builder.CreateStripInvariantGroup(Src);
2593 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2597 if (!PointeeType.
isNull())
2606 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2607 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2610 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2611 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2612 ScalableDstTy = llvm::ScalableVectorType::get(
2613 FixedSrcTy->getElementType(),
2615 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2617 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2618 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2619 llvm::Value *
Result = Builder.CreateInsertVector(
2620 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2622 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2623 if (
Result->getType() != ScalableDstTy)
2625 if (
Result->getType() != DstTy)
2635 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2636 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2639 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2640 FixedDstTy->getElementType()->isIntegerTy(8)) {
2641 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2642 ScalableSrcTy = llvm::ScalableVectorType::get(
2643 ScalableSrcTy->getElementType(),
2645 ScalableSrcTy->getElementCount().getKnownMinValue()));
2646 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2647 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2651 ScalableSrcTy = llvm::ScalableVectorType::get(
2652 FixedDstTy->getElementType(),
2653 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2654 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2656 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2657 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2678 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2681 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2684 case CK_AddressSpaceConversion: {
2687 Result.Val.isNullPointer()) {
2691 if (
Result.HasSideEffects)
2694 ConvertType(DestTy)), DestTy);
2700 ConvertType(DestTy));
2702 case CK_AtomicToNonAtomic:
2703 case CK_NonAtomicToAtomic:
2704 case CK_UserDefinedConversion:
2711 case CK_BaseToDerived: {
2713 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2727 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2735 case CK_UncheckedDerivedToBase:
2736 case CK_DerivedToBase: {
2749 case CK_ArrayToPointerDecay:
2752 case CK_FunctionToPointerDecay:
2753 return EmitLValue(E).getPointer(CGF);
2755 case CK_NullToPointer:
2756 if (MustVisitNullValue(E))
2762 case CK_NullToMemberPointer: {
2763 if (MustVisitNullValue(E))
2766 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2770 case CK_ReinterpretMemberPointer:
2771 case CK_BaseToDerivedMemberPointer:
2772 case CK_DerivedToBaseMemberPointer: {
2773 Value *Src = Visit(E);
2784 case CK_ARCProduceObject:
2786 case CK_ARCConsumeObject:
2788 case CK_ARCReclaimReturnedObject:
2790 case CK_ARCExtendBlockObject:
2793 case CK_CopyAndAutoreleaseBlockObject:
2796 case CK_FloatingRealToComplex:
2797 case CK_FloatingComplexCast:
2798 case CK_IntegralRealToComplex:
2799 case CK_IntegralComplexCast:
2800 case CK_IntegralComplexToFloatingComplex:
2801 case CK_FloatingComplexToIntegralComplex:
2802 case CK_ConstructorConversion:
2804 case CK_HLSLArrayRValue:
2805 llvm_unreachable(
"scalar cast to non-scalar value");
2807 case CK_LValueToRValue:
2809 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2812 case CK_IntegralToPointer: {
2813 Value *Src = Visit(E);
2817 auto DestLLVMTy = ConvertType(DestTy);
2820 llvm::Value* IntResult =
2821 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2823 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2829 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2835 case CK_PointerToIntegral: {
2836 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2837 auto *PtrExpr = Visit(E);
2840 const QualType SrcType = E->
getType();
2845 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2849 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2855 case CK_MatrixCast: {
2856 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2863 case CK_HLSLAggregateSplatCast:
2864 case CK_VectorSplat: {
2865 llvm::Type *DstTy = ConvertType(DestTy);
2866 Value *Elt = Visit(E);
2868 llvm::ElementCount NumElements =
2870 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2873 case CK_FixedPointCast:
2874 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2877 case CK_FixedPointToBoolean:
2879 "Expected src type to be fixed point type");
2880 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2881 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2884 case CK_FixedPointToIntegral:
2886 "Expected src type to be fixed point type");
2887 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2888 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2891 case CK_IntegralToFixedPoint:
2893 "Expected src type to be an integer");
2895 "Expected dest type to be fixed point type");
2896 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2899 case CK_IntegralCast: {
2901 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2902 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2906 ScalarConversionOpts Opts;
2907 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2908 if (!ICE->isPartOfExplicitCast())
2909 Opts = ScalarConversionOpts(CGF.
SanOpts);
2911 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2914 case CK_IntegralToFloating: {
2917 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2919 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2920 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2922 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2923 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2926 case CK_FloatingToIntegral: {
2929 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2931 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2932 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2934 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2935 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2938 case CK_FloatingCast: {
2941 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2942 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2943 if (DstElTy->
castAs<BuiltinType>()->getKind() <
2944 SrcElTy->
castAs<BuiltinType>()->getKind())
2945 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2946 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2948 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2949 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2952 case CK_FixedPointToFloating:
2953 case CK_FloatingToFixedPoint: {
2954 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2955 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2958 case CK_BooleanToSignedIntegral: {
2959 ScalarConversionOpts Opts;
2960 Opts.TreatBooleanAsSigned =
true;
2961 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2964 case CK_IntegralToBoolean:
2965 return EmitIntToBoolConversion(Visit(E));
2966 case CK_PointerToBoolean:
2967 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2968 case CK_FloatingToBoolean: {
2969 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2970 return EmitFloatToBoolConversion(Visit(E));
2972 case CK_MemberPointerToBoolean: {
2973 llvm::Value *MemPtr = Visit(E);
2974 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
2978 case CK_FloatingComplexToReal:
2979 case CK_IntegralComplexToReal:
2982 case CK_FloatingComplexToBoolean:
2983 case CK_IntegralComplexToBoolean: {
2987 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2991 case CK_ZeroToOCLOpaqueType: {
2994 "CK_ZeroToOCLEvent cast on non-event type");
2995 return llvm::Constant::getNullValue(ConvertType(DestTy));
2998 case CK_IntToOCLSampler:
3001 case CK_HLSLVectorTruncation: {
3003 "Destination type must be a vector or builtin type.");
3004 Value *Vec = Visit(E);
3005 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3006 SmallVector<int> Mask;
3007 unsigned NumElts = VecTy->getNumElements();
3008 for (
unsigned I = 0; I != NumElts; ++I)
3011 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3013 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3014 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3016 case CK_HLSLMatrixTruncation: {
3018 "Destination type must be a matrix or builtin type.");
3019 Value *Mat = Visit(E);
3020 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3021 SmallVector<int> Mask;
3022 unsigned NumCols = MatTy->getNumColumns();
3023 unsigned NumRows = MatTy->getNumRows();
3024 unsigned ColOffset = NumCols;
3025 if (
auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>())
3026 ColOffset = SrcMatTy->getNumColumns();
3027 for (
unsigned R = 0; R < NumRows; R++) {
3028 for (
unsigned C = 0;
C < NumCols;
C++) {
3029 unsigned I = R * ColOffset +
C;
3034 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3036 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3037 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3039 case CK_HLSLElementwiseCast: {
3059 llvm_unreachable(
"unknown scalar cast");
3062Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3063 CodeGenFunction::StmtExprEvaluation eval(CGF);
3072Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3073 CodeGenFunction::RunCleanupsScope Scope(CGF);
3077 Scope.ForceCleanup({&
V});
3086 llvm::Value *InVal,
bool IsInc,
3090 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3092 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3093 BinOp.FPFeatures = FPFeatures;
3098llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3099 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3100 llvm::Value *Amount =
3101 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3102 StringRef Name = IsInc ?
"inc" :
"dec";
3103 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3104 case LangOptions::SOB_Defined:
3105 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3106 return Builder.CreateAdd(InVal, Amount, Name);
3108 case LangOptions::SOB_Undefined:
3109 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3110 return Builder.CreateNSWAdd(InVal, Amount, Name);
3112 case LangOptions::SOB_Trapping:
3116 return Builder.CreateNSWAdd(InVal, Amount, Name);
3117 return EmitOverflowCheckedBinOp(Info);
3119 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3144class OMPLastprivateConditionalUpdateRAII {
3146 CodeGenFunction &CGF;
3147 const UnaryOperator *E;
3150 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3151 const UnaryOperator *E)
3153 ~OMPLastprivateConditionalUpdateRAII() {
3162ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3163 bool isInc,
bool isPre) {
3165 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3167 llvm::PHINode *atomicPHI =
nullptr;
3171 QualType SrcType = E->
getType();
3173 int amount = (isInc ? 1 : -1);
3174 bool isSubtraction = !isInc;
3176 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3177 type = atomicTy->getValueType();
3178 if (isInc &&
type->isBooleanType()) {
3181 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3182 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3183 return Builder.getTrue();
3187 return Builder.CreateAtomicRMW(
3188 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3189 llvm::AtomicOrdering::SequentiallyConsistent);
3194 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3195 !(
type->isUnsignedIntegerType() &&
3196 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3198 LangOptions::SOB_Trapping) {
3199 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3200 llvm::AtomicRMWInst::Sub;
3201 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3202 llvm::Instruction::Sub;
3204 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3206 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3207 llvm::AtomicOrdering::SequentiallyConsistent);
3208 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3212 if (
type->isFloatingType()) {
3213 llvm::Type *Ty = ConvertType(
type);
3214 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3215 llvm::AtomicRMWInst::BinOp aop =
3216 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3217 llvm::Instruction::BinaryOps op =
3218 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3219 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3220 llvm::AtomicRMWInst *old =
3222 llvm::AtomicOrdering::SequentiallyConsistent);
3224 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3227 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3230 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3233 Builder.CreateBr(opBB);
3234 Builder.SetInsertPoint(opBB);
3235 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3236 atomicPHI->addIncoming(value, startBB);
3239 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3250 if (isInc &&
type->isBooleanType()) {
3251 value = Builder.getTrue();
3254 }
else if (
type->isIntegerType()) {
3255 QualType promotedType;
3256 bool canPerformLossyDemotionCheck =
false;
3258 bool excludeOverflowPattern =
3263 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3264 canPerformLossyDemotionCheck =
true;
3265 canPerformLossyDemotionCheck &=
3268 canPerformLossyDemotionCheck &=
3270 type, promotedType);
3271 assert((!canPerformLossyDemotionCheck ||
3272 type->isSignedIntegerOrEnumerationType() ||
3274 ConvertType(
type)->getScalarSizeInBits() ==
3275 ConvertType(promotedType)->getScalarSizeInBits()) &&
3276 "The following check expects that if we do promotion to different "
3277 "underlying canonical type, at least one of the types (either "
3278 "base or promoted) will be signed, or the bitwidths will match.");
3281 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3282 SanitizerKind::ImplicitBitfieldConversion) &&
3283 canPerformLossyDemotionCheck) {
3297 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3298 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3299 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3303 ScalarConversionOpts Opts;
3304 if (!LV.isBitField())
3305 Opts = ScalarConversionOpts(CGF.
SanOpts);
3306 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3308 SrcType = promotedType;
3311 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3317 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3318 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3320 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3321 !excludeOverflowPattern &&
3323 SanitizerKind::UnsignedIntegerOverflow, E->
getType())) {
3327 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3328 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3332 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3333 QualType
type = ptr->getPointeeType();
3336 if (
const VariableArrayType *vla
3339 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3342 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3345 elemTy, value, numElts,
false, isSubtraction,
3349 }
else if (
type->isFunctionType()) {
3350 llvm::Value *amt = Builder.getInt32(amount);
3353 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3357 false, isSubtraction,
3362 llvm::Value *amt = Builder.getInt32(amount);
3365 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3368 elemTy, value, amt,
false, isSubtraction,
3373 }
else if (
type->isVectorType()) {
3374 if (
type->hasIntegerRepresentation()) {
3375 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3377 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3379 value = Builder.CreateFAdd(
3381 llvm::ConstantFP::get(value->getType(), amount),
3382 isInc ?
"inc" :
"dec");
3386 }
else if (
type->isRealFloatingType()) {
3389 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3394 value = Builder.CreateCall(
3397 input,
"incdec.conv");
3399 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3403 if (value->getType()->isFloatTy())
3404 amt = llvm::ConstantFP::get(VMContext,
3405 llvm::APFloat(
static_cast<float>(amount)));
3406 else if (value->getType()->isDoubleTy())
3407 amt = llvm::ConstantFP::get(VMContext,
3408 llvm::APFloat(
static_cast<double>(amount)));
3412 llvm::APFloat F(
static_cast<float>(amount));
3414 const llvm::fltSemantics *FS;
3417 if (value->getType()->isFP128Ty())
3419 else if (value->getType()->isHalfTy())
3421 else if (value->getType()->isBFloatTy())
3423 else if (value->getType()->isPPC_FP128Ty())
3427 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3428 amt = llvm::ConstantFP::get(VMContext, F);
3430 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3434 value = Builder.CreateCall(
3437 value,
"incdec.conv");
3439 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3444 }
else if (
type->isFixedPointType()) {
3451 Info.Opcode = isInc ? BO_Add : BO_Sub;
3453 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3456 if (
type->isSignedFixedPointType()) {
3457 Info.Opcode = isInc ? BO_Sub : BO_Add;
3458 Info.RHS = Builder.CreateNeg(Info.RHS);
3463 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3465 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3466 value = EmitFixedPointBinOp(Info);
3470 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3473 if (!isInc) size = -size;
3474 llvm::Value *sizeValue =
3475 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3478 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3481 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3483 value = Builder.CreateBitCast(value, input->getType());
3487 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3492 llvm::Value *
success = Pair.second;
3493 atomicPHI->addIncoming(old, curBlock);
3494 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3495 Builder.SetInsertPoint(contBB);
3496 return isPre ? value : input;
3500 if (LV.isBitField()) {
3510 return isPre ? value : input;
3514Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3515 QualType PromotionType) {
3516 QualType promotionTy = PromotionType.
isNull()
3519 Value *result = VisitPlus(E, promotionTy);
3520 if (result && !promotionTy.
isNull())
3521 result = EmitUnPromotedValue(result, E->
getType());
3525Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3526 QualType PromotionType) {
3528 TestAndClearIgnoreResultAssign();
3529 if (!PromotionType.
isNull())
3534Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3535 QualType PromotionType) {
3536 QualType promotionTy = PromotionType.
isNull()
3539 Value *result = VisitMinus(E, promotionTy);
3540 if (result && !promotionTy.
isNull())
3541 result = EmitUnPromotedValue(result, E->
getType());
3545Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3546 QualType PromotionType) {
3547 TestAndClearIgnoreResultAssign();
3549 if (!PromotionType.
isNull())
3555 if (Op->
getType()->isFPOrFPVectorTy())
3556 return Builder.CreateFNeg(Op,
"fneg");
3561 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3563 BinOp.Opcode = BO_Sub;
3566 return EmitSub(BinOp);
3569Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3570 TestAndClearIgnoreResultAssign();
3572 return Builder.CreateNot(Op,
"not");
3575Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3579 VectorKind::Generic) {
3583 if (Oper->
getType()->isFPOrFPVectorTy()) {
3584 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3586 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3588 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3589 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3598 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3601 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3604Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3606 Expr::EvalResult EVResult;
3609 return Builder.getInt(
Value);
3614 llvm::Type* ResultType = ConvertType(E->
getType());
3615 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3617 for (
unsigned i = 0; i != n; ++i) {
3619 llvm::Value *Offset =
nullptr;
3626 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3633 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3637 Offset = Builder.CreateMul(Idx, ElemSize);
3642 FieldDecl *MemberDecl = ON.
getField();
3650 FieldEnd = RD->field_end();
3651 Field != FieldEnd; ++Field, ++i) {
3652 if (*Field == MemberDecl)
3655 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3660 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3663 CurrentType = MemberDecl->
getType();
3668 llvm_unreachable(
"dependent __builtin_offsetof");
3685 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3697ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3698 const UnaryExprOrTypeTraitExpr *E) {
3701 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3702 if (
const VariableArrayType *VAT =
3707 bool EvaluateExtent =
true;
3708 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3710 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3712 if (EvaluateExtent) {
3723 if (Kind == UETT_CountOf)
3732 if (!eltSize.
isOne())
3735 return VlaSize.NumElts;
3738 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3744 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3745 }
else if (E->
getKind() == UETT_VectorElements) {
3747 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3755Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3756 QualType PromotionType) {
3757 QualType promotionTy = PromotionType.
isNull()
3760 Value *result = VisitReal(E, promotionTy);
3761 if (result && !promotionTy.
isNull())
3762 result = EmitUnPromotedValue(result, E->
getType());
3766Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3767 QualType PromotionType) {
3774 if (!PromotionType.
isNull()) {
3776 Op, IgnoreResultAssign,
true);
3791 if (!PromotionType.
isNull())
3796Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3797 QualType PromotionType) {
3798 QualType promotionTy = PromotionType.
isNull()
3801 Value *result = VisitImag(E, promotionTy);
3802 if (result && !promotionTy.
isNull())
3803 result = EmitUnPromotedValue(result, E->
getType());
3807Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3808 QualType PromotionType) {
3815 if (!PromotionType.
isNull()) {
3817 Op,
true, IgnoreResultAssign);
3821 return result.second
3837 else if (!PromotionType.
isNull())
3841 if (!PromotionType.
isNull())
3842 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3843 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3850Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3851 QualType PromotionType) {
3852 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3855Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3856 QualType ExprType) {
3857 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3860Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3862 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3864#define HANDLE_BINOP(OP) \
3866 return Emit##OP(EmitBinOps(BO, PromotionType));
3875 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3878 return VisitImag(UO, PromotionType);
3880 return VisitReal(UO, PromotionType);
3882 return VisitMinus(UO, PromotionType);
3884 return VisitPlus(UO, PromotionType);
3889 auto result = Visit(
const_cast<Expr *
>(E));
3891 if (!PromotionType.
isNull())
3892 return EmitPromotedValue(result, PromotionType);
3894 return EmitUnPromotedValue(result, E->
getType());
3899BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3900 QualType PromotionType) {
3901 TestAndClearIgnoreResultAssign();
3905 if (!PromotionType.
isNull())
3906 Result.Ty = PromotionType;
3915LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3916 const CompoundAssignOperator *E,
3917 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3928 QualType PromotionTypeCR;
3930 if (PromotionTypeCR.
isNull())
3933 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3934 if (!PromotionTypeRHS.
isNull())
3937 OpInfo.RHS = Visit(E->
getRHS());
3938 OpInfo.Ty = PromotionTypeCR;
3945 llvm::PHINode *atomicPHI =
nullptr;
3946 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3947 QualType
type = atomicTy->getValueType();
3948 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3949 !(
type->isUnsignedIntegerType() &&
3950 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3952 LangOptions::SOB_Trapping) {
3953 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3954 llvm::Instruction::BinaryOps Op;
3955 switch (OpInfo.Opcode) {
3957 case BO_MulAssign:
case BO_DivAssign:
3963 AtomicOp = llvm::AtomicRMWInst::Add;
3964 Op = llvm::Instruction::Add;
3967 AtomicOp = llvm::AtomicRMWInst::Sub;
3968 Op = llvm::Instruction::Sub;
3971 AtomicOp = llvm::AtomicRMWInst::And;
3972 Op = llvm::Instruction::And;
3975 AtomicOp = llvm::AtomicRMWInst::Xor;
3976 Op = llvm::Instruction::Xor;
3979 AtomicOp = llvm::AtomicRMWInst::Or;
3980 Op = llvm::Instruction::Or;
3983 llvm_unreachable(
"Invalid compound assignment type");
3985 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3987 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3991 llvm::AtomicRMWInst *OldVal =
3996 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4002 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4004 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4006 Builder.CreateBr(opBB);
4007 Builder.SetInsertPoint(opBB);
4008 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4009 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4010 OpInfo.LHS = atomicPHI;
4013 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4015 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4017 if (!PromotionTypeLHS.
isNull())
4018 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4021 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4032 if (LHSLV.isBitField()) {
4034 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4036 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4037 ScalarConversionOpts(CGF.
SanOpts));
4040 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4044 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4045 llvm::Value *
success = Pair.second;
4046 atomicPHI->addIncoming(old, curBlock);
4047 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4048 Builder.SetInsertPoint(contBB);
4056 if (LHSLV.isBitField()) {
4072Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4073 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4074 bool Ignore = TestAndClearIgnoreResultAssign();
4075 Value *RHS =
nullptr;
4076 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4087 if (!LHS.isVolatileQualified())
4091 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4094void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4095 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4096 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4099 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4100 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4101 SanitizerKind::SO_IntegerDivideByZero));
4105 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4106 Ops.Ty->hasSignedIntegerRepresentation() &&
4108 Ops.mayHaveIntegerOverflow()) {
4111 llvm::Value *IntMin =
4112 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4113 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4115 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4116 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4117 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4119 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4122 if (Checks.size() > 0)
4123 EmitBinOpCheck(Checks, Ops);
4126Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4128 SanitizerDebugLocation SanScope(&CGF,
4129 {SanitizerKind::SO_IntegerDivideByZero,
4130 SanitizerKind::SO_SignedIntegerOverflow,
4131 SanitizerKind::SO_FloatDivideByZero},
4132 SanitizerHandler::DivremOverflow);
4133 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4134 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4135 Ops.Ty->isIntegerType() &&
4136 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4137 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4138 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4139 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4140 Ops.Ty->isRealFloatingType() &&
4141 Ops.mayHaveFloatDivisionByZero()) {
4142 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4143 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4145 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4149 if (Ops.Ty->isConstantMatrixType()) {
4150 llvm::MatrixBuilder MB(Builder);
4157 "first operand must be a matrix");
4159 "second operand must be an arithmetic type");
4160 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4161 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4162 Ops.Ty->hasUnsignedIntegerRepresentation());
4165 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4167 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4168 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4172 else if (Ops.isFixedPointOp())
4173 return EmitFixedPointBinOp(Ops);
4174 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4175 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4177 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4180Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4182 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4183 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4184 Ops.Ty->isIntegerType() &&
4185 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4186 SanitizerDebugLocation SanScope(&CGF,
4187 {SanitizerKind::SO_IntegerDivideByZero,
4188 SanitizerKind::SO_SignedIntegerOverflow},
4189 SanitizerHandler::DivremOverflow);
4190 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4191 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4194 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4195 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4197 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4198 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4200 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4203Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4208 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4209 switch (Ops.Opcode) {
4213 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4214 llvm::Intrinsic::uadd_with_overflow;
4215 OverflowKind = SanitizerHandler::AddOverflow;
4220 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4221 llvm::Intrinsic::usub_with_overflow;
4222 OverflowKind = SanitizerHandler::SubOverflow;
4227 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4228 llvm::Intrinsic::umul_with_overflow;
4229 OverflowKind = SanitizerHandler::MulOverflow;
4232 llvm_unreachable(
"Unsupported operation for overflow detection");
4238 SanitizerDebugLocation SanScope(&CGF,
4239 {SanitizerKind::SO_SignedIntegerOverflow,
4240 SanitizerKind::SO_UnsignedIntegerOverflow},
4246 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4247 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4248 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4251 const std::string *handlerName =
4253 if (handlerName->empty()) {
4256 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4257 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4259 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4260 : SanitizerKind::SO_UnsignedIntegerOverflow;
4261 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4263 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4268 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4269 llvm::BasicBlock *continueBB =
4273 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4277 Builder.SetInsertPoint(overflowBB);
4280 llvm::Type *Int8Ty = CGF.
Int8Ty;
4281 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4282 llvm::FunctionType *handlerTy =
4283 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4284 llvm::FunctionCallee handler =
4289 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4290 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4294 llvm::Value *handlerArgs[] = {
4297 Builder.getInt8(OpID),
4300 llvm::Value *handlerResult =
4304 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4305 Builder.CreateBr(continueBB);
4307 Builder.SetInsertPoint(continueBB);
4308 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4309 phi->addIncoming(result, initialBB);
4310 phi->addIncoming(handlerResult, overflowBB);
4319 bool isSubtraction) {
4324 Value *pointer = op.LHS;
4325 Expr *pointerOperand =
expr->getLHS();
4327 Expr *indexOperand =
expr->getRHS();
4330 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4331 std::swap(pointer,
index);
4332 std::swap(pointerOperand, indexOperand);
4336 index, isSubtraction);
4342 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4346 auto &DL =
CGM.getDataLayout();
4369 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4371 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4372 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4373 PtrTy->getPointerAddressSpace()))
4376 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4377 auto CheckHandler = SanitizerHandler::PointerOverflow;
4379 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4381 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4382 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4384 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4385 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4390 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4401 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4411 llvm::Value *objectSize =
4417 return Builder.CreateBitCast(result, pointer->getType());
4422 getContext().getAsVariableArrayType(elementType)) {
4424 llvm::Value *numElements =
getVLASize(vla).NumElts;
4433 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4453 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4466 bool negMul,
bool negAdd) {
4467 Value *MulOp0 = MulOp->getOperand(0);
4468 Value *MulOp1 = MulOp->getOperand(1);
4470 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4472 Addend = Builder.CreateFNeg(Addend,
"neg");
4474 Value *FMulAdd =
nullptr;
4475 if (Builder.getIsFPConstrained()) {
4477 "Only constrained operation should be created when Builder is in FP "
4478 "constrained mode");
4479 FMulAdd = Builder.CreateConstrainedFPCall(
4480 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4482 {MulOp0, MulOp1, Addend});
4484 FMulAdd = Builder.CreateCall(
4486 {MulOp0, MulOp1, Addend});
4488 MulOp->eraseFromParent();
4503 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4504 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4505 "Only fadd/fsub can be the root of an fmuladd.");
4508 if (!op.FPFeatures.allowFPContractWithinStatement())
4511 Value *LHS = op.LHS;
4512 Value *RHS = op.RHS;
4516 bool NegLHS =
false;
4517 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4518 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4519 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4520 LHS = LHSUnOp->getOperand(0);
4525 bool NegRHS =
false;
4526 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4527 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4528 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4529 RHS = RHSUnOp->getOperand(0);
4537 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4538 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4539 (LHSBinOp->use_empty() || NegLHS)) {
4543 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4546 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4547 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4548 (RHSBinOp->use_empty() || NegRHS)) {
4552 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4556 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4557 if (LHSBinOp->getIntrinsicID() ==
4558 llvm::Intrinsic::experimental_constrained_fmul &&
4559 (LHSBinOp->use_empty() || NegLHS)) {
4563 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4566 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4567 if (RHSBinOp->getIntrinsicID() ==
4568 llvm::Intrinsic::experimental_constrained_fmul &&
4569 (RHSBinOp->use_empty() || NegRHS)) {
4573 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4580Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4581 if (op.LHS->getType()->isPointerTy() ||
4582 op.RHS->getType()->isPointerTy())
4585 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4586 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4587 case LangOptions::SOB_Defined:
4588 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4589 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4591 case LangOptions::SOB_Undefined:
4592 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4593 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4595 case LangOptions::SOB_Trapping:
4596 if (CanElideOverflowCheck(CGF.
getContext(), op))
4597 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4598 return EmitOverflowCheckedBinOp(op);
4603 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4604 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4610 if (op.Ty->isConstantMatrixType()) {
4611 llvm::MatrixBuilder MB(Builder);
4612 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4613 return MB.CreateAdd(op.LHS, op.RHS);
4616 if (op.Ty->isUnsignedIntegerType() &&
4617 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4618 !CanElideOverflowCheck(CGF.
getContext(), op))
4619 return EmitOverflowCheckedBinOp(op);
4621 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4622 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4623 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4626 if (op.isFixedPointOp())
4627 return EmitFixedPointBinOp(op);
4629 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4634Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4636 using llvm::ConstantInt;
4642 QualType ResultTy = op.Ty;
4643 QualType LHSTy, RHSTy;
4644 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4645 RHSTy = BinOp->getRHS()->getType();
4646 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4651 LHSTy = CAO->getComputationLHSType();
4652 ResultTy = CAO->getComputationResultType();
4654 LHSTy = BinOp->getLHS()->getType();
4655 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4656 LHSTy = UnOp->getSubExpr()->getType();
4657 RHSTy = UnOp->getSubExpr()->getType();
4660 Value *LHS = op.LHS;
4661 Value *RHS = op.RHS;
4666 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4670 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4671 switch (op.Opcode) {
4674 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4678 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4682 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4686 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4690 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4694 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4697 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4699 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4701 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4703 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4708 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4710 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4714 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4727 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4733 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4738Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4740 if (!op.LHS->getType()->isPointerTy()) {
4741 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4742 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4743 case LangOptions::SOB_Defined:
4744 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4745 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4747 case LangOptions::SOB_Undefined:
4748 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4749 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4751 case LangOptions::SOB_Trapping:
4752 if (CanElideOverflowCheck(CGF.
getContext(), op))
4753 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4754 return EmitOverflowCheckedBinOp(op);
4759 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4760 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4766 if (op.Ty->isConstantMatrixType()) {
4767 llvm::MatrixBuilder MB(Builder);
4768 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4769 return MB.CreateSub(op.LHS, op.RHS);
4772 if (op.Ty->isUnsignedIntegerType() &&
4773 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4774 !CanElideOverflowCheck(CGF.
getContext(), op))
4775 return EmitOverflowCheckedBinOp(op);
4777 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4778 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4779 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4782 if (op.isFixedPointOp())
4783 return EmitFixedPointBinOp(op);
4785 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4790 if (!op.RHS->getType()->isPointerTy())
4797 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4799 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4800 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4804 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4806 llvm::Value *divisor =
nullptr;
4809 if (
const VariableArrayType *vla
4812 elementType = VlaSize.Type;
4813 divisor = VlaSize.NumElts;
4817 if (!eltSize.
isOne())
4824 CharUnits elementSize;
4833 if (elementSize.
isOne())
4842 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4845Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4847 llvm::IntegerType *Ty;
4848 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4856 llvm::Type *RHSTy = RHS->
getType();
4857 llvm::APInt RHSMax =
4858 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4859 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4860 if (RHSMax.ult(Ty->getBitWidth()))
4861 return llvm::ConstantInt::get(RHSTy, RHSMax);
4862 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4866 const Twine &Name) {
4867 llvm::IntegerType *Ty;
4868 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4873 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4874 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4876 return Builder.CreateURem(
4877 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4880Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4882 if (Ops.isFixedPointOp())
4883 return EmitFixedPointBinOp(Ops);
4887 Value *RHS = Ops.RHS;
4888 if (Ops.LHS->getType() != RHS->
getType())
4889 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4891 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4892 Ops.Ty->hasSignedIntegerRepresentation() &&
4895 bool SanitizeUnsignedBase =
4896 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4897 Ops.Ty->hasUnsignedIntegerRepresentation();
4898 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4899 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4902 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4903 else if ((SanitizeBase || SanitizeExponent) &&
4905 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4906 if (SanitizeSignedBase)
4907 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4908 if (SanitizeUnsignedBase)
4909 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4910 if (SanitizeExponent)
4911 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4913 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4914 SanitizerHandler::ShiftOutOfBounds);
4915 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4916 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4917 llvm::Value *WidthMinusOne =
4918 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4919 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4921 if (SanitizeExponent) {
4923 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4930 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4933 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4934 llvm::Value *PromotedWidthMinusOne =
4935 (RHS == Ops.RHS) ? WidthMinusOne
4936 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4938 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4939 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4948 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4949 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4951 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4952 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4954 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4955 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4956 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4957 Checks.push_back(std::make_pair(
4958 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4959 : SanitizerKind::SO_UnsignedShiftBase));
4962 assert(!Checks.empty());
4963 EmitBinOpCheck(Checks, Ops);
4966 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4969Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4971 if (Ops.isFixedPointOp())
4972 return EmitFixedPointBinOp(Ops);
4976 Value *RHS = Ops.RHS;
4977 if (Ops.LHS->getType() != RHS->
getType())
4978 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4982 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4983 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4985 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4986 SanitizerHandler::ShiftOutOfBounds);
4987 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4988 llvm::Value *
Valid = Builder.CreateICmpULE(
4989 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4990 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4993 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4994 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4995 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5003 default: llvm_unreachable(
"unexpected element type");
5004 case BuiltinType::Char_U:
5005 case BuiltinType::UChar:
5006 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5007 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5008 case BuiltinType::Char_S:
5009 case BuiltinType::SChar:
5010 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5011 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5012 case BuiltinType::UShort:
5013 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5014 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5015 case BuiltinType::Short:
5016 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5017 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5018 case BuiltinType::UInt:
5019 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5020 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5021 case BuiltinType::Int:
5022 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5023 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5024 case BuiltinType::ULong:
5025 case BuiltinType::ULongLong:
5026 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5027 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5028 case BuiltinType::Long:
5029 case BuiltinType::LongLong:
5030 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5031 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5032 case BuiltinType::Float:
5033 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5034 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5035 case BuiltinType::Double:
5036 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5037 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5038 case BuiltinType::UInt128:
5039 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5040 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5041 case BuiltinType::Int128:
5042 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5043 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5047Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5048 llvm::CmpInst::Predicate UICmpOpc,
5049 llvm::CmpInst::Predicate SICmpOpc,
5050 llvm::CmpInst::Predicate FCmpOpc,
5052 TestAndClearIgnoreResultAssign();
5056 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5062 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5064 BinOpInfo BOInfo = EmitBinOps(E);
5065 Value *LHS = BOInfo.LHS;
5066 Value *RHS = BOInfo.RHS;
5072 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5074 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5077 Value *FirstVecArg = LHS,
5078 *SecondVecArg = RHS;
5080 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5084 default: llvm_unreachable(
"is not a comparison operation");
5096 std::swap(FirstVecArg, SecondVecArg);
5103 if (ElementKind == BuiltinType::Float) {
5105 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5106 std::swap(FirstVecArg, SecondVecArg);
5114 if (ElementKind == BuiltinType::Float) {
5116 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5121 std::swap(FirstVecArg, SecondVecArg);
5126 Value *CR6Param = Builder.getInt32(CR6);
5128 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5136 if (ResultTy->getBitWidth() > 1 &&
5138 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5143 if (BOInfo.isFixedPointOp()) {
5144 Result = EmitFixedPointBinOp(BOInfo);
5145 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5146 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5148 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5150 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5152 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5167 LHS = Builder.CreateStripInvariantGroup(LHS);
5169 RHS = Builder.CreateStripInvariantGroup(RHS);
5172 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5178 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5184 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5186 CETy = CTy->getElementType();
5188 LHS.first = Visit(E->
getLHS());
5189 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5192 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5195 CTy->getElementType()) &&
5196 "The element types must always match.");
5199 RHS.first = Visit(E->
getRHS());
5200 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5202 "The element types must always match.");
5205 Value *ResultR, *ResultI;
5209 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5210 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5214 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5215 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5219 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5222 "Complex comparison other than == or != ?");
5223 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5235 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5236 CastKind Kind = ICE->getCastKind();
5237 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5238 *SrcType = ICE->getSubExpr()->getType();
5251 bool Ignore = TestAndClearIgnoreResultAssign();
5285 RHS = Visit(E->
getRHS());
5301 RHS = Visit(E->
getRHS());
5341 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5344Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5352 if (LHS->
getType()->isFPOrFPVectorTy()) {
5353 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5355 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5356 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5358 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5359 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5361 Value *
And = Builder.CreateAnd(LHS, RHS);
5362 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5366 llvm::Type *ResTy = ConvertType(E->
getType());
5387 if (InstrumentRegions &&
5392 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5406 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5412 return llvm::Constant::getNullValue(ResTy);
5425 CodeGenFunction::ConditionalEvaluation eval(CGF);
5434 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5436 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5438 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5447 RHSBlock = Builder.GetInsertBlock();
5452 if (InstrumentRegions &&
5456 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5460 PN->addIncoming(RHSCond, RHSBlockCnt);
5470 PN->addIncoming(RHSCond, RHSBlock);
5480 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5484 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5487Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5495 if (LHS->
getType()->isFPOrFPVectorTy()) {
5496 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5498 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5499 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5501 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5502 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5504 Value *
Or = Builder.CreateOr(LHS, RHS);
5505 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5509 llvm::Type *ResTy = ConvertType(E->
getType());
5530 if (InstrumentRegions &&
5535 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5549 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5555 return llvm::ConstantInt::get(ResTy, 1);
5568 CodeGenFunction::ConditionalEvaluation eval(CGF);
5578 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5580 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5582 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5594 RHSBlock = Builder.GetInsertBlock();
5599 if (InstrumentRegions &&
5603 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5607 PN->addIncoming(RHSCond, RHSBlockCnt);
5613 PN->addIncoming(RHSCond, RHSBlock);
5621 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5624Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5627 return Visit(E->
getRHS());
5652Value *ScalarExprEmitter::
5653VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5654 TestAndClearIgnoreResultAssign();
5657 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5659 Expr *condExpr = E->
getCond();
5667 Expr *live = lhsExpr, *dead = rhsExpr;
5668 if (!CondExprBool) std::swap(live, dead);
5699 llvm::Value *LHS = Visit(lhsExpr);
5700 llvm::Value *RHS = Visit(rhsExpr);
5702 llvm::Type *condType = ConvertType(condExpr->
getType());
5705 unsigned numElem = vecTy->getNumElements();
5706 llvm::Type *elemType = vecTy->getElementType();
5708 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5709 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5710 llvm::Value *tmp = Builder.CreateSExt(
5711 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5712 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5715 llvm::Value *RHSTmp = RHS;
5716 llvm::Value *LHSTmp = LHS;
5717 bool wasCast =
false;
5719 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5720 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5721 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5725 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5726 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5727 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5729 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5739 llvm::Value *LHS = Visit(lhsExpr);
5740 llvm::Value *RHS = Visit(rhsExpr);
5742 llvm::Type *CondType = ConvertType(condExpr->
getType());
5745 if (VecTy->getElementType()->isIntegerTy(1))
5746 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5749 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5751 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5753 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5754 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5763 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5772 llvm::Value *LHS = Visit(lhsExpr);
5773 llvm::Value *RHS = Visit(rhsExpr);
5776 assert(!RHS &&
"LHS and RHS types must match");
5779 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5790 CodeGenFunction::ConditionalEvaluation eval(CGF);
5808 Value *LHS = Visit(lhsExpr);
5811 LHSBlock = Builder.GetInsertBlock();
5812 Builder.CreateBr(ContBlock);
5826 Value *RHS = Visit(rhsExpr);
5829 RHSBlock = Builder.GetInsertBlock();
5839 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5840 PN->addIncoming(LHS, LHSBlock);
5841 PN->addIncoming(RHS, RHSBlock);
5851Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5855Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5857 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5862Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5868 Value *Src,
unsigned NumElementsDst) {
5869 static constexpr int Mask[] = {0, 1, 2, -1};
5870 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5890 const llvm::DataLayout &DL,
5891 Value *Src, llvm::Type *DstTy,
5892 StringRef Name =
"") {
5896 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5897 return Builder.CreateBitCast(Src, DstTy, Name);
5900 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5901 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5904 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5906 if (!DstTy->isIntegerTy())
5907 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5909 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5913 if (!SrcTy->isIntegerTy())
5914 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5916 return Builder.CreateIntToPtr(Src, DstTy, Name);
5919Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5921 llvm::Type *DstTy = ConvertType(E->
getType());
5923 llvm::Type *SrcTy = Src->
getType();
5924 unsigned NumElementsSrc =
5928 unsigned NumElementsDst =
5939 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5944 Src->setName(
"astype");
5951 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5952 auto *Vec4Ty = llvm::FixedVectorType::get(
5958 Src->setName(
"astype");
5963 Src, DstTy,
"astype");
5966Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5978 "Invalid scalar expression to emit");
5980 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5981 .Visit(
const_cast<Expr *
>(E));
5990 "Invalid scalar expression to emit");
5991 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6001 "Invalid complex -> scalar conversion");
6002 return ScalarExprEmitter(*
this)
6003 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6010 if (!PromotionType.
isNull())
6011 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6013 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6019 bool isInc,
bool isPre) {
6020 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6030 llvm::Type *BaseTy =
6046 ScalarExprEmitter Scalar(*
this);
6049#define COMPOUND_OP(Op) \
6050 case BO_##Op##Assign: \
6051 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6088 llvm_unreachable(
"Not valid compound assignment operators");
6091 llvm_unreachable(
"Unhandled compound assignment operator");
6106 llvm::LLVMContext &VMContext,
6112 llvm::Value *TotalOffset =
nullptr;
6118 Value *BasePtr_int =
6119 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6121 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6122 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6123 return {TotalOffset, Builder.getFalse()};
6127 assert(GEP->getPointerOperand() == BasePtr &&
6128 "BasePtr must be the base of the GEP.");
6129 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6131 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6134 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6135 auto *SAddIntrinsic =
6136 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6137 auto *SMulIntrinsic =
6138 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6141 llvm::Value *OffsetOverflows = Builder.getFalse();
6145 llvm::Value *RHS) -> llvm::Value * {
6146 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6149 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6150 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6152 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6155 OffsetOverflows = Builder.getTrue();
6156 return llvm::ConstantInt::get(VMContext, N);
6161 auto *ResultAndOverflow = Builder.CreateCall(
6162 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6163 OffsetOverflows = Builder.CreateOr(
6164 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6165 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6169 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6170 GTI != GTE; ++GTI) {
6171 llvm::Value *LocalOffset;
6172 auto *Index = GTI.getOperand();
6174 if (
auto *STy = GTI.getStructTypeOrNull()) {
6178 LocalOffset = llvm::ConstantInt::get(
6179 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6184 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6185 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6186 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6191 if (!TotalOffset || TotalOffset ==
Zero)
6192 TotalOffset = LocalOffset;
6194 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6197 return {TotalOffset, OffsetOverflows};
6202 ArrayRef<Value *> IdxList,
6203 bool SignedIndices,
bool IsSubtraction,
6204 SourceLocation Loc,
const Twine &Name) {
6205 llvm::Type *PtrTy = Ptr->
getType();
6207 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6208 if (!SignedIndices && !IsSubtraction)
6209 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6211 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6214 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6218 bool PerformNullCheck = !NullPointerIsDefined(
6219 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6222 bool PerformOverflowCheck =
6225 if (!(PerformNullCheck || PerformOverflowCheck))
6228 const auto &DL = CGM.getDataLayout();
6230 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6231 auto CheckHandler = SanitizerHandler::PointerOverflow;
6232 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6233 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6235 GEPOffsetAndOverflow EvaluatedGEP =
6240 "If the offset got constant-folded, we don't expect that there was an "
6243 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6251 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6252 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6254 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6258 if (PerformNullCheck) {
6266 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6267 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6268 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6269 Checks.emplace_back(
Valid, CheckOrdinal);
6272 if (PerformOverflowCheck) {
6277 llvm::Value *ValidGEP;
6278 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6279 if (SignedIndices) {
6285 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6286 auto *PosOrZeroOffset =
6288 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6290 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6291 }
else if (!IsSubtraction) {
6296 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6302 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6304 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6305 Checks.emplace_back(ValidGEP, CheckOrdinal);
6308 assert(!Checks.empty() &&
"Should have produced some checks.");
6310 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6312 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6313 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6319 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6320 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6321 const Twine &Name) {
6322 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6323 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6324 if (!SignedIndices && !IsSubtraction)
6325 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6327 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6331 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6332 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6333 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)
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
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.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void 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
Represents a concrete matrix type with constant number of rows and columns.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
@ PostDecrInWhile
while (count–)
bool isSignedOverflowDefined() const
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
specific_decl_iterator< FieldDecl > field_iterator
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether 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.