36#include "llvm/ADT/APFixedPoint.h"
37#include "llvm/ADT/ScopeExit.h"
38#include "llvm/IR/Argument.h"
39#include "llvm/IR/CFG.h"
40#include "llvm/IR/Constants.h"
41#include "llvm/IR/DataLayout.h"
42#include "llvm/IR/DerivedTypes.h"
43#include "llvm/IR/FixedPointBuilder.h"
44#include "llvm/IR/Function.h"
45#include "llvm/IR/GEPNoWrapFlags.h"
46#include "llvm/IR/GetElementPtrTypeIterator.h"
47#include "llvm/IR/GlobalVariable.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/IntrinsicsPowerPC.h"
50#include "llvm/IR/IntrinsicsWebAssembly.h"
51#include "llvm/IR/MatrixBuilder.h"
52#include "llvm/IR/Module.h"
53#include "llvm/Support/TypeSize.h"
76bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
81 const auto &LHSAP = LHS->getValue();
82 const auto &RHSAP = RHS->getValue();
83 if (Opcode == BO_Add) {
85 : LHSAP.uadd_ov(RHSAP, Overflow);
86 }
else if (Opcode == BO_Sub) {
88 : LHSAP.usub_ov(RHSAP, Overflow);
89 }
else if (Opcode == BO_Mul) {
91 : LHSAP.umul_ov(RHSAP, Overflow);
92 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
93 if (
Signed && !RHS->isZero())
94 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
106 FPOptions FPFeatures;
110 bool mayHaveIntegerOverflow()
const {
112 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
113 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
114 if (!LHSCI || !RHSCI)
118 return ::mayHaveIntegerOverflow(
123 bool isDivremOp()
const {
129 bool mayHaveIntegerDivisionByZero()
const {
131 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
137 bool mayHaveFloatDivisionByZero()
const {
139 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
140 return CFP->isZero();
147 bool isFixedPointOp()
const {
150 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
151 QualType LHSType = BinOp->getLHS()->getType();
152 QualType RHSType = BinOp->getRHS()->getType();
155 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
156 return UnOp->getSubExpr()->getType()->isFixedPointType();
161 bool rhsHasSignedIntegerRepresentation()
const {
162 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
163 QualType RHSType = BinOp->getRHS()->getType();
170static bool MustVisitNullValue(
const Expr *E) {
193static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
203 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
208 switch (OBT->getBehaviorKind()) {
209 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
211 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
214 llvm_unreachable(
"Unknown OverflowBehaviorKind");
221 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
229 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
233static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
235 "Expected a unary or binary operator");
239 if (!Op.mayHaveIntegerOverflow())
246 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
247 if (BO && BO->hasExcludedOverflowPattern())
250 if (Op.Ty.isWrapType())
252 if (Op.Ty.isTrapType())
255 if (Op.Ty->isSignedIntegerType() &&
261 if (Op.Ty->isUnsignedIntegerType() &&
286 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
292 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
293 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
297class ScalarExprEmitter
299 CodeGenFunction &CGF;
300 CGBuilderTy &Builder;
301 bool IgnoreResultAssign;
302 llvm::LLVMContext &VMContext;
305 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
306 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
307 VMContext(cgf.getLLVMContext()) {
314 bool TestAndClearIgnoreResultAssign() {
315 bool I = IgnoreResultAssign;
316 IgnoreResultAssign =
false;
320 llvm::Type *ConvertType(QualType T) {
return CGF.
ConvertType(T); }
321 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
327 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
328 const BinOpInfo &Info);
330 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
334 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
335 const AlignValueAttr *AVAttr =
nullptr;
336 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
337 const ValueDecl *VD = DRE->getDecl();
340 if (
const auto *TTy =
342 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
352 AVAttr = VD->
getAttr<AlignValueAttr>();
357 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
358 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
371 Value *EmitLoadOfLValue(
const Expr *E) {
375 EmitLValueAlignmentAssumption(E,
V);
381 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
385 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
386 Value *Src, QualType SrcType, QualType DstType,
387 llvm::Type *DstTy, SourceLocation Loc);
392 enum ImplicitConversionCheckKind :
unsigned char {
393 ICCK_IntegerTruncation = 0,
394 ICCK_UnsignedIntegerTruncation = 1,
395 ICCK_SignedIntegerTruncation = 2,
396 ICCK_IntegerSignChange = 3,
397 ICCK_SignedIntegerTruncationOrSignChange = 4,
402 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
403 QualType DstType, SourceLocation Loc,
404 bool OBTrapInvolved =
false);
409 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
410 QualType DstType, SourceLocation Loc,
411 bool OBTrapInvolved =
false);
415 struct ScalarConversionOpts {
416 bool TreatBooleanAsSigned;
417 bool EmitImplicitIntegerTruncationChecks;
418 bool EmitImplicitIntegerSignChangeChecks;
420 bool PatternExcluded;
422 ScalarConversionOpts()
423 : TreatBooleanAsSigned(
false),
424 EmitImplicitIntegerTruncationChecks(
false),
425 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
427 ScalarConversionOpts(clang::SanitizerSet SanOpts)
428 : TreatBooleanAsSigned(
false),
429 EmitImplicitIntegerTruncationChecks(
430 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
431 EmitImplicitIntegerSignChangeChecks(
432 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
433 PatternExcluded(
false) {}
435 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
436 llvm::Type *SrcTy, llvm::Type *DstTy,
437 ScalarConversionOpts Opts);
439 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
441 ScalarConversionOpts Opts = ScalarConversionOpts());
445 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
451 QualType SrcTy, QualType DstTy,
455 Value *EmitNullValue(QualType Ty);
460 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
461 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
465 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
468 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
475 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
476 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
482 ZI->eraseFromParent();
487 return Builder.CreateIsNotNull(
V,
"tobool");
494 Value *Visit(Expr *E) {
495 ApplyDebugLocation DL(CGF, E);
496 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
499 Value *VisitStmt(Stmt *S) {
501 llvm_unreachable(
"Stmt can't have complex result type!");
503 Value *VisitExpr(Expr *S);
505 Value *VisitConstantExpr(ConstantExpr *E) {
511 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
526 Value *VisitParenExpr(ParenExpr *PE) {
529 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
532 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
533 return Visit(
GE->getResultExpr());
535 Value *VisitCoawaitExpr(CoawaitExpr *S) {
538 Value *VisitCoyieldExpr(CoyieldExpr *S) {
541 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
546 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
547 return Builder.getInt(E->
getValue());
549 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
550 return Builder.getInt(E->
getValue());
552 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
553 return llvm::ConstantFP::get(VMContext, E->
getValue());
555 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
558 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
561 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
562 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
564 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
565 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
567 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
571 return EmitNullValue(E->
getType());
573 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
574 return EmitNullValue(E->
getType());
576 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
577 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
578 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
580 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
583 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
587 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
591 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
592 Value *VisitEmbedExpr(EmbedExpr *E);
594 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
603 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
604 llvm_unreachable(
"Codegen for this isn't defined/implemented");
608 Value *VisitDeclRefExpr(DeclRefExpr *E) {
611 return EmitLoadOfLValue(E);
614 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
617 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
620 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
621 return EmitLoadOfLValue(E);
623 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
626 return EmitLoadOfLValue(E);
630 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
636 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
642 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
647 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
648 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
649 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
650 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
651 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
652 Value *VisitMemberExpr(MemberExpr *E);
653 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
654 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
655 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
661 return EmitLoadOfLValue(E);
664 Value *VisitInitListExpr(InitListExpr *E);
666 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
668 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
672 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
673 return EmitNullValue(E->
getType());
675 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
677 return VisitCastExpr(E);
681 Value *VisitCallExpr(
const CallExpr *E) {
683 return EmitLoadOfLValue(E);
687 EmitLValueAlignmentAssumption(E,
V);
691 Value *VisitStmtExpr(
const StmtExpr *E);
694 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
696 return EmitScalarPrePostIncDec(E, LV,
false,
false);
698 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
700 return EmitScalarPrePostIncDec(E, LV,
true,
false);
702 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
704 return EmitScalarPrePostIncDec(E, LV,
false,
true);
706 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
708 return EmitScalarPrePostIncDec(E, LV,
true,
true);
711 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
715 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
716 bool isInc,
bool isPre);
719 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
723 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
725 Value *VisitUnaryDeref(
const UnaryOperator *E) {
728 return EmitLoadOfLValue(E);
731 Value *VisitUnaryPlus(
const UnaryOperator *E,
732 QualType PromotionType = QualType());
733 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
734 Value *VisitUnaryMinus(
const UnaryOperator *E,
735 QualType PromotionType = QualType());
736 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
738 Value *VisitUnaryNot (
const UnaryOperator *E);
739 Value *VisitUnaryLNot (
const UnaryOperator *E);
740 Value *VisitUnaryReal(
const UnaryOperator *E,
741 QualType PromotionType = QualType());
742 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
743 Value *VisitUnaryImag(
const UnaryOperator *E,
744 QualType PromotionType = QualType());
745 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
746 Value *VisitUnaryExtension(
const UnaryOperator *E) {
751 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
752 return EmitLoadOfLValue(E);
754 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
762 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
763 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
766 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
767 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
770 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
774 Value *VisitExprWithCleanups(ExprWithCleanups *E);
775 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
778 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
783 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
785 return llvm::ConstantInt::get(ConvertType(E->
getType()),
788 return llvm::ConstantInt::get(ConvertType(E->
getType()),
792 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
800 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
801 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
804 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
805 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
808 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
818 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
819 return EmitNullValue(E->
getType());
822 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
827 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
828 return Builder.getInt1(E->
getValue());
832 Value *EmitMul(
const BinOpInfo &Ops) {
833 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
834 Ops.Ty->isUnsignedIntegerType()) {
835 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
837 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
838 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
839 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
840 case LangOptions::OB_Wrap:
841 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
842 case LangOptions::OB_SignedAndDefined:
844 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
846 case LangOptions::OB_Unset:
848 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
849 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
851 case LangOptions::OB_Trap:
852 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
853 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
854 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
855 return EmitOverflowCheckedBinOp(Ops);
859 if (Ops.Ty->isConstantMatrixType()) {
860 llvm::MatrixBuilder MB(Builder);
864 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
865 BO->getLHS()->getType().getCanonicalType());
866 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
867 BO->getRHS()->getType().getCanonicalType());
868 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
869 if (LHSMatTy && RHSMatTy)
870 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
871 LHSMatTy->getNumColumns(),
872 RHSMatTy->getNumColumns());
873 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
876 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
878 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
879 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
881 if (Ops.isFixedPointOp())
882 return EmitFixedPointBinOp(Ops);
883 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
887 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
890 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
891 llvm::Value *
Zero,
bool isDiv);
893 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
899 Value *EmitDiv(
const BinOpInfo &Ops);
900 Value *EmitRem(
const BinOpInfo &Ops);
901 Value *EmitAdd(
const BinOpInfo &Ops);
902 Value *EmitSub(
const BinOpInfo &Ops);
903 Value *EmitShl(
const BinOpInfo &Ops);
904 Value *EmitShr(
const BinOpInfo &Ops);
905 Value *EmitAnd(
const BinOpInfo &Ops) {
906 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
908 Value *EmitXor(
const BinOpInfo &Ops) {
909 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
911 Value *EmitOr (
const BinOpInfo &Ops) {
912 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
916 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
918 BinOpInfo EmitBinOps(
const BinaryOperator *E,
919 QualType PromotionTy = QualType());
921 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
922 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
923 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
925 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
926 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
929 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
930 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
932 QualType getPromotionType(QualType Ty) {
934 if (
auto *CT = Ty->
getAs<ComplexType>()) {
935 QualType ElementType = CT->getElementType();
941 if (
auto *VT = Ty->
getAs<VectorType>()) {
942 unsigned NumElements = VT->getNumElements();
952#define HANDLEBINOP(OP) \
953 Value *VisitBin##OP(const BinaryOperator *E) { \
954 QualType promotionTy = getPromotionType(E->getType()); \
955 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
956 if (result && !promotionTy.isNull()) \
957 result = EmitUnPromotedValue(result, E->getType()); \
960 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
961 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
962 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
978 llvm::CmpInst::Predicate SICmpOpc,
979 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
980#define VISITCOMP(CODE, UI, SI, FP, SIG) \
981 Value *VisitBin##CODE(const BinaryOperator *E) { \
982 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
983 llvm::FCmpInst::FP, SIG); }
984 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
998 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
999 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1001 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1006 Value *VisitBlockExpr(
const BlockExpr *BE);
1007 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1008 Value *VisitChooseExpr(ChooseExpr *CE);
1009 Value *VisitVAArgExpr(VAArgExpr *VE);
1010 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1013 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1016 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1019 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1022 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1023 Value *VisitAtomicExpr(AtomicExpr *AE);
1024 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1037 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1040 return EmitFloatToBoolConversion(Src);
1042 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1046 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1050 "Unknown scalar type to convert");
1053 return EmitIntToBoolConversion(Src);
1056 return EmitPointerToBoolConversion(Src, SrcType);
1059void ScalarExprEmitter::EmitFloatConversionCheck(
1060 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1061 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1062 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1066 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1067 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1068 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1069 using llvm::APFloat;
1072 llvm::Value *Check =
nullptr;
1073 const llvm::fltSemantics &SrcSema =
1083 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1084 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1085 APFloat::opOverflow)
1088 MinSrc = APFloat::getInf(SrcSema,
true);
1092 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1095 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1096 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1097 APFloat::opOverflow)
1100 MaxSrc = APFloat::getInf(SrcSema,
false);
1104 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1109 const llvm::fltSemantics &Sema =
1112 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1113 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1117 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1119 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1120 Check = Builder.CreateAnd(GE, LE);
1125 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1131static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1132 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1135 llvm::Type *SrcTy = Src->
getType();
1136 llvm::Type *DstTy = Dst->
getType();
1141 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1143 "non-integer llvm type");
1150 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1152 if (!SrcSigned && !DstSigned) {
1153 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1154 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1156 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1157 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1160 llvm::Value *Check =
nullptr;
1162 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1164 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1166 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1174void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1175 Value *Dst, QualType DstType,
1177 bool OBTrapInvolved) {
1178 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1188 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1189 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1191 if (SrcBits <= DstBits)
1194 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1201 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1202 (!SrcSigned && DstSigned))
1205 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1206 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1209 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1214 SanitizerDebugLocation SanScope(
1216 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1217 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1233 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1241 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1242 if (OBT->isWrapKind())
1245 if (ignoredBySanitizer && !OBTrapInvolved)
1248 llvm::Constant *StaticArgs[] = {
1251 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1252 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1254 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1261 llvm::Type *VTy =
V->getType();
1264 return llvm::ConstantInt::getFalse(VTy->getContext());
1266 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1267 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1268 llvm::Twine(Name) +
"." +
V->getName() +
1269 ".negativitycheck");
1274static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1275 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1278 llvm::Type *SrcTy = Src->
getType();
1279 llvm::Type *DstTy = Dst->
getType();
1282 "non-integer llvm type");
1288 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1289 unsigned DstBits = DstTy->getScalarSizeInBits();
1293 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1294 "either the widths should be different, or the signednesses.");
1297 llvm::Value *SrcIsNegative =
1300 llvm::Value *DstIsNegative =
1306 llvm::Value *Check =
nullptr;
1307 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1309 return std::make_pair(
1310 ScalarExprEmitter::ICCK_IntegerSignChange,
1311 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1314void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1315 Value *Dst, QualType DstType,
1317 bool OBTrapInvolved) {
1318 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1322 llvm::Type *SrcTy = Src->
getType();
1323 llvm::Type *DstTy = Dst->
getType();
1333 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1334 unsigned DstBits = DstTy->getScalarSizeInBits();
1341 if (SrcSigned == DstSigned && SrcBits == DstBits)
1345 if (!SrcSigned && !DstSigned)
1350 if ((DstBits > SrcBits) && DstSigned)
1352 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1353 (SrcBits > DstBits) && SrcSigned) {
1362 if (!OBTrapInvolved) {
1365 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1369 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1374 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1375 SanitizerDebugLocation SanScope(
1377 {SanitizerKind::SO_ImplicitIntegerSignChange,
1378 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1379 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1382 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1383 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1387 ImplicitConversionCheckKind CheckKind;
1388 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1395 CheckKind = Check.first;
1396 Checks.emplace_back(Check.second);
1398 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1399 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1405 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1406 Checks.emplace_back(Check.second);
1410 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1411 if (OBTrapInvolved) {
1412 llvm::Value *Combined = Check.second.first;
1413 for (
const auto &
C : Checks)
1414 Combined = Builder.CreateAnd(Combined,
C.first);
1420 llvm::Constant *StaticArgs[] = {
1423 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1424 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1426 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1431static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1432 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1438 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1439 if (!SrcSigned && !DstSigned)
1440 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1442 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1444 llvm::Value *Check =
nullptr;
1446 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1448 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1451 return std::make_pair(
1453 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1458static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1459 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1463 llvm::Value *SrcIsNegative =
1466 llvm::Value *DstIsNegative =
1472 llvm::Value *Check =
nullptr;
1474 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1476 return std::make_pair(
1477 ScalarExprEmitter::ICCK_IntegerSignChange,
1478 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1486 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1504 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1505 unsigned DstBits = Info.
Size;
1510 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1512 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1514 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1515 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1519 bool EmitTruncation = DstBits < SrcBits;
1523 bool EmitTruncationFromUnsignedToSigned =
1524 EmitTruncation && DstSigned && !SrcSigned;
1526 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1527 bool BothUnsigned = !SrcSigned && !DstSigned;
1528 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1535 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1540 else if (EmitSignChange) {
1541 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1542 "either the widths should be different, or the signednesses.");
1548 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1549 if (EmitTruncationFromUnsignedToSigned)
1550 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1552 llvm::Constant *StaticArgs[] = {
1555 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1556 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1558 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1562 QualType DstType, llvm::Type *SrcTy,
1564 ScalarConversionOpts Opts) {
1566 llvm::Type *SrcElementTy;
1567 llvm::Type *DstElementTy;
1577 "cannot cast between matrix and non-matrix types");
1578 SrcElementTy = SrcTy;
1579 DstElementTy = DstTy;
1580 SrcElementType = SrcType;
1581 DstElementType = DstType;
1586 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1591 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1593 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1594 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1598 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1605 llvm::Intrinsic::ID IID =
1606 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1607 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1611 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1612 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1615 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1616 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1617 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1619 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1620 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1621 return Builder.CreateFPExt(Src, DstTy,
"conv");
1626Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1629 ScalarConversionOpts Opts) {
1644 return Builder.CreateIsNotNull(Src,
"tobool");
1647 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1650 "Unhandled scalar conversion from a fixed point type to another type.");
1654 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1657 "Unhandled scalar conversion to a fixed point type from another type.");
1660 QualType NoncanonicalSrcType = SrcType;
1661 QualType NoncanonicalDstType = DstType;
1665 if (SrcType == DstType)
return Src;
1669 llvm::Value *OrigSrc = Src;
1670 QualType OrigSrcType = SrcType;
1671 llvm::Type *SrcTy = Src->
getType();
1675 return EmitConversionToBool(Src, SrcType);
1677 llvm::Type *DstTy = ConvertType(DstType);
1686 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1687 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1688 bool OBTrapInvolved =
1689 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1690 bool OBWrapInvolved =
1691 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1696 if (DstTy->isFloatingPointTy())
1697 return Builder.CreateFPExt(Src, DstTy,
"conv");
1701 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1707 if (SrcTy == DstTy) {
1708 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1709 (OBTrapInvolved && !OBWrapInvolved))
1710 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1711 NoncanonicalDstType, Loc, OBTrapInvolved);
1719 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1724 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1729 llvm::Value* IntResult =
1730 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1732 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1738 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1745 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1747 "Splatted expr doesn't match with vector element type?");
1751 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1755 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1759 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1760 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1761 if (SrcSize == DstSize)
1762 return Builder.CreateBitCast(Src, DstTy,
"conv");
1775 assert(((SrcElementTy->isIntegerTy() &&
1776 DstElementTy->isIntegerTy()) ||
1777 (SrcElementTy->isFloatingPointTy() &&
1778 DstElementTy->isFloatingPointTy())) &&
1779 "unexpected conversion between a floating-point vector and an "
1783 if (SrcElementTy->isIntegerTy())
1784 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1787 if (SrcSize > DstSize)
1788 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1791 return Builder.CreateFPExt(Src, DstTy,
"conv");
1795 Value *Res =
nullptr;
1796 llvm::Type *ResTy = DstTy;
1803 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1805 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1813 if (SrcTy->isFloatingPointTy())
1814 return Builder.CreateFPTrunc(Src, CGF.
CGM.
HalfTy,
"conv");
1819 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1821 if (DstTy != ResTy) {
1822 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1825 assert(ResTy->isIntegerTy(16) &&
1826 "Only half FP requires extra conversion");
1827 Res = Builder.CreateBitCast(Res, ResTy);
1831 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1832 !OBWrapInvolved && !Opts.PatternExcluded)
1833 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1834 NoncanonicalDstType, Loc, OBTrapInvolved);
1836 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1837 (OBTrapInvolved && !OBWrapInvolved))
1838 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1839 NoncanonicalDstType, Loc, OBTrapInvolved);
1844Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1846 SourceLocation Loc) {
1847 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1850 Result = FPBuilder.CreateFloatingToFixed(Src,
1853 Result = FPBuilder.CreateFixedToFloating(Src,
1855 ConvertType(DstTy));
1861 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1862 DstFPSema.getWidth(),
1863 DstFPSema.isSigned());
1865 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1868 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1875Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1877 SourceLocation Loc) {
1879 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1884 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1885 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1886 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1893 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1896Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1904void ScalarExprEmitter::EmitBinOpCheck(
1905 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1906 const BinOpInfo &Info) {
1909 SmallVector<llvm::Constant *, 4> StaticData;
1910 SmallVector<llvm::Value *, 2> DynamicData;
1918 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1919 if (UO && UO->
getOpcode() == UO_Minus) {
1920 Check = SanitizerHandler::NegateOverflow;
1922 DynamicData.push_back(Info.RHS);
1926 Check = SanitizerHandler::ShiftOutOfBounds;
1928 StaticData.push_back(
1930 StaticData.push_back(
1932 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1934 Check = SanitizerHandler::DivremOverflow;
1938 int ArithOverflowKind = 0;
1941 Check = SanitizerHandler::AddOverflow;
1942 ArithOverflowKind = diag::UBSanArithKind::Add;
1946 Check = SanitizerHandler::SubOverflow;
1947 ArithOverflowKind = diag::UBSanArithKind::Sub;
1951 Check = SanitizerHandler::MulOverflow;
1952 ArithOverflowKind = diag::UBSanArithKind::Mul;
1956 llvm_unreachable(
"unexpected opcode for bin op check");
1960 SanitizerKind::UnsignedIntegerOverflow) ||
1962 SanitizerKind::SignedIntegerOverflow)) {
1966 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1970 DynamicData.push_back(Info.LHS);
1971 DynamicData.push_back(Info.RHS);
1974 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1981Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1989ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1991 unsigned AddrSpace =
1993 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1996 llvm::Type *ExprTy = ConvertType(E->
getType());
1997 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2001Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2003 auto It = E->
begin();
2004 return Builder.getInt((*It)->getValue());
2007Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2015 unsigned LHSElts = LTy->getNumElements();
2023 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2024 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2032 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2033 MTy->getNumElements());
2034 Value* NewV = llvm::PoisonValue::get(RTy);
2035 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2036 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2037 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2039 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2040 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2048 SmallVector<int, 32> Indices;
2052 if (Idx.isSigned() && Idx.isAllOnes())
2053 Indices.push_back(-1);
2055 Indices.push_back(Idx.getZExtValue());
2058 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2061Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2069 if (SrcType == DstType)
return Src;
2072 "ConvertVector source type must be a vector");
2074 "ConvertVector destination type must be a vector");
2076 llvm::Type *SrcTy = Src->
getType();
2077 llvm::Type *DstTy = ConvertType(DstType);
2083 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2084 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2086 assert(SrcTy->isVectorTy() &&
2087 "ConvertVector source IR type must be a vector");
2088 assert(DstTy->isVectorTy() &&
2089 "ConvertVector destination IR type must be a vector");
2094 if (DstEltType->isBooleanType()) {
2095 assert((SrcEltTy->isFloatingPointTy() ||
2098 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2099 if (SrcEltTy->isFloatingPointTy()) {
2100 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2101 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2103 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2108 Value *Res =
nullptr;
2113 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2115 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2117 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2119 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2122 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2123 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2124 if (DstEltType->isSignedIntegerOrEnumerationType())
2125 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2127 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2129 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2130 "Unknown real conversion");
2131 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2132 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2133 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2135 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2141Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2150 return Builder.getInt(
Value);
2154 llvm::Value *
Result = EmitLoadOfLValue(E);
2160 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2161 if (llvm::GetElementPtrInst *GEP =
2162 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2163 if (llvm::Instruction *
Pointer =
2164 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2176Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2177 TestAndClearIgnoreResultAssign();
2185 return EmitLoadOfLValue(E);
2193 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2196 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2200 Ret = Builder.CreateInsertElement(
2201 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2207Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2208 MatrixSingleSubscriptExpr *E) {
2209 TestAndClearIgnoreResultAssign();
2212 unsigned NumRows = MatrixTy->getNumRows();
2213 unsigned NumColumns = MatrixTy->getNumColumns();
2217 llvm::MatrixBuilder MB(Builder);
2221 MB.CreateIndexAssumption(RowIdx, NumRows);
2225 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2226 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2228 bool IsMatrixRowMajor =
2231 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2232 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2233 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2234 IsMatrixRowMajor,
"matrix_row_idx");
2236 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2237 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2238 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2244Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2245 TestAndClearIgnoreResultAssign();
2253 llvm::MatrixBuilder MB(Builder);
2256 unsigned NumCols = MatrixTy->getNumColumns();
2257 unsigned NumRows = MatrixTy->getNumRows();
2258 bool IsMatrixRowMajor =
2260 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2263 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2268 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2273 int MV = SVI->getMaskValue(Idx);
2280 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2281 "Index operand too large for shufflevector mask!");
2282 return C->getZExtValue();
2285Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2286 bool Ignore = TestAndClearIgnoreResultAssign();
2289 assert((Ignore ==
false ||
2291 "init list ignored");
2308 llvm::VectorType *VType =
2309 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2312 if (NumInitElements == 0) {
2314 return EmitNullValue(E->
getType());
2321 if (NumInitElements == 0) {
2323 return EmitNullValue(E->
getType());
2326 if (NumInitElements == 1) {
2327 Expr *InitVector = E->
getInit(0);
2332 return Visit(InitVector);
2335 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2342 const ConstantMatrixType *ColMajorMT =
nullptr;
2343 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2352 unsigned CurIdx = 0;
2353 bool VIsPoisonShuffle =
false;
2354 llvm::Value *
V = llvm::PoisonValue::get(VType);
2355 for (
unsigned i = 0; i != NumInitElements; ++i) {
2358 SmallVector<int, 16> Args;
2360 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2370 ->getNumElements() == ResElts) {
2372 Value *LHS =
nullptr, *RHS =
nullptr;
2377 Args.resize(ResElts, -1);
2379 LHS = EI->getVectorOperand();
2381 VIsPoisonShuffle =
true;
2382 }
else if (VIsPoisonShuffle) {
2385 for (
unsigned j = 0; j != CurIdx; ++j)
2387 Args.push_back(ResElts +
C->getZExtValue());
2388 Args.resize(ResElts, -1);
2391 RHS = EI->getVectorOperand();
2392 VIsPoisonShuffle =
false;
2394 if (!Args.empty()) {
2395 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2401 unsigned InsertIdx =
2405 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2407 VIsPoisonShuffle =
false;
2417 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2420 Value *SVOp = SVI->getOperand(0);
2423 if (OpTy->getNumElements() == ResElts) {
2424 for (
unsigned j = 0; j != CurIdx; ++j) {
2427 if (VIsPoisonShuffle) {
2433 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2435 Args.resize(ResElts, -1);
2437 if (VIsPoisonShuffle)
2447 for (
unsigned j = 0; j != InitElts; ++j)
2449 Args.resize(ResElts, -1);
2450 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2453 for (
unsigned j = 0; j != CurIdx; ++j)
2455 for (
unsigned j = 0; j != InitElts; ++j)
2456 Args.push_back(j + Offset);
2457 Args.resize(ResElts, -1);
2464 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2471 llvm::Type *EltTy = VType->getElementType();
2474 for (; CurIdx < ResElts; ++CurIdx) {
2475 unsigned InsertIdx =
2478 Value *Idx = Builder.getInt32(InsertIdx);
2479 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2480 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2493 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2497 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2500 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2519 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2523 if (
const auto *CE = dyn_cast<CastExpr>(E))
2524 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2525 CE->getCastKind() == CK_ArrayToPointerDecay)
2536 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2546 if (ICE->isGLValue())
2561 assert(LoadList.size() >= VecTy->getNumElements() &&
2562 "Flattened type on RHS must have the same number or more elements "
2563 "than vector on LHS.");
2567 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2570 "All flattened source values should be scalars.");
2573 VecTy->getElementType(), Loc);
2574 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2579 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2580 "Flattened type on RHS must have the same number or more elements "
2581 "than vector on LHS.");
2588 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2589 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2592 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2595 "All flattened source values should be scalars.");
2598 MatTy->getElementType(), Loc);
2599 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2600 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2607 "Destination type must be a vector, matrix, or builtin type.");
2609 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2618 llvm::scope_exit RestoreCurCast(
2619 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2623 QualType DestTy = CE->
getType();
2625 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2629 bool Ignored = TestAndClearIgnoreResultAssign();
2635 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2636 case CK_BuiltinFnToFnPtr:
2637 llvm_unreachable(
"builtin functions are handled elsewhere");
2639 case CK_LValueBitCast:
2640 case CK_ObjCObjectLValueCast: {
2644 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2647 case CK_LValueToRValueBitCast: {
2653 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2656 case CK_CPointerToObjCPointerCast:
2657 case CK_BlockPointerToObjCPointerCast:
2658 case CK_AnyPointerToBlockPointerCast:
2660 Value *Src = Visit(E);
2661 llvm::Type *SrcTy = Src->
getType();
2662 llvm::Type *DstTy = ConvertType(DestTy);
2673 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2687 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2688 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2693 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2694 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2695 "Address-space cast must be used to convert address spaces");
2697 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2698 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2700 PT->getPointeeType(),
2711 const QualType SrcType = E->
getType();
2716 Src = Builder.CreateLaunderInvariantGroup(Src);
2724 Src = Builder.CreateStripInvariantGroup(Src);
2729 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2733 if (!PointeeType.
isNull())
2742 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2743 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2746 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2747 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2748 ScalableDstTy = llvm::ScalableVectorType::get(
2749 FixedSrcTy->getElementType(),
2751 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2753 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2754 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2755 llvm::Value *
Result = Builder.CreateInsertVector(
2756 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2758 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2759 if (
Result->getType() != ScalableDstTy)
2761 if (
Result->getType() != DstTy)
2771 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2772 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2775 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2776 FixedDstTy->getElementType()->isIntegerTy(8)) {
2777 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2778 ScalableSrcTy = llvm::ScalableVectorType::get(
2779 ScalableSrcTy->getElementType(),
2781 ScalableSrcTy->getElementCount().getKnownMinValue()));
2782 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2783 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2787 ScalableSrcTy = llvm::ScalableVectorType::get(
2788 FixedDstTy->getElementType(),
2789 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2790 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2792 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2793 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2814 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2817 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2820 case CK_AddressSpaceConversion: {
2821 llvm::Type *DestLTy = ConvertType(DestTy);
2824 auto IsWasmFuncref = [](llvm::Type *T) {
2825 auto *TET = dyn_cast<llvm::TargetExtType>(T);
2826 return TET && TET->getName() ==
"wasm.funcref";
2828 bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->
getType()));
2829 bool DestIsFuncref = IsWasmFuncref(DestLTy);
2830 if (SrcIsFuncref && DestIsFuncref) {
2835 if (SrcIsFuncref && !DestIsFuncref) {
2839 llvm::Function *ToPtr =
2841 return CGF.
Builder.CreateCall(ToPtr, {Visit(E)});
2843 if (!SrcIsFuncref && DestIsFuncref) {
2846 Expr::EvalResult NullResult;
2851 return llvm::Constant::getNullValue(DestLTy);
2854 llvm::Function *ToFuncref =
2856 return CGF.
Builder.CreateCall(ToFuncref, {Visit(E)});
2860 Result.Val.isNullPointer()) {
2864 if (
Result.HasSideEffects)
2872 case CK_AtomicToNonAtomic:
2873 case CK_NonAtomicToAtomic:
2874 case CK_UserDefinedConversion:
2881 case CK_BaseToDerived: {
2883 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2897 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2905 case CK_UncheckedDerivedToBase:
2906 case CK_DerivedToBase: {
2919 case CK_ArrayToPointerDecay:
2922 case CK_FunctionToPointerDecay:
2923 return EmitLValue(E).getPointer(CGF);
2925 case CK_NullToPointer:
2926 if (MustVisitNullValue(E))
2932 case CK_NullToMemberPointer: {
2933 if (MustVisitNullValue(E))
2936 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2940 case CK_ReinterpretMemberPointer:
2941 case CK_BaseToDerivedMemberPointer:
2942 case CK_DerivedToBaseMemberPointer: {
2943 Value *Src = Visit(E);
2954 case CK_ARCProduceObject:
2956 case CK_ARCConsumeObject:
2958 case CK_ARCReclaimReturnedObject:
2960 case CK_ARCExtendBlockObject:
2963 case CK_CopyAndAutoreleaseBlockObject:
2966 case CK_FloatingRealToComplex:
2967 case CK_FloatingComplexCast:
2968 case CK_IntegralRealToComplex:
2969 case CK_IntegralComplexCast:
2970 case CK_IntegralComplexToFloatingComplex:
2971 case CK_FloatingComplexToIntegralComplex:
2972 case CK_ConstructorConversion:
2974 case CK_HLSLArrayRValue:
2975 llvm_unreachable(
"scalar cast to non-scalar value");
2977 case CK_LValueToRValue:
2979 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2982 case CK_IntegralToPointer: {
2983 Value *Src = Visit(E);
2987 auto DestLLVMTy = ConvertType(DestTy);
2990 llvm::Value* IntResult =
2991 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2993 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2999 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
3005 case CK_PointerToIntegral: {
3006 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
3007 auto *PtrExpr = Visit(E);
3010 const QualType SrcType = E->
getType();
3015 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
3019 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3025 case CK_MatrixCast: {
3026 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3033 case CK_HLSLAggregateSplatCast:
3034 case CK_VectorSplat: {
3035 llvm::Type *DstTy = ConvertType(DestTy);
3036 Value *Elt = Visit(E);
3038 llvm::ElementCount NumElements =
3040 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3043 case CK_FixedPointCast:
3044 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3047 case CK_FixedPointToBoolean:
3049 "Expected src type to be fixed point type");
3050 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3051 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3054 case CK_FixedPointToIntegral:
3056 "Expected src type to be fixed point type");
3057 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3058 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3061 case CK_IntegralToFixedPoint:
3063 "Expected src type to be an integer");
3065 "Expected dest type to be fixed point type");
3066 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3069 case CK_IntegralCast: {
3071 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3072 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3076 ScalarConversionOpts Opts;
3077 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3078 if (!ICE->isPartOfExplicitCast())
3079 Opts = ScalarConversionOpts(CGF.
SanOpts);
3081 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3084 case CK_IntegralToFloating: {
3087 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3089 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3090 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3092 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3093 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3096 case CK_FloatingToIntegral: {
3099 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3101 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3102 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3104 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3105 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3108 case CK_FloatingCast: {
3111 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3112 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3113 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3114 SrcElTy->
castAs<BuiltinType>()->getKind())
3115 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3116 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3118 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3119 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3122 case CK_FixedPointToFloating:
3123 case CK_FloatingToFixedPoint: {
3124 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3125 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3128 case CK_BooleanToSignedIntegral: {
3129 ScalarConversionOpts Opts;
3130 Opts.TreatBooleanAsSigned =
true;
3131 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3134 case CK_IntegralToBoolean:
3135 return EmitIntToBoolConversion(Visit(E));
3136 case CK_PointerToBoolean:
3137 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3138 case CK_FloatingToBoolean: {
3139 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3140 return EmitFloatToBoolConversion(Visit(E));
3142 case CK_MemberPointerToBoolean: {
3143 llvm::Value *MemPtr = Visit(E);
3144 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3148 case CK_FloatingComplexToReal:
3149 case CK_IntegralComplexToReal:
3152 case CK_FloatingComplexToBoolean:
3153 case CK_IntegralComplexToBoolean: {
3157 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3161 case CK_ZeroToOCLOpaqueType: {
3164 "CK_ZeroToOCLEvent cast on non-event type");
3165 return llvm::Constant::getNullValue(ConvertType(DestTy));
3168 case CK_IntToOCLSampler:
3171 case CK_HLSLVectorTruncation: {
3173 "Destination type must be a vector or builtin type.");
3174 Value *Vec = Visit(E);
3175 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3176 SmallVector<int> Mask;
3177 unsigned NumElts = VecTy->getNumElements();
3178 for (
unsigned I = 0; I != NumElts; ++I)
3181 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3183 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3184 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3186 case CK_HLSLMatrixTruncation: {
3188 "Destination type must be a matrix or builtin type.");
3189 Value *Mat = Visit(E);
3190 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3191 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3192 unsigned NumCols = MatTy->getNumColumns();
3193 unsigned NumRows = MatTy->getNumRows();
3194 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3195 assert(SrcMatTy &&
"Source type must be a matrix type.");
3196 assert(NumRows <= SrcMatTy->getNumRows());
3197 assert(NumCols <= SrcMatTy->getNumColumns());
3204 for (
unsigned R = 0;
R < NumRows;
R++)
3205 for (
unsigned C = 0;
C < NumCols;
C++)
3206 Mask[MatTy->getFlattenedIndex(R,
C, IsDstRowMajor)] =
3207 SrcMatTy->getFlattenedIndex(R,
C, IsSrcRowMajor);
3209 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3211 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3212 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3214 case CK_HLSLElementwiseCast: {
3234 llvm_unreachable(
"unknown scalar cast");
3237Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3238 CodeGenFunction::StmtExprEvaluation eval(CGF);
3247Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3248 CodeGenFunction::RunCleanupsScope Scope(CGF);
3252 Scope.ForceCleanup({&
V});
3261 llvm::Value *InVal,
bool IsInc,
3265 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3267 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3268 BinOp.FPFeatures = FPFeatures;
3273llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3274 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3277 llvm::Value *Amount =
3278 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3279 StringRef Name = IsInc ?
"inc" :
"dec";
3283 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3284 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3286 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3287 case LangOptions::OB_Wrap:
3288 return Builder.CreateAdd(InVal, Amount, Name);
3289 case LangOptions::OB_SignedAndDefined:
3291 return Builder.CreateAdd(InVal, Amount, Name);
3293 case LangOptions::OB_Unset:
3295 return Builder.CreateAdd(InVal, Amount, Name);
3297 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3298 : Builder.CreateAdd(InVal, Amount, Name);
3300 case LangOptions::OB_Trap:
3302 return Builder.CreateAdd(InVal, Amount, Name);
3305 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3306 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3307 : Builder.CreateAdd(InVal, Amount, Name);
3308 return EmitOverflowCheckedBinOp(Info);
3310 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3315class OMPLastprivateConditionalUpdateRAII {
3317 CodeGenFunction &CGF;
3318 const UnaryOperator *E;
3321 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3322 const UnaryOperator *E)
3324 ~OMPLastprivateConditionalUpdateRAII() {
3333ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3334 bool isInc,
bool isPre) {
3336 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3338 llvm::PHINode *atomicPHI =
nullptr;
3342 QualType SrcType = E->
getType();
3344 int amount = (isInc ? 1 : -1);
3345 bool isSubtraction = !isInc;
3347 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3348 type = atomicTy->getValueType();
3349 if (isInc &&
type->isBooleanType()) {
3352 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3353 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3354 return Builder.getTrue();
3358 return Builder.CreateAtomicRMW(
3359 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3360 llvm::AtomicOrdering::SequentiallyConsistent);
3365 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3366 !(
type->isUnsignedIntegerType() &&
3367 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3369 LangOptions::SOB_Trapping) {
3370 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3371 llvm::AtomicRMWInst::Sub;
3372 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3373 llvm::Instruction::Sub;
3375 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3377 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3378 llvm::AtomicOrdering::SequentiallyConsistent);
3379 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3383 if (
type->isFloatingType()) {
3384 llvm::Type *Ty = ConvertType(
type);
3385 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3386 llvm::AtomicRMWInst::BinOp aop =
3387 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3388 llvm::Instruction::BinaryOps op =
3389 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3390 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3391 llvm::AtomicRMWInst *old =
3393 llvm::AtomicOrdering::SequentiallyConsistent);
3395 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3398 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3401 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3404 Builder.CreateBr(opBB);
3405 Builder.SetInsertPoint(opBB);
3406 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3407 atomicPHI->addIncoming(value, startBB);
3410 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3421 if (isInc &&
type->isBooleanType()) {
3422 value = Builder.getTrue();
3425 }
else if (
type->isIntegerType()) {
3426 QualType promotedType;
3427 bool canPerformLossyDemotionCheck =
false;
3431 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3432 canPerformLossyDemotionCheck =
true;
3433 canPerformLossyDemotionCheck &=
3436 canPerformLossyDemotionCheck &=
3438 type, promotedType);
3439 assert((!canPerformLossyDemotionCheck ||
3440 type->isSignedIntegerOrEnumerationType() ||
3442 ConvertType(
type)->getScalarSizeInBits() ==
3443 ConvertType(promotedType)->getScalarSizeInBits()) &&
3444 "The following check expects that if we do promotion to different "
3445 "underlying canonical type, at least one of the types (either "
3446 "base or promoted) will be signed, or the bitwidths will match.");
3449 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3450 SanitizerKind::ImplicitBitfieldConversion) &&
3451 canPerformLossyDemotionCheck) {
3465 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3466 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3467 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3471 ScalarConversionOpts Opts;
3472 if (!LV.isBitField())
3473 Opts = ScalarConversionOpts(CGF.
SanOpts);
3474 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3476 SrcType = promotedType;
3480 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3486 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3487 type->isUnsignedIntegerType()) {
3488 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3493 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3494 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3498 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3499 QualType
type = ptr->getPointeeType();
3502 if (
const VariableArrayType *vla
3505 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3508 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3511 elemTy, value, numElts,
false, isSubtraction,
3515 }
else if (
type->isFunctionType()) {
3516 llvm::Value *amt = Builder.getInt32(amount);
3519 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3523 false, isSubtraction,
3528 llvm::Value *amt = Builder.getInt32(amount);
3531 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3534 elemTy, value, amt,
false, isSubtraction,
3539 }
else if (
type->isVectorType()) {
3540 if (
type->hasIntegerRepresentation()) {
3541 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3543 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3545 value = Builder.CreateFAdd(
3547 llvm::ConstantFP::get(value->getType(), amount),
3548 isInc ?
"inc" :
"dec");
3552 }
else if (
type->isRealFloatingType()) {
3555 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3561 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3564 if (value->getType()->isFloatTy())
3565 amt = llvm::ConstantFP::get(VMContext,
3566 llvm::APFloat(
static_cast<float>(amount)));
3567 else if (value->getType()->isDoubleTy())
3568 amt = llvm::ConstantFP::get(VMContext,
3569 llvm::APFloat(
static_cast<double>(amount)));
3573 llvm::APFloat F(
static_cast<float>(amount));
3575 const llvm::fltSemantics *FS;
3578 if (value->getType()->isFP128Ty())
3580 else if (value->getType()->isHalfTy())
3582 else if (value->getType()->isBFloatTy())
3584 else if (value->getType()->isPPC_FP128Ty())
3588 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3589 amt = llvm::ConstantFP::get(VMContext, F);
3591 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3594 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3595 value = Builder.CreateBitCast(value, input->getType());
3599 }
else if (
type->isFixedPointType()) {
3606 Info.Opcode = isInc ? BO_Add : BO_Sub;
3608 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3611 if (
type->isSignedFixedPointType()) {
3612 Info.Opcode = isInc ? BO_Sub : BO_Add;
3613 Info.RHS = Builder.CreateNeg(Info.RHS);
3618 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3620 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3621 value = EmitFixedPointBinOp(Info);
3625 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3628 if (!isInc) size = -size;
3629 llvm::Value *sizeValue =
3630 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3633 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3636 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3638 value = Builder.CreateBitCast(value, input->getType());
3642 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3647 llvm::Value *
success = Pair.second;
3648 atomicPHI->addIncoming(old, curBlock);
3649 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3650 Builder.SetInsertPoint(contBB);
3651 return isPre ? value : input;
3655 if (LV.isBitField()) {
3665 return isPre ? value : input;
3669Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3670 QualType PromotionType) {
3671 QualType promotionTy = PromotionType.
isNull()
3674 Value *result = VisitPlus(E, promotionTy);
3675 if (result && !promotionTy.
isNull())
3676 result = EmitUnPromotedValue(result, E->
getType());
3680Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3681 QualType PromotionType) {
3683 TestAndClearIgnoreResultAssign();
3684 if (!PromotionType.
isNull())
3689Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3690 QualType PromotionType) {
3691 QualType promotionTy = PromotionType.
isNull()
3694 Value *result = VisitMinus(E, promotionTy);
3695 if (result && !promotionTy.
isNull())
3696 result = EmitUnPromotedValue(result, E->
getType());
3700Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3701 QualType PromotionType) {
3702 TestAndClearIgnoreResultAssign();
3704 if (!PromotionType.
isNull())
3710 if (Op->
getType()->isFPOrFPVectorTy())
3711 return Builder.CreateFNeg(Op,
"fneg");
3716 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3718 BinOp.Opcode = BO_Sub;
3721 return EmitSub(BinOp);
3724Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3725 TestAndClearIgnoreResultAssign();
3727 return Builder.CreateNot(Op,
"not");
3730Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3734 VectorKind::Generic) {
3738 if (Oper->
getType()->isFPOrFPVectorTy()) {
3739 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3741 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3743 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3744 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3753 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3756 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3759Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3761 Expr::EvalResult EVResult;
3764 return Builder.getInt(
Value);
3769 llvm::Type* ResultType = ConvertType(E->
getType());
3770 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3772 for (
unsigned i = 0; i != n; ++i) {
3774 llvm::Value *Offset =
nullptr;
3781 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3788 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3792 Offset = Builder.CreateMul(Idx, ElemSize);
3797 FieldDecl *MemberDecl = ON.
getField();
3807 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3810 CurrentType = MemberDecl->
getType();
3815 llvm_unreachable(
"dependent __builtin_offsetof");
3832 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3844ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3845 const UnaryExprOrTypeTraitExpr *E) {
3848 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3849 if (
const VariableArrayType *VAT =
3854 bool EvaluateExtent =
true;
3855 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3857 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3859 if (EvaluateExtent) {
3870 if (Kind == UETT_CountOf)
3879 if (!eltSize.
isOne())
3882 return VlaSize.NumElts;
3885 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3891 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3892 }
else if (E->
getKind() == UETT_VectorElements) {
3894 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3902Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3903 QualType PromotionType) {
3904 QualType promotionTy = PromotionType.
isNull()
3907 Value *result = VisitReal(E, promotionTy);
3908 if (result && !promotionTy.
isNull())
3909 result = EmitUnPromotedValue(result, E->
getType());
3913Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3914 QualType PromotionType) {
3921 if (!PromotionType.
isNull()) {
3923 Op, IgnoreResultAssign,
true);
3938 if (!PromotionType.
isNull())
3943Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3944 QualType PromotionType) {
3945 QualType promotionTy = PromotionType.
isNull()
3948 Value *result = VisitImag(E, promotionTy);
3949 if (result && !promotionTy.
isNull())
3950 result = EmitUnPromotedValue(result, E->
getType());
3954Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3955 QualType PromotionType) {
3962 if (!PromotionType.
isNull()) {
3964 Op,
true, IgnoreResultAssign);
3968 return result.second
3984 else if (!PromotionType.
isNull())
3988 if (!PromotionType.
isNull())
3989 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3990 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3997Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3998 QualType PromotionType) {
3999 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
4002Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
4003 QualType ExprType) {
4004 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
4007Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
4009 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
4011#define HANDLE_BINOP(OP) \
4013 return Emit##OP(EmitBinOps(BO, PromotionType));
4022 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4025 return VisitImag(UO, PromotionType);
4027 return VisitReal(UO, PromotionType);
4029 return VisitMinus(UO, PromotionType);
4031 return VisitPlus(UO, PromotionType);
4036 auto result = Visit(
const_cast<Expr *
>(E));
4038 if (!PromotionType.
isNull())
4039 return EmitPromotedValue(result, PromotionType);
4041 return EmitUnPromotedValue(result, E->
getType());
4046BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4047 QualType PromotionType) {
4048 TestAndClearIgnoreResultAssign();
4052 if (!PromotionType.
isNull())
4053 Result.Ty = PromotionType;
4062LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4063 const CompoundAssignOperator *E,
4064 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4075 QualType PromotionTypeCR;
4077 if (PromotionTypeCR.
isNull())
4080 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4081 if (!PromotionTypeRHS.
isNull())
4084 OpInfo.RHS = Visit(E->
getRHS());
4085 OpInfo.Ty = PromotionTypeCR;
4092 llvm::PHINode *atomicPHI =
nullptr;
4093 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4094 QualType
type = atomicTy->getValueType();
4095 if (!
type->isBooleanType() &&
type->isIntegerType() &&
4096 !(
type->isUnsignedIntegerType() &&
4097 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4099 LangOptions::SOB_Trapping) {
4100 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4101 llvm::Instruction::BinaryOps Op;
4102 switch (OpInfo.Opcode) {
4104 case BO_MulAssign:
case BO_DivAssign:
4110 AtomicOp = llvm::AtomicRMWInst::Add;
4111 Op = llvm::Instruction::Add;
4114 AtomicOp = llvm::AtomicRMWInst::Sub;
4115 Op = llvm::Instruction::Sub;
4118 AtomicOp = llvm::AtomicRMWInst::And;
4119 Op = llvm::Instruction::And;
4122 AtomicOp = llvm::AtomicRMWInst::Xor;
4123 Op = llvm::Instruction::Xor;
4126 AtomicOp = llvm::AtomicRMWInst::Or;
4127 Op = llvm::Instruction::Or;
4130 llvm_unreachable(
"Invalid compound assignment type");
4132 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4134 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4138 llvm::AtomicRMWInst *OldVal =
4143 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4149 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4151 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4153 Builder.CreateBr(opBB);
4154 Builder.SetInsertPoint(opBB);
4155 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4156 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4157 OpInfo.LHS = atomicPHI;
4160 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4162 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4164 if (!PromotionTypeLHS.
isNull())
4165 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4168 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4179 if (LHSLV.isBitField()) {
4181 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4182 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4184 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4185 Loc, ScalarConversionOpts(CGF.
SanOpts));
4187 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4188 ScalarConversionOpts(CGF.
SanOpts));
4192 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4196 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4197 llvm::Value *
success = Pair.second;
4198 atomicPHI->addIncoming(old, curBlock);
4199 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4200 Builder.SetInsertPoint(contBB);
4208 if (LHSLV.isBitField()) {
4224Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4225 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4226 bool Ignore = TestAndClearIgnoreResultAssign();
4227 Value *RHS =
nullptr;
4228 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4239 if (!LHS.isVolatileQualified())
4243 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4246void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4247 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4248 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4251 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4252 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4253 SanitizerKind::SO_IntegerDivideByZero));
4257 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4258 Ops.Ty->hasSignedIntegerRepresentation() &&
4260 Ops.mayHaveIntegerOverflow() &&
4262 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4265 llvm::Value *IntMin =
4266 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4267 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4269 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4270 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4271 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4273 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4276 if (Checks.size() > 0)
4277 EmitBinOpCheck(Checks, Ops);
4280Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4282 SanitizerDebugLocation SanScope(&CGF,
4283 {SanitizerKind::SO_IntegerDivideByZero,
4284 SanitizerKind::SO_SignedIntegerOverflow,
4285 SanitizerKind::SO_FloatDivideByZero},
4286 SanitizerHandler::DivremOverflow);
4287 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4288 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4289 Ops.Ty->isIntegerType() &&
4290 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4291 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4292 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4293 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4294 Ops.Ty->isRealFloatingType() &&
4295 Ops.mayHaveFloatDivisionByZero()) {
4296 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4297 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4299 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4303 if (Ops.Ty->isConstantMatrixType()) {
4304 llvm::MatrixBuilder MB(Builder);
4311 "first operand must be a matrix");
4313 "second operand must be an arithmetic type");
4314 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4315 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4316 Ops.Ty->hasUnsignedIntegerRepresentation());
4319 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4321 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4322 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4326 else if (Ops.isFixedPointOp())
4327 return EmitFixedPointBinOp(Ops);
4328 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4329 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4331 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4334Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4336 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4337 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4338 Ops.Ty->isIntegerType() &&
4339 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4340 SanitizerDebugLocation SanScope(&CGF,
4341 {SanitizerKind::SO_IntegerDivideByZero,
4342 SanitizerKind::SO_SignedIntegerOverflow},
4343 SanitizerHandler::DivremOverflow);
4344 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4345 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4348 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4349 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4351 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4352 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4354 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4357Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4362 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4363 switch (Ops.Opcode) {
4367 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4368 llvm::Intrinsic::uadd_with_overflow;
4369 OverflowKind = SanitizerHandler::AddOverflow;
4374 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4375 llvm::Intrinsic::usub_with_overflow;
4376 OverflowKind = SanitizerHandler::SubOverflow;
4381 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4382 llvm::Intrinsic::umul_with_overflow;
4383 OverflowKind = SanitizerHandler::MulOverflow;
4386 llvm_unreachable(
"Unsupported operation for overflow detection");
4392 SanitizerDebugLocation SanScope(&CGF,
4393 {SanitizerKind::SO_SignedIntegerOverflow,
4394 SanitizerKind::SO_UnsignedIntegerOverflow},
4400 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4401 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4402 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4405 const std::string *handlerName =
4407 if (handlerName->empty()) {
4413 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4414 llvm::Value *NotOf = Builder.CreateNot(overflow);
4416 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4419 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4422 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4423 llvm::Value *NotOf = Builder.CreateNot(overflow);
4425 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4428 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4433 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4434 llvm::BasicBlock *continueBB =
4438 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4442 Builder.SetInsertPoint(overflowBB);
4445 llvm::Type *Int8Ty = CGF.
Int8Ty;
4446 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4447 llvm::FunctionType *handlerTy =
4448 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4449 llvm::FunctionCallee handler =
4454 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4455 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4459 llvm::Value *handlerArgs[] = {
4462 Builder.getInt8(OpID),
4465 llvm::Value *handlerResult =
4469 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4470 Builder.CreateBr(continueBB);
4472 Builder.SetInsertPoint(continueBB);
4473 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4474 phi->addIncoming(result, initialBB);
4475 phi->addIncoming(handlerResult, overflowBB);
4484 bool isSubtraction) {
4489 Value *pointer = op.LHS;
4490 Expr *pointerOperand =
expr->getLHS();
4492 Expr *indexOperand =
expr->getRHS();
4495 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4496 std::swap(pointer,
index);
4497 std::swap(pointerOperand, indexOperand);
4501 index, isSubtraction);
4507 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4511 auto &DL =
CGM.getDataLayout();
4534 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4536 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4537 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4538 PtrTy->getPointerAddressSpace()))
4541 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4542 auto CheckHandler = SanitizerHandler::PointerOverflow;
4544 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4546 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4547 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4549 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4550 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4555 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4566 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4576 llvm::Value *objectSize =
4582 return Builder.CreateBitCast(result, pointer->getType());
4587 getContext().getAsVariableArrayType(elementType)) {
4589 llvm::Value *numElements =
getVLASize(vla).NumElts;
4598 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4618 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4631 bool negMul,
bool negAdd) {
4632 Value *MulOp0 = MulOp->getOperand(0);
4633 Value *MulOp1 = MulOp->getOperand(1);
4635 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4637 Addend = Builder.CreateFNeg(Addend,
"neg");
4639 Value *FMulAdd =
nullptr;
4640 if (Builder.getIsFPConstrained()) {
4642 "Only constrained operation should be created when Builder is in FP "
4643 "constrained mode");
4644 FMulAdd = Builder.CreateConstrainedFPCall(
4645 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4647 {MulOp0, MulOp1, Addend});
4649 FMulAdd = Builder.CreateCall(
4651 {MulOp0, MulOp1, Addend});
4653 MulOp->eraseFromParent();
4668 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4669 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4670 "Only fadd/fsub can be the root of an fmuladd.");
4673 if (!op.FPFeatures.allowFPContractWithinStatement())
4676 Value *LHS = op.LHS;
4677 Value *RHS = op.RHS;
4681 bool NegLHS =
false;
4682 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4683 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4684 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4685 LHS = LHSUnOp->getOperand(0);
4690 bool NegRHS =
false;
4691 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4692 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4693 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4694 RHS = RHSUnOp->getOperand(0);
4702 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4703 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4704 (LHSBinOp->use_empty() || NegLHS)) {
4708 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4711 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4712 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4713 (RHSBinOp->use_empty() || NegRHS)) {
4717 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4721 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4722 if (LHSBinOp->getIntrinsicID() ==
4723 llvm::Intrinsic::experimental_constrained_fmul &&
4724 (LHSBinOp->use_empty() || NegLHS)) {
4728 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4731 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4732 if (RHSBinOp->getIntrinsicID() ==
4733 llvm::Intrinsic::experimental_constrained_fmul &&
4734 (RHSBinOp->use_empty() || NegRHS)) {
4738 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4745Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4746 if (op.LHS->getType()->isPointerTy() ||
4747 op.RHS->getType()->isPointerTy())
4750 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4751 op.Ty->isUnsignedIntegerType()) {
4752 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4754 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4755 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4756 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4757 case LangOptions::OB_Wrap:
4758 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4759 case LangOptions::OB_SignedAndDefined:
4761 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4763 case LangOptions::OB_Unset:
4765 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4766 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4768 case LangOptions::OB_Trap:
4769 if (CanElideOverflowCheck(CGF.
getContext(), op))
4770 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4771 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4772 return EmitOverflowCheckedBinOp(op);
4777 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4778 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4784 if (op.Ty->isConstantMatrixType()) {
4785 llvm::MatrixBuilder MB(Builder);
4786 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4787 return MB.CreateAdd(op.LHS, op.RHS);
4790 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4791 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4792 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4795 if (op.isFixedPointOp())
4796 return EmitFixedPointBinOp(op);
4798 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4803Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4805 using llvm::ConstantInt;
4811 QualType ResultTy = op.Ty;
4812 QualType LHSTy, RHSTy;
4813 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4814 RHSTy = BinOp->getRHS()->getType();
4815 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4820 LHSTy = CAO->getComputationLHSType();
4821 ResultTy = CAO->getComputationResultType();
4823 LHSTy = BinOp->getLHS()->getType();
4824 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4825 LHSTy = UnOp->getSubExpr()->getType();
4826 RHSTy = UnOp->getSubExpr()->getType();
4829 Value *LHS = op.LHS;
4830 Value *RHS = op.RHS;
4835 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4839 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4840 switch (op.Opcode) {
4843 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4847 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4851 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4855 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4859 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4863 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4866 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4868 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4870 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4872 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4877 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4879 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4883 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4896 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4902 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4907Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4909 if (!op.LHS->getType()->isPointerTy()) {
4910 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4911 op.Ty->isUnsignedIntegerType()) {
4912 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4914 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4915 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4916 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4917 case LangOptions::OB_Wrap:
4918 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4919 case LangOptions::OB_SignedAndDefined:
4921 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4923 case LangOptions::OB_Unset:
4925 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4926 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4928 case LangOptions::OB_Trap:
4929 if (CanElideOverflowCheck(CGF.
getContext(), op))
4930 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4931 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4932 return EmitOverflowCheckedBinOp(op);
4937 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4938 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4944 if (op.Ty->isConstantMatrixType()) {
4945 llvm::MatrixBuilder MB(Builder);
4946 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4947 return MB.CreateSub(op.LHS, op.RHS);
4950 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4951 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4952 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4955 if (op.isFixedPointOp())
4956 return EmitFixedPointBinOp(op);
4958 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4963 if (!op.RHS->getType()->isPointerTy())
4970 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4972 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4973 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4977 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4979 llvm::Value *divisor =
nullptr;
4982 if (
const VariableArrayType *vla
4985 elementType = VlaSize.Type;
4986 divisor = VlaSize.NumElts;
4990 if (!eltSize.
isOne())
4997 CharUnits elementSize;
5006 if (elementSize.
isOne())
5015 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5018Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5020 llvm::IntegerType *Ty;
5021 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5029 llvm::Type *RHSTy = RHS->
getType();
5030 llvm::APInt RHSMax =
5031 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5032 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5033 if (RHSMax.ult(Ty->getBitWidth()))
5034 return llvm::ConstantInt::get(RHSTy, RHSMax);
5035 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5039 const Twine &Name) {
5040 llvm::IntegerType *Ty;
5041 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5046 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5047 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5049 return Builder.CreateURem(
5050 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5053Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5055 if (Ops.isFixedPointOp())
5056 return EmitFixedPointBinOp(Ops);
5060 Value *RHS = Ops.RHS;
5061 if (Ops.LHS->getType() != RHS->
getType())
5062 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5064 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5065 Ops.Ty->hasSignedIntegerRepresentation() &&
5068 bool SanitizeUnsignedBase =
5069 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5070 Ops.Ty->hasUnsignedIntegerRepresentation();
5071 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5072 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5075 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5076 else if ((SanitizeBase || SanitizeExponent) &&
5078 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5079 if (SanitizeSignedBase)
5080 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5081 if (SanitizeUnsignedBase)
5082 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5083 if (SanitizeExponent)
5084 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5086 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5087 SanitizerHandler::ShiftOutOfBounds);
5088 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5089 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5090 llvm::Value *WidthMinusOne =
5091 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5092 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5094 if (SanitizeExponent) {
5096 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5103 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5106 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5107 llvm::Value *PromotedWidthMinusOne =
5108 (RHS == Ops.RHS) ? WidthMinusOne
5109 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5111 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5112 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5121 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5122 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5124 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5125 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5127 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5128 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5129 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5130 Checks.push_back(std::make_pair(
5131 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5132 : SanitizerKind::SO_UnsignedShiftBase));
5135 assert(!Checks.empty());
5136 EmitBinOpCheck(Checks, Ops);
5139 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5142Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5144 if (Ops.isFixedPointOp())
5145 return EmitFixedPointBinOp(Ops);
5149 Value *RHS = Ops.RHS;
5150 if (Ops.LHS->getType() != RHS->
getType())
5151 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5155 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5156 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5158 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5159 SanitizerHandler::ShiftOutOfBounds);
5160 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5161 llvm::Value *
Valid = Builder.CreateICmpULE(
5162 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5163 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5166 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5167 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5168 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5176 default: llvm_unreachable(
"unexpected element type");
5177 case BuiltinType::Char_U:
5178 case BuiltinType::UChar:
5179 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5180 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5181 case BuiltinType::Char_S:
5182 case BuiltinType::SChar:
5183 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5184 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5185 case BuiltinType::UShort:
5186 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5187 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5188 case BuiltinType::Short:
5189 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5190 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5191 case BuiltinType::UInt:
5192 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5193 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5194 case BuiltinType::Int:
5195 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5196 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5197 case BuiltinType::ULong:
5198 case BuiltinType::ULongLong:
5199 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5200 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5201 case BuiltinType::Long:
5202 case BuiltinType::LongLong:
5203 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5204 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5205 case BuiltinType::Float:
5206 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5207 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5208 case BuiltinType::Double:
5209 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5210 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5211 case BuiltinType::UInt128:
5212 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5213 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5214 case BuiltinType::Int128:
5215 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5216 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5220Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5221 llvm::CmpInst::Predicate UICmpOpc,
5222 llvm::CmpInst::Predicate SICmpOpc,
5223 llvm::CmpInst::Predicate FCmpOpc,
5225 TestAndClearIgnoreResultAssign();
5229 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5235 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5237 BinOpInfo BOInfo = EmitBinOps(E);
5238 Value *LHS = BOInfo.LHS;
5239 Value *RHS = BOInfo.RHS;
5245 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5247 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5250 Value *FirstVecArg = LHS,
5251 *SecondVecArg = RHS;
5253 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5257 default: llvm_unreachable(
"is not a comparison operation");
5269 std::swap(FirstVecArg, SecondVecArg);
5276 if (ElementKind == BuiltinType::Float) {
5278 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5279 std::swap(FirstVecArg, SecondVecArg);
5287 if (ElementKind == BuiltinType::Float) {
5289 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5294 std::swap(FirstVecArg, SecondVecArg);
5299 Value *CR6Param = Builder.getInt32(CR6);
5301 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5309 if (ResultTy->getBitWidth() > 1 &&
5311 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5316 if (BOInfo.isFixedPointOp()) {
5317 Result = EmitFixedPointBinOp(BOInfo);
5318 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5319 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5321 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5323 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5325 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5340 LHS = Builder.CreateStripInvariantGroup(LHS);
5342 RHS = Builder.CreateStripInvariantGroup(RHS);
5345 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5351 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5357 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5359 CETy = CTy->getElementType();
5361 LHS.first = Visit(E->
getLHS());
5362 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5365 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5368 CTy->getElementType()) &&
5369 "The element types must always match.");
5372 RHS.first = Visit(E->
getRHS());
5373 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5375 "The element types must always match.");
5378 Value *ResultR, *ResultI;
5382 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5383 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5387 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5388 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5392 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5395 "Complex comparison other than == or != ?");
5396 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5408 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5409 CastKind Kind = ICE->getCastKind();
5410 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5411 *SrcType = ICE->getSubExpr()->getType();
5424 bool Ignore = TestAndClearIgnoreResultAssign();
5458 RHS = Visit(E->
getRHS());
5474 RHS = Visit(E->
getRHS());
5514 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5517Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5528 if (LHS->
getType()->isFPOrFPVectorTy()) {
5529 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5531 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5532 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5534 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5535 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5537 Value *
And = Builder.CreateAnd(LHS, RHS);
5538 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5542 llvm::Type *ResTy = ConvertType(E->
getType());
5561 if (InstrumentRegions &&
5565 llvm::BasicBlock *RHSSkip =
5568 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5585 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5596 return llvm::Constant::getNullValue(ResTy);
5607 llvm::BasicBlock *LHSFalseBlock =
5610 CodeGenFunction::ConditionalEvaluation eval(CGF);
5625 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5627 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5629 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5638 RHSBlock = Builder.GetInsertBlock();
5643 llvm::BasicBlock *ContIncoming = RHSBlock;
5644 if (InstrumentRegions &&
5648 llvm::BasicBlock *RHSBlockSkip =
5650 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5654 PN->addIncoming(RHSCond, RHSBlockCnt);
5659 ContIncoming = RHSBlockSkip;
5670 PN->addIncoming(RHSCond, ContIncoming);
5679 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5683 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5686Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5697 if (LHS->
getType()->isFPOrFPVectorTy()) {
5698 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5700 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5701 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5703 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5704 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5706 Value *
Or = Builder.CreateOr(LHS, RHS);
5707 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5711 llvm::Type *ResTy = ConvertType(E->
getType());
5730 if (InstrumentRegions &&
5734 llvm::BasicBlock *RHSSkip =
5737 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5754 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5765 return llvm::ConstantInt::get(ResTy, 1);
5775 llvm::BasicBlock *LHSTrueBlock =
5778 CodeGenFunction::ConditionalEvaluation eval(CGF);
5794 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5796 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5798 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5810 RHSBlock = Builder.GetInsertBlock();
5815 llvm::BasicBlock *ContIncoming = RHSBlock;
5816 if (InstrumentRegions &&
5820 llvm::BasicBlock *RHSTrueBlock =
5822 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5826 PN->addIncoming(RHSCond, RHSBlockCnt);
5831 ContIncoming = RHSTrueBlock;
5838 PN->addIncoming(RHSCond, ContIncoming);
5845 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5848Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5851 return Visit(E->
getRHS());
5876Value *ScalarExprEmitter::
5877VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5878 TestAndClearIgnoreResultAssign();
5881 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5883 Expr *condExpr = E->
getCond();
5891 Expr *live = lhsExpr, *dead = rhsExpr;
5892 if (!CondExprBool) std::swap(live, dead);
5919 llvm::Value *LHS = Visit(lhsExpr);
5920 llvm::Value *RHS = Visit(rhsExpr);
5922 llvm::Type *condType = ConvertType(condExpr->
getType());
5925 unsigned numElem = vecTy->getNumElements();
5926 llvm::Type *elemType = vecTy->getElementType();
5928 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5929 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5930 llvm::Value *tmp = Builder.CreateSExt(
5931 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5932 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5935 llvm::Value *RHSTmp = RHS;
5936 llvm::Value *LHSTmp = LHS;
5937 bool wasCast =
false;
5939 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5940 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5941 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5945 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5946 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5947 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5949 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5959 llvm::Value *LHS = Visit(lhsExpr);
5960 llvm::Value *RHS = Visit(rhsExpr);
5962 llvm::Type *CondType = ConvertType(condExpr->
getType());
5965 if (VecTy->getElementType()->isIntegerTy(1))
5966 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5969 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5971 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5973 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5974 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5984 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5988 llvm::Value *LHS = Visit(lhsExpr);
5989 llvm::Value *RHS = Visit(rhsExpr);
5992 assert(!RHS &&
"LHS and RHS types must match");
5995 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6006 CodeGenFunction::ConditionalEvaluation eval(CGF);
6020 Value *LHS = Visit(lhsExpr);
6023 LHSBlock = Builder.GetInsertBlock();
6024 Builder.CreateBr(ContBlock);
6036 Value *RHS = Visit(rhsExpr);
6039 RHSBlock = Builder.GetInsertBlock();
6049 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6050 PN->addIncoming(LHS, LHSBlock);
6051 PN->addIncoming(RHS, RHSBlock);
6056Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6060Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6062 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6067Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6073 Value *Src,
unsigned NumElementsDst) {
6074 static constexpr int Mask[] = {0, 1, 2, -1};
6075 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6095 const llvm::DataLayout &DL,
6096 Value *Src, llvm::Type *DstTy,
6097 StringRef Name =
"") {
6101 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6102 return Builder.CreateBitCast(Src, DstTy, Name);
6105 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6106 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6109 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6111 if (!DstTy->isIntegerTy())
6112 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6114 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6118 if (!SrcTy->isIntegerTy())
6119 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6121 return Builder.CreateIntToPtr(Src, DstTy, Name);
6124Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6126 llvm::Type *DstTy = ConvertType(E->
getType());
6128 llvm::Type *SrcTy = Src->
getType();
6129 unsigned NumElementsSrc =
6133 unsigned NumElementsDst =
6144 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6149 Src->setName(
"astype");
6156 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6157 auto *Vec4Ty = llvm::FixedVectorType::get(
6163 Src->setName(
"astype");
6168 Src, DstTy,
"astype");
6171Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6183 "Invalid scalar expression to emit");
6185 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6186 .Visit(
const_cast<Expr *
>(E));
6195 "Invalid scalar expression to emit");
6196 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6206 "Invalid complex -> scalar conversion");
6207 return ScalarExprEmitter(*
this)
6208 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6215 if (!PromotionType.
isNull())
6216 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6218 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6224 bool isInc,
bool isPre) {
6225 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6235 llvm::Type *BaseTy =
6251 ScalarExprEmitter Scalar(*
this);
6254#define COMPOUND_OP(Op) \
6255 case BO_##Op##Assign: \
6256 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6293 llvm_unreachable(
"Not valid compound assignment operators");
6296 llvm_unreachable(
"Unhandled compound assignment operator");
6311 llvm::LLVMContext &VMContext,
6317 llvm::Value *TotalOffset =
nullptr;
6323 Value *BasePtr_int =
6324 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6326 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6327 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6328 return {TotalOffset, Builder.getFalse()};
6332 assert(GEP->getPointerOperand() == BasePtr &&
6333 "BasePtr must be the base of the GEP.");
6334 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6336 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6339 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6340 auto *SAddIntrinsic =
6341 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6342 auto *SMulIntrinsic =
6343 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6346 llvm::Value *OffsetOverflows = Builder.getFalse();
6350 llvm::Value *RHS) -> llvm::Value * {
6351 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6354 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6355 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6357 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6360 OffsetOverflows = Builder.getTrue();
6361 return llvm::ConstantInt::get(VMContext, N);
6366 auto *ResultAndOverflow = Builder.CreateCall(
6367 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6368 OffsetOverflows = Builder.CreateOr(
6369 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6370 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6374 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6375 GTI != GTE; ++GTI) {
6376 llvm::Value *LocalOffset;
6377 auto *Index = GTI.getOperand();
6379 if (
auto *STy = GTI.getStructTypeOrNull()) {
6383 LocalOffset = llvm::ConstantInt::get(
6384 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6389 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6390 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6391 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6396 if (!TotalOffset || TotalOffset ==
Zero)
6397 TotalOffset = LocalOffset;
6399 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6402 return {TotalOffset, OffsetOverflows};
6407 ArrayRef<Value *> IdxList,
6408 bool SignedIndices,
bool IsSubtraction,
6409 SourceLocation Loc,
const Twine &Name) {
6410 llvm::Type *PtrTy = Ptr->
getType();
6412 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6413 if (!SignedIndices && !IsSubtraction)
6414 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6416 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6419 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6423 bool PerformNullCheck = !NullPointerIsDefined(
6424 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6427 bool PerformOverflowCheck =
6430 if (!(PerformNullCheck || PerformOverflowCheck))
6433 const auto &DL = CGM.getDataLayout();
6435 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6436 auto CheckHandler = SanitizerHandler::PointerOverflow;
6437 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6438 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6440 GEPOffsetAndOverflow EvaluatedGEP =
6445 "If the offset got constant-folded, we don't expect that there was an "
6448 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6456 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6457 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6459 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6463 if (PerformNullCheck) {
6471 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6472 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6473 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6474 Checks.emplace_back(
Valid, CheckOrdinal);
6477 if (PerformOverflowCheck) {
6482 llvm::Value *ValidGEP;
6483 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6484 if (SignedIndices) {
6490 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6491 auto *PosOrZeroOffset =
6493 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6495 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6496 }
else if (!IsSubtraction) {
6501 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6507 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6509 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6510 Checks.emplace_back(ValidGEP, CheckOrdinal);
6513 assert(!Checks.empty() &&
"Should have produced some checks.");
6515 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6517 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6518 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6524 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6525 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6526 const Twine &Name) {
6527 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6528 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6529 if (!SignedIndices && !IsSubtraction)
6530 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6532 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6536 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6537 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6538 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 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)
Result
Implement __builtin_bit_cast and related operations.
Defines AST-level helper utilities for matrix types.
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
bool isNullPointer() 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.
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.
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.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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 * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
@ UseSkipPath
Skip (false)
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)
bool hasSkipCounter(const Stmt *S) const
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.
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
void markStmtAsUsed(bool Skipped, const Stmt *S)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isMCDCDecisionExpr(const Expr *E) const
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const 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.
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.
unsigned mapRowMajorToColumnMajorFlattenedIndex(unsigned RowMajorIdx) const
Given a row-major flattened index RowMajorIdx, return the equivalent column-major flattened index.
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,...
@ 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.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
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
bool isSignedOverflowDefined() 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
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.
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.
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
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 isMFloat8Type() 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.
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.
PRESERVE_NONE bool Ret(InterpState &S)
@ Address
A pointer to a ValueDecl.
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())))
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
@ Result
The result type of a method or function.
@ Off
Never emit colors regardless of the output stream.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::Type * HalfTy
half, bfloat, float, double
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool HasSideEffects
Whether the evaluated expression has side effects.
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.