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>()) {
4095 QualType AtomicValueTy = atomicTy->getValueType();
4104 bool CanEmitAtomicRMW =
4108 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4110 LangOptions::SOB_Trapping;
4111 if (CanEmitAtomicRMW) {
4112 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4113 llvm::Instruction::BinaryOps Op;
4114 switch (OpInfo.Opcode) {
4116 case BO_MulAssign:
case BO_DivAssign:
4122 AtomicOp = llvm::AtomicRMWInst::Add;
4123 Op = llvm::Instruction::Add;
4126 AtomicOp = llvm::AtomicRMWInst::Sub;
4127 Op = llvm::Instruction::Sub;
4130 AtomicOp = llvm::AtomicRMWInst::And;
4131 Op = llvm::Instruction::And;
4134 AtomicOp = llvm::AtomicRMWInst::Xor;
4135 Op = llvm::Instruction::Xor;
4138 AtomicOp = llvm::AtomicRMWInst::Or;
4139 Op = llvm::Instruction::Or;
4142 llvm_unreachable(
"Invalid compound assignment type");
4144 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4146 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4150 llvm::AtomicRMWInst *OldVal =
4155 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4161 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4163 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4164 OpInfo.LHS = CGF.
EmitToMemory(OpInfo.LHS, AtomicValueTy);
4165 Builder.CreateBr(opBB);
4166 Builder.SetInsertPoint(opBB);
4167 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4168 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4169 OpInfo.LHS = atomicPHI;
4172 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4174 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4176 if (!PromotionTypeLHS.
isNull())
4177 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4180 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4191 if (LHSLV.isBitField()) {
4193 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4194 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4196 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4197 Loc, ScalarConversionOpts(CGF.
SanOpts));
4199 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4200 ScalarConversionOpts(CGF.
SanOpts));
4204 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4208 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4209 llvm::Value *
success = Pair.second;
4210 atomicPHI->addIncoming(old, curBlock);
4211 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4212 Builder.SetInsertPoint(contBB);
4220 if (LHSLV.isBitField()) {
4236Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4237 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4238 bool Ignore = TestAndClearIgnoreResultAssign();
4239 Value *RHS =
nullptr;
4240 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4251 if (!LHS.isVolatileQualified())
4255 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4258void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4259 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4260 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4263 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4264 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4265 SanitizerKind::SO_IntegerDivideByZero));
4269 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4270 Ops.Ty->hasSignedIntegerRepresentation() &&
4272 Ops.mayHaveIntegerOverflow() &&
4274 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4277 llvm::Value *IntMin =
4278 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4279 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4281 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4282 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4283 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4285 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4288 if (Checks.size() > 0)
4289 EmitBinOpCheck(Checks, Ops);
4292Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4294 SanitizerDebugLocation SanScope(&CGF,
4295 {SanitizerKind::SO_IntegerDivideByZero,
4296 SanitizerKind::SO_SignedIntegerOverflow,
4297 SanitizerKind::SO_FloatDivideByZero},
4298 SanitizerHandler::DivremOverflow);
4299 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4300 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4301 Ops.Ty->isIntegerType() &&
4302 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4303 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4304 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4305 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4306 Ops.Ty->isRealFloatingType() &&
4307 Ops.mayHaveFloatDivisionByZero()) {
4308 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4309 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4311 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4315 if (Ops.Ty->isConstantMatrixType()) {
4316 llvm::MatrixBuilder MB(Builder);
4323 "first operand must be a matrix");
4325 "second operand must be an arithmetic type");
4326 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4327 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4328 Ops.Ty->hasUnsignedIntegerRepresentation());
4331 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4333 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4334 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4338 else if (Ops.isFixedPointOp())
4339 return EmitFixedPointBinOp(Ops);
4340 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4341 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4343 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4346Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4348 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4349 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4350 Ops.Ty->isIntegerType() &&
4351 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4352 SanitizerDebugLocation SanScope(&CGF,
4353 {SanitizerKind::SO_IntegerDivideByZero,
4354 SanitizerKind::SO_SignedIntegerOverflow},
4355 SanitizerHandler::DivremOverflow);
4356 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4357 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4360 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4361 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4363 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4364 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4366 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4369Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4374 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4375 switch (Ops.Opcode) {
4379 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4380 llvm::Intrinsic::uadd_with_overflow;
4381 OverflowKind = SanitizerHandler::AddOverflow;
4386 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4387 llvm::Intrinsic::usub_with_overflow;
4388 OverflowKind = SanitizerHandler::SubOverflow;
4393 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4394 llvm::Intrinsic::umul_with_overflow;
4395 OverflowKind = SanitizerHandler::MulOverflow;
4398 llvm_unreachable(
"Unsupported operation for overflow detection");
4404 SanitizerDebugLocation SanScope(&CGF,
4405 {SanitizerKind::SO_SignedIntegerOverflow,
4406 SanitizerKind::SO_UnsignedIntegerOverflow},
4412 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4413 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4414 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4417 const std::string *handlerName =
4419 if (handlerName->empty()) {
4425 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4426 llvm::Value *NotOf = Builder.CreateNot(overflow);
4428 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4431 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4434 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4435 llvm::Value *NotOf = Builder.CreateNot(overflow);
4437 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4440 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4445 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4446 llvm::BasicBlock *continueBB =
4450 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4454 Builder.SetInsertPoint(overflowBB);
4457 llvm::Type *Int8Ty = CGF.
Int8Ty;
4458 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4459 llvm::FunctionType *handlerTy =
4460 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4461 llvm::FunctionCallee handler =
4466 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4467 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4471 llvm::Value *handlerArgs[] = {
4474 Builder.getInt8(OpID),
4477 llvm::Value *handlerResult =
4481 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4482 Builder.CreateBr(continueBB);
4484 Builder.SetInsertPoint(continueBB);
4485 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4486 phi->addIncoming(result, initialBB);
4487 phi->addIncoming(handlerResult, overflowBB);
4496 bool isSubtraction) {
4501 Value *pointer = op.LHS;
4502 Expr *pointerOperand =
expr->getLHS();
4504 Expr *indexOperand =
expr->getRHS();
4507 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4508 std::swap(pointer,
index);
4509 std::swap(pointerOperand, indexOperand);
4513 index, isSubtraction);
4519 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4523 auto &DL =
CGM.getDataLayout();
4546 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4548 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4549 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4550 PtrTy->getPointerAddressSpace()))
4553 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4554 auto CheckHandler = SanitizerHandler::PointerOverflow;
4556 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4558 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4559 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4561 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4562 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4567 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4578 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4588 llvm::Value *objectSize =
4594 return Builder.CreateBitCast(result, pointer->getType());
4599 getContext().getAsVariableArrayType(elementType)) {
4601 llvm::Value *numElements =
getVLASize(vla).NumElts;
4610 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4630 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4643 bool negMul,
bool negAdd) {
4644 Value *MulOp0 = MulOp->getOperand(0);
4645 Value *MulOp1 = MulOp->getOperand(1);
4647 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4649 Addend = Builder.CreateFNeg(Addend,
"neg");
4651 Value *FMulAdd =
nullptr;
4652 if (Builder.getIsFPConstrained()) {
4654 "Only constrained operation should be created when Builder is in FP "
4655 "constrained mode");
4656 FMulAdd = Builder.CreateConstrainedFPCall(
4657 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4659 {MulOp0, MulOp1, Addend});
4661 FMulAdd = Builder.CreateCall(
4663 {MulOp0, MulOp1, Addend});
4665 MulOp->eraseFromParent();
4680 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4681 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4682 "Only fadd/fsub can be the root of an fmuladd.");
4685 if (!op.FPFeatures.allowFPContractWithinStatement())
4688 Value *LHS = op.LHS;
4689 Value *RHS = op.RHS;
4693 bool NegLHS =
false;
4694 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4695 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4696 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4697 LHS = LHSUnOp->getOperand(0);
4702 bool NegRHS =
false;
4703 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4704 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4705 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4706 RHS = RHSUnOp->getOperand(0);
4714 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4715 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4716 (LHSBinOp->use_empty() || NegLHS)) {
4720 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4723 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4724 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4725 (RHSBinOp->use_empty() || NegRHS)) {
4729 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4733 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4734 if (LHSBinOp->getIntrinsicID() ==
4735 llvm::Intrinsic::experimental_constrained_fmul &&
4736 (LHSBinOp->use_empty() || NegLHS)) {
4740 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4743 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4744 if (RHSBinOp->getIntrinsicID() ==
4745 llvm::Intrinsic::experimental_constrained_fmul &&
4746 (RHSBinOp->use_empty() || NegRHS)) {
4750 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4757Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4758 if (op.LHS->getType()->isPointerTy() ||
4759 op.RHS->getType()->isPointerTy())
4762 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4763 op.Ty->isUnsignedIntegerType()) {
4764 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4766 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4767 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4768 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4769 case LangOptions::OB_Wrap:
4770 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4771 case LangOptions::OB_SignedAndDefined:
4773 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4775 case LangOptions::OB_Unset:
4777 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4778 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4780 case LangOptions::OB_Trap:
4781 if (CanElideOverflowCheck(CGF.
getContext(), op))
4782 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4783 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4784 return EmitOverflowCheckedBinOp(op);
4789 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4790 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4796 if (op.Ty->isConstantMatrixType()) {
4797 llvm::MatrixBuilder MB(Builder);
4798 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4799 return MB.CreateAdd(op.LHS, op.RHS);
4802 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4803 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4804 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4807 if (op.isFixedPointOp())
4808 return EmitFixedPointBinOp(op);
4810 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4815Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4817 using llvm::ConstantInt;
4823 QualType ResultTy = op.Ty;
4824 QualType LHSTy, RHSTy;
4825 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4826 RHSTy = BinOp->getRHS()->getType();
4827 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4832 LHSTy = CAO->getComputationLHSType();
4833 ResultTy = CAO->getComputationResultType();
4835 LHSTy = BinOp->getLHS()->getType();
4836 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4837 LHSTy = UnOp->getSubExpr()->getType();
4838 RHSTy = UnOp->getSubExpr()->getType();
4841 Value *LHS = op.LHS;
4842 Value *RHS = op.RHS;
4847 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4851 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4852 switch (op.Opcode) {
4855 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4859 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4863 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4867 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4871 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4875 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4878 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4880 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4882 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4884 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4889 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4891 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4895 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4908 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4914 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4919Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4921 if (!op.LHS->getType()->isPointerTy()) {
4922 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4923 op.Ty->isUnsignedIntegerType()) {
4924 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4926 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4927 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4928 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4929 case LangOptions::OB_Wrap:
4930 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4931 case LangOptions::OB_SignedAndDefined:
4933 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4935 case LangOptions::OB_Unset:
4937 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4938 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4940 case LangOptions::OB_Trap:
4941 if (CanElideOverflowCheck(CGF.
getContext(), op))
4942 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4943 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4944 return EmitOverflowCheckedBinOp(op);
4949 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4950 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4956 if (op.Ty->isConstantMatrixType()) {
4957 llvm::MatrixBuilder MB(Builder);
4958 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4959 return MB.CreateSub(op.LHS, op.RHS);
4962 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4963 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4964 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4967 if (op.isFixedPointOp())
4968 return EmitFixedPointBinOp(op);
4970 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4975 if (!op.RHS->getType()->isPointerTy())
4982 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4984 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4985 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4989 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4991 llvm::Value *divisor =
nullptr;
4994 if (
const VariableArrayType *vla
4997 elementType = VlaSize.Type;
4998 divisor = VlaSize.NumElts;
5002 if (!eltSize.
isOne())
5009 CharUnits elementSize;
5018 if (elementSize.
isOne())
5025 return Builder.CreateSDiv(diffInChars, divisor,
"sub.ptr.div");
5029 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5032Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5034 llvm::IntegerType *Ty;
5035 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5043 llvm::Type *RHSTy = RHS->
getType();
5044 llvm::APInt RHSMax =
5045 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5046 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5047 if (RHSMax.ult(Ty->getBitWidth()))
5048 return llvm::ConstantInt::get(RHSTy, RHSMax);
5049 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5053 const Twine &Name) {
5054 llvm::IntegerType *Ty;
5055 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5060 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5061 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5063 return Builder.CreateURem(
5064 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5067Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5069 if (Ops.isFixedPointOp())
5070 return EmitFixedPointBinOp(Ops);
5074 Value *RHS = Ops.RHS;
5075 if (Ops.LHS->getType() != RHS->
getType())
5076 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5078 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5079 Ops.Ty->hasSignedIntegerRepresentation() &&
5082 bool SanitizeUnsignedBase =
5083 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5084 Ops.Ty->hasUnsignedIntegerRepresentation();
5085 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5086 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5089 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5090 else if ((SanitizeBase || SanitizeExponent) &&
5092 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5093 if (SanitizeSignedBase)
5094 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5095 if (SanitizeUnsignedBase)
5096 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5097 if (SanitizeExponent)
5098 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5100 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5101 SanitizerHandler::ShiftOutOfBounds);
5102 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5103 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5104 llvm::Value *WidthMinusOne =
5105 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5106 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5108 if (SanitizeExponent) {
5110 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5117 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5120 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5121 llvm::Value *PromotedWidthMinusOne =
5122 (RHS == Ops.RHS) ? WidthMinusOne
5123 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5125 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5126 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5135 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5136 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5138 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5139 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5141 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5142 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5143 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5144 Checks.push_back(std::make_pair(
5145 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5146 : SanitizerKind::SO_UnsignedShiftBase));
5149 assert(!Checks.empty());
5150 EmitBinOpCheck(Checks, Ops);
5153 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5156Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5158 if (Ops.isFixedPointOp())
5159 return EmitFixedPointBinOp(Ops);
5163 Value *RHS = Ops.RHS;
5164 if (Ops.LHS->getType() != RHS->
getType())
5165 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5169 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5170 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5172 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5173 SanitizerHandler::ShiftOutOfBounds);
5174 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5175 llvm::Value *
Valid = Builder.CreateICmpULE(
5176 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5177 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5180 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5181 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5182 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5190 default: llvm_unreachable(
"unexpected element type");
5191 case BuiltinType::Char_U:
5192 case BuiltinType::UChar:
5193 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5194 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5195 case BuiltinType::Char_S:
5196 case BuiltinType::SChar:
5197 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5198 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5199 case BuiltinType::UShort:
5200 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5201 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5202 case BuiltinType::Short:
5203 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5204 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5205 case BuiltinType::UInt:
5206 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5207 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5208 case BuiltinType::Int:
5209 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5210 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5211 case BuiltinType::ULong:
5212 case BuiltinType::ULongLong:
5213 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5214 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5215 case BuiltinType::Long:
5216 case BuiltinType::LongLong:
5217 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5218 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5219 case BuiltinType::Float:
5220 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5221 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5222 case BuiltinType::Double:
5223 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5224 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5225 case BuiltinType::UInt128:
5226 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5227 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5228 case BuiltinType::Int128:
5229 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5230 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5234Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5235 llvm::CmpInst::Predicate UICmpOpc,
5236 llvm::CmpInst::Predicate SICmpOpc,
5237 llvm::CmpInst::Predicate FCmpOpc,
5239 TestAndClearIgnoreResultAssign();
5243 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5249 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5251 BinOpInfo BOInfo = EmitBinOps(E);
5252 Value *LHS = BOInfo.LHS;
5253 Value *RHS = BOInfo.RHS;
5259 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5261 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5264 Value *FirstVecArg = LHS,
5265 *SecondVecArg = RHS;
5267 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5271 default: llvm_unreachable(
"is not a comparison operation");
5283 std::swap(FirstVecArg, SecondVecArg);
5290 if (ElementKind == BuiltinType::Float) {
5292 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5293 std::swap(FirstVecArg, SecondVecArg);
5301 if (ElementKind == BuiltinType::Float) {
5303 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5308 std::swap(FirstVecArg, SecondVecArg);
5313 Value *CR6Param = Builder.getInt32(CR6);
5315 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5323 if (ResultTy->getBitWidth() > 1 &&
5325 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5330 if (BOInfo.isFixedPointOp()) {
5331 Result = EmitFixedPointBinOp(BOInfo);
5332 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5333 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5335 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5337 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5339 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5354 LHS = Builder.CreateStripInvariantGroup(LHS);
5356 RHS = Builder.CreateStripInvariantGroup(RHS);
5359 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5365 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5371 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5373 CETy = CTy->getElementType();
5375 LHS.first = Visit(E->
getLHS());
5376 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5379 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5382 CTy->getElementType()) &&
5383 "The element types must always match.");
5386 RHS.first = Visit(E->
getRHS());
5387 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5389 "The element types must always match.");
5392 Value *ResultR, *ResultI;
5396 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5397 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5401 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5402 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5406 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5409 "Complex comparison other than == or != ?");
5410 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5422 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5423 CastKind Kind = ICE->getCastKind();
5424 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5425 *SrcType = ICE->getSubExpr()->getType();
5438 bool Ignore = TestAndClearIgnoreResultAssign();
5472 RHS = Visit(E->
getRHS());
5488 RHS = Visit(E->
getRHS());
5528 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5531Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5542 if (LHS->
getType()->isFPOrFPVectorTy()) {
5543 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5545 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5546 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5548 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5549 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5551 Value *
And = Builder.CreateAnd(LHS, RHS);
5552 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5556 llvm::Type *ResTy = ConvertType(E->
getType());
5575 if (InstrumentRegions &&
5579 llvm::BasicBlock *RHSSkip =
5582 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5599 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5610 return llvm::Constant::getNullValue(ResTy);
5621 llvm::BasicBlock *LHSFalseBlock =
5624 CodeGenFunction::ConditionalEvaluation eval(CGF);
5639 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5641 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5643 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5652 RHSBlock = Builder.GetInsertBlock();
5657 llvm::BasicBlock *ContIncoming = RHSBlock;
5658 if (InstrumentRegions &&
5662 llvm::BasicBlock *RHSBlockSkip =
5664 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5668 PN->addIncoming(RHSCond, RHSBlockCnt);
5673 ContIncoming = RHSBlockSkip;
5684 PN->addIncoming(RHSCond, ContIncoming);
5693 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5697 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5700Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5711 if (LHS->
getType()->isFPOrFPVectorTy()) {
5712 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5714 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5715 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5717 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5718 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5720 Value *
Or = Builder.CreateOr(LHS, RHS);
5721 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5725 llvm::Type *ResTy = ConvertType(E->
getType());
5744 if (InstrumentRegions &&
5748 llvm::BasicBlock *RHSSkip =
5751 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5768 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5779 return llvm::ConstantInt::get(ResTy, 1);
5789 llvm::BasicBlock *LHSTrueBlock =
5792 CodeGenFunction::ConditionalEvaluation eval(CGF);
5808 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5810 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5812 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5824 RHSBlock = Builder.GetInsertBlock();
5829 llvm::BasicBlock *ContIncoming = RHSBlock;
5830 if (InstrumentRegions &&
5834 llvm::BasicBlock *RHSTrueBlock =
5836 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5840 PN->addIncoming(RHSCond, RHSBlockCnt);
5845 ContIncoming = RHSTrueBlock;
5852 PN->addIncoming(RHSCond, ContIncoming);
5859 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5862Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5865 return Visit(E->
getRHS());
5890Value *ScalarExprEmitter::
5891VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5892 TestAndClearIgnoreResultAssign();
5895 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5897 Expr *condExpr = E->
getCond();
5905 Expr *live = lhsExpr, *dead = rhsExpr;
5906 if (!CondExprBool) std::swap(live, dead);
5933 llvm::Value *LHS = Visit(lhsExpr);
5934 llvm::Value *RHS = Visit(rhsExpr);
5936 llvm::Type *condType = ConvertType(condExpr->
getType());
5939 unsigned numElem = vecTy->getNumElements();
5940 llvm::Type *elemType = vecTy->getElementType();
5942 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5943 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5944 llvm::Value *tmp = Builder.CreateSExt(
5945 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5946 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5949 llvm::Value *RHSTmp = RHS;
5950 llvm::Value *LHSTmp = LHS;
5951 bool wasCast =
false;
5953 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5954 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5955 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5959 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5960 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5961 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5963 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5973 llvm::Value *LHS = Visit(lhsExpr);
5974 llvm::Value *RHS = Visit(rhsExpr);
5976 llvm::Type *CondType = ConvertType(condExpr->
getType());
5979 if (VecTy->getElementType()->isIntegerTy(1))
5980 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5983 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5985 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5987 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5988 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5998 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
6002 llvm::Value *LHS = Visit(lhsExpr);
6003 llvm::Value *RHS = Visit(rhsExpr);
6006 assert(!RHS &&
"LHS and RHS types must match");
6009 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6020 CodeGenFunction::ConditionalEvaluation eval(CGF);
6034 Value *LHS = Visit(lhsExpr);
6037 LHSBlock = Builder.GetInsertBlock();
6038 Builder.CreateBr(ContBlock);
6050 Value *RHS = Visit(rhsExpr);
6053 RHSBlock = Builder.GetInsertBlock();
6063 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6064 PN->addIncoming(LHS, LHSBlock);
6065 PN->addIncoming(RHS, RHSBlock);
6070Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6074Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6076 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6081Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6087 Value *Src,
unsigned NumElementsDst) {
6088 static constexpr int Mask[] = {0, 1, 2, -1};
6089 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6109 const llvm::DataLayout &DL,
6110 Value *Src, llvm::Type *DstTy,
6111 StringRef Name =
"") {
6115 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6116 return Builder.CreateBitCast(Src, DstTy, Name);
6119 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6120 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6123 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6125 if (!DstTy->isIntegerTy())
6126 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6128 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6132 if (!SrcTy->isIntegerTy())
6133 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6135 return Builder.CreateIntToPtr(Src, DstTy, Name);
6138Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6140 llvm::Type *DstTy = ConvertType(E->
getType());
6142 llvm::Type *SrcTy = Src->
getType();
6143 unsigned NumElementsSrc =
6147 unsigned NumElementsDst =
6158 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6163 Src->setName(
"astype");
6170 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6171 auto *Vec4Ty = llvm::FixedVectorType::get(
6177 Src->setName(
"astype");
6182 Src, DstTy,
"astype");
6185Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6197 "Invalid scalar expression to emit");
6199 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6200 .Visit(
const_cast<Expr *
>(E));
6209 "Invalid scalar expression to emit");
6210 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6220 "Invalid complex -> scalar conversion");
6221 return ScalarExprEmitter(*
this)
6222 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6229 if (!PromotionType.
isNull())
6230 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6232 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6238 bool isInc,
bool isPre) {
6239 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6249 llvm::Type *BaseTy =
6265 ScalarExprEmitter Scalar(*
this);
6268#define COMPOUND_OP(Op) \
6269 case BO_##Op##Assign: \
6270 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6307 llvm_unreachable(
"Not valid compound assignment operators");
6310 llvm_unreachable(
"Unhandled compound assignment operator");
6325 llvm::LLVMContext &VMContext,
6331 llvm::Value *TotalOffset =
nullptr;
6337 Value *BasePtr_int =
6338 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6340 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6341 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6342 return {TotalOffset, Builder.getFalse()};
6346 assert(GEP->getPointerOperand() == BasePtr &&
6347 "BasePtr must be the base of the GEP.");
6348 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6350 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6353 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6354 auto *SAddIntrinsic =
6355 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6356 auto *SMulIntrinsic =
6357 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6360 llvm::Value *OffsetOverflows = Builder.getFalse();
6364 llvm::Value *RHS) -> llvm::Value * {
6365 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6368 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6369 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6371 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6374 OffsetOverflows = Builder.getTrue();
6375 return llvm::ConstantInt::get(VMContext, N);
6380 auto *ResultAndOverflow = Builder.CreateCall(
6381 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6382 OffsetOverflows = Builder.CreateOr(
6383 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6384 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6388 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6389 GTI != GTE; ++GTI) {
6390 llvm::Value *LocalOffset;
6391 auto *Index = GTI.getOperand();
6393 if (
auto *STy = GTI.getStructTypeOrNull()) {
6397 LocalOffset = llvm::ConstantInt::get(
6398 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6403 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6404 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6405 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6410 if (!TotalOffset || TotalOffset ==
Zero)
6411 TotalOffset = LocalOffset;
6413 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6416 return {TotalOffset, OffsetOverflows};
6421 ArrayRef<Value *> IdxList,
6422 bool SignedIndices,
bool IsSubtraction,
6423 SourceLocation Loc,
const Twine &Name) {
6424 llvm::Type *PtrTy = Ptr->
getType();
6426 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6427 if (!SignedIndices && !IsSubtraction)
6428 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6430 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6433 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6437 bool PerformNullCheck = !NullPointerIsDefined(
6438 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6441 bool PerformOverflowCheck =
6444 if (!(PerformNullCheck || PerformOverflowCheck))
6447 const auto &DL = CGM.getDataLayout();
6449 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6450 auto CheckHandler = SanitizerHandler::PointerOverflow;
6451 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6452 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6454 GEPOffsetAndOverflow EvaluatedGEP =
6459 "If the offset got constant-folded, we don't expect that there was an "
6462 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6470 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6471 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6473 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6477 if (PerformNullCheck) {
6485 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6486 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6487 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6488 Checks.emplace_back(
Valid, CheckOrdinal);
6491 if (PerformOverflowCheck) {
6496 llvm::Value *ValidGEP;
6497 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6498 if (SignedIndices) {
6504 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6505 auto *PosOrZeroOffset =
6507 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6509 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6510 }
else if (!IsSubtraction) {
6515 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6521 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6523 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6524 Checks.emplace_back(ValidGEP, CheckOrdinal);
6527 assert(!Checks.empty() &&
"Should have produced some checks.");
6529 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6531 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6532 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6538 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6539 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6540 const Twine &Name) {
6541 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6542 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6543 if (!SignedIndices && !IsSubtraction)
6544 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6546 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6550 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6551 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6552 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.
const FunctionProtoType * T
@ 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.