37#include "llvm/ADT/APFixedPoint.h"
38#include "llvm/ADT/ScopeExit.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/CFG.h"
41#include "llvm/IR/Constants.h"
42#include "llvm/IR/DataLayout.h"
43#include "llvm/IR/DerivedTypes.h"
44#include "llvm/IR/FixedPointBuilder.h"
45#include "llvm/IR/Function.h"
46#include "llvm/IR/GEPNoWrapFlags.h"
47#include "llvm/IR/GetElementPtrTypeIterator.h"
48#include "llvm/IR/GlobalVariable.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/IntrinsicsPowerPC.h"
51#include "llvm/IR/IntrinsicsWebAssembly.h"
52#include "llvm/IR/MatrixBuilder.h"
53#include "llvm/IR/Module.h"
54#include "llvm/Support/TypeSize.h"
77bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
82 const auto &LHSAP = LHS->getValue();
83 const auto &RHSAP = RHS->getValue();
84 if (Opcode == BO_Add) {
86 : LHSAP.uadd_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Sub) {
89 : LHSAP.usub_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Mul) {
92 : LHSAP.umul_ov(RHSAP, Overflow);
93 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
94 if (
Signed && !RHS->isZero())
95 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
107 FPOptions FPFeatures;
111 bool mayHaveIntegerOverflow()
const {
113 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
114 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
115 if (!LHSCI || !RHSCI)
119 return ::mayHaveIntegerOverflow(
124 bool isDivremOp()
const {
130 bool mayHaveIntegerDivisionByZero()
const {
132 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
138 bool mayHaveFloatDivisionByZero()
const {
140 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
141 return CFP->isZero();
148 bool isFixedPointOp()
const {
151 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
152 QualType LHSType = BinOp->getLHS()->getType();
153 QualType RHSType = BinOp->getRHS()->getType();
156 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
157 return UnOp->getSubExpr()->getType()->isFixedPointType();
162 bool rhsHasSignedIntegerRepresentation()
const {
163 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
164 QualType RHSType = BinOp->getRHS()->getType();
171static bool MustVisitNullValue(
const Expr *E) {
194static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
204 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
209 switch (OBT->getBehaviorKind()) {
210 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
212 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
215 llvm_unreachable(
"Unknown OverflowBehaviorKind");
222 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
230 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
234static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
236 "Expected a unary or binary operator");
240 if (!Op.mayHaveIntegerOverflow())
247 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
248 if (BO && BO->hasExcludedOverflowPattern())
251 if (Op.Ty.isWrapType())
253 if (Op.Ty.isTrapType())
256 if (Op.Ty->isSignedIntegerType() &&
262 if (Op.Ty->isUnsignedIntegerType() &&
287 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
293 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
294 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
298class ScalarExprEmitter
300 CodeGenFunction &CGF;
301 CGBuilderTy &Builder;
302 bool IgnoreResultAssign;
303 llvm::LLVMContext &VMContext;
306 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
307 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
308 VMContext(cgf.getLLVMContext()) {
315 bool TestAndClearIgnoreResultAssign() {
316 bool I = IgnoreResultAssign;
317 IgnoreResultAssign =
false;
321 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
322 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
328 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
329 const BinOpInfo &Info);
331 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
335 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
336 const AlignValueAttr *AVAttr =
nullptr;
337 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
338 const ValueDecl *VD = DRE->getDecl();
341 if (
const auto *TTy =
343 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
353 AVAttr = VD->
getAttr<AlignValueAttr>();
358 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
359 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
372 Value *EmitLoadOfLValue(
const Expr *E) {
376 EmitLValueAlignmentAssumption(E,
V);
382 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
386 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
387 Value *Src, QualType SrcType, QualType DstType,
388 llvm::Type *DstTy, SourceLocation Loc);
393 enum ImplicitConversionCheckKind :
unsigned char {
394 ICCK_IntegerTruncation = 0,
395 ICCK_UnsignedIntegerTruncation = 1,
396 ICCK_SignedIntegerTruncation = 2,
397 ICCK_IntegerSignChange = 3,
398 ICCK_SignedIntegerTruncationOrSignChange = 4,
403 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
404 QualType DstType, SourceLocation Loc,
405 bool OBTrapInvolved =
false);
410 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
411 QualType DstType, SourceLocation Loc,
412 bool OBTrapInvolved =
false);
416 struct ScalarConversionOpts {
417 bool TreatBooleanAsSigned;
418 bool EmitImplicitIntegerTruncationChecks;
419 bool EmitImplicitIntegerSignChangeChecks;
421 bool PatternExcluded;
423 ScalarConversionOpts()
424 : TreatBooleanAsSigned(
false),
425 EmitImplicitIntegerTruncationChecks(
false),
426 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
428 ScalarConversionOpts(clang::SanitizerSet SanOpts)
429 : TreatBooleanAsSigned(
false),
430 EmitImplicitIntegerTruncationChecks(
431 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
432 EmitImplicitIntegerSignChangeChecks(
433 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
434 PatternExcluded(
false) {}
436 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
437 llvm::Type *SrcTy, llvm::Type *DstTy,
438 ScalarConversionOpts Opts);
440 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
442 ScalarConversionOpts Opts = ScalarConversionOpts());
446 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
452 QualType SrcTy, QualType DstTy,
456 Value *EmitNullValue(QualType Ty);
461 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
462 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
466 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
469 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
476 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
477 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
483 ZI->eraseFromParent();
488 return Builder.CreateIsNotNull(
V,
"tobool");
495 Value *Visit(Expr *E) {
496 ApplyDebugLocation DL(CGF, E);
497 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
500 Value *VisitStmt(Stmt *S) {
502 llvm_unreachable(
"Stmt can't have complex result type!");
504 Value *VisitExpr(Expr *S);
506 Value *VisitConstantExpr(ConstantExpr *E) {
512 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
527 Value *VisitParenExpr(ParenExpr *PE) {
530 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
533 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
534 return Visit(
GE->getResultExpr());
536 Value *VisitCoawaitExpr(CoawaitExpr *S) {
539 Value *VisitCoyieldExpr(CoyieldExpr *S) {
542 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
547 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
548 return Builder.getInt(E->
getValue());
550 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
551 return Builder.getInt(E->
getValue());
553 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
554 return llvm::ConstantFP::get(VMContext, E->
getValue());
556 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
559 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
562 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
563 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
565 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
566 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
568 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
572 return EmitNullValue(E->
getType());
574 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
575 return EmitNullValue(E->
getType());
577 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
578 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
579 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
581 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
584 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
588 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
592 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
593 Value *VisitEmbedExpr(EmbedExpr *E);
595 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
604 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
605 llvm_unreachable(
"Codegen for this isn't defined/implemented");
609 Value *VisitDeclRefExpr(DeclRefExpr *E) {
612 return EmitLoadOfLValue(E);
615 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
618 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
621 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
622 return EmitLoadOfLValue(E);
624 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
627 return EmitLoadOfLValue(E);
631 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
637 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
643 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
648 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
649 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
650 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
651 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
652 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
653 Value *VisitMemberExpr(MemberExpr *E);
654 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
655 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
656 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
662 return EmitLoadOfLValue(E);
665 Value *VisitInitListExpr(InitListExpr *E);
667 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
669 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
673 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
674 return EmitNullValue(E->
getType());
676 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
678 return VisitCastExpr(E);
682 Value *VisitCallExpr(
const CallExpr *E) {
684 return EmitLoadOfLValue(E);
686 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
690 EmitLValueAlignmentAssumption(E,
V);
694 Value *VisitStmtExpr(
const StmtExpr *E);
697 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
699 return EmitScalarPrePostIncDec(E, LV,
false,
false);
701 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
703 return EmitScalarPrePostIncDec(E, LV,
true,
false);
705 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
707 return EmitScalarPrePostIncDec(E, LV,
false,
true);
709 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
711 return EmitScalarPrePostIncDec(E, LV,
true,
true);
714 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
718 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
719 bool isInc,
bool isPre);
722 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
726 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
728 Value *VisitUnaryDeref(
const UnaryOperator *E) {
731 return EmitLoadOfLValue(E);
734 Value *VisitUnaryPlus(
const UnaryOperator *E,
735 QualType PromotionType = QualType());
736 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
737 Value *VisitUnaryMinus(
const UnaryOperator *E,
738 QualType PromotionType = QualType());
739 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
741 Value *VisitUnaryNot (
const UnaryOperator *E);
742 Value *VisitUnaryLNot (
const UnaryOperator *E);
743 Value *VisitUnaryReal(
const UnaryOperator *E,
744 QualType PromotionType = QualType());
745 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
746 Value *VisitUnaryImag(
const UnaryOperator *E,
747 QualType PromotionType = QualType());
748 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
749 Value *VisitUnaryExtension(
const UnaryOperator *E) {
754 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
755 return EmitLoadOfLValue(E);
757 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
765 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
766 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
769 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
770 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
773 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
777 Value *VisitExprWithCleanups(ExprWithCleanups *E);
778 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
781 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
786 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
788 return llvm::ConstantInt::get(ConvertType(E->
getType()),
792 return llvm::ConstantInt::get(ConvertType(E->
getType()),
796 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
804 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
805 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
808 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
809 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
812 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
822 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
823 return EmitNullValue(E->
getType());
826 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
831 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
832 return Builder.getInt1(E->
getValue());
836 Value *EmitMul(
const BinOpInfo &Ops) {
837 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
838 Ops.Ty->isUnsignedIntegerType()) {
839 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
841 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
842 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
843 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
844 case LangOptions::OB_Wrap:
845 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
846 case LangOptions::OB_SignedAndDefined:
848 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
850 case LangOptions::OB_Unset:
852 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
853 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
855 case LangOptions::OB_Trap:
856 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
857 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
858 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
859 return EmitOverflowCheckedBinOp(Ops);
863 if (Ops.Ty->isConstantMatrixType()) {
864 llvm::MatrixBuilder MB(Builder);
868 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
869 BO->getLHS()->getType().getCanonicalType());
870 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
871 BO->getRHS()->getType().getCanonicalType());
872 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
873 if (LHSMatTy && RHSMatTy)
874 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
875 LHSMatTy->getNumColumns(),
876 RHSMatTy->getNumColumns());
877 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
880 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
882 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
883 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
885 if (Ops.isFixedPointOp())
886 return EmitFixedPointBinOp(Ops);
887 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
891 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
894 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
895 llvm::Value *
Zero,
bool isDiv);
897 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
903 Value *EmitDiv(
const BinOpInfo &Ops);
904 Value *EmitRem(
const BinOpInfo &Ops);
905 Value *EmitAdd(
const BinOpInfo &Ops);
906 Value *EmitSub(
const BinOpInfo &Ops);
907 Value *EmitShl(
const BinOpInfo &Ops);
908 Value *EmitShr(
const BinOpInfo &Ops);
909 Value *EmitAnd(
const BinOpInfo &Ops) {
910 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
912 Value *EmitXor(
const BinOpInfo &Ops) {
913 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
915 Value *EmitOr (
const BinOpInfo &Ops) {
916 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
920 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
922 BinOpInfo EmitBinOps(
const BinaryOperator *E,
923 QualType PromotionTy = QualType());
925 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
926 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
927 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
929 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
930 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
933 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
934 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
936 QualType getPromotionType(QualType Ty) {
938 if (
auto *CT = Ty->
getAs<ComplexType>()) {
939 QualType ElementType = CT->getElementType();
940 if (ElementType.UseExcessPrecision(Ctx))
945 if (
auto *VT = Ty->
getAs<VectorType>()) {
946 unsigned NumElements = VT->getNumElements();
956#define HANDLEBINOP(OP) \
957 Value *VisitBin##OP(const BinaryOperator *E) { \
958 QualType promotionTy = getPromotionType(E->getType()); \
959 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
960 if (result && !promotionTy.isNull()) \
961 result = EmitUnPromotedValue(result, E->getType()); \
964 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
965 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
966 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
982 llvm::CmpInst::Predicate SICmpOpc,
983 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
984#define VISITCOMP(CODE, UI, SI, FP, SIG) \
985 Value *VisitBin##CODE(const BinaryOperator *E) { \
986 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
987 llvm::FCmpInst::FP, SIG); }
988 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
1002 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
1003 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1005 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1010 Value *VisitBlockExpr(
const BlockExpr *BE);
1011 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1012 Value *VisitChooseExpr(ChooseExpr *CE);
1013 Value *VisitVAArgExpr(VAArgExpr *VE);
1014 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1017 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1020 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1023 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1026 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1027 Value *VisitAtomicExpr(AtomicExpr *AE);
1028 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1041 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1044 return EmitFloatToBoolConversion(Src);
1046 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1050 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1054 "Unknown scalar type to convert");
1057 return EmitIntToBoolConversion(Src);
1060 return EmitPointerToBoolConversion(Src, SrcType);
1063void ScalarExprEmitter::EmitFloatConversionCheck(
1064 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1065 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1066 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1070 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1071 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1072 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1073 using llvm::APFloat;
1076 llvm::Value *Check =
nullptr;
1077 const llvm::fltSemantics &SrcSema =
1087 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1088 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1089 APFloat::opOverflow)
1092 MinSrc = APFloat::getInf(SrcSema,
true);
1096 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1099 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1100 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1101 APFloat::opOverflow)
1104 MaxSrc = APFloat::getInf(SrcSema,
false);
1108 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1113 const llvm::fltSemantics &Sema =
1116 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1117 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1121 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1123 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1124 Check = Builder.CreateAnd(GE, LE);
1129 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1135static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1136 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1139 llvm::Type *SrcTy = Src->
getType();
1140 llvm::Type *DstTy = Dst->
getType();
1145 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1147 "non-integer llvm type");
1154 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1156 if (!SrcSigned && !DstSigned) {
1157 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1158 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1160 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1161 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1164 llvm::Value *Check =
nullptr;
1166 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1168 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1170 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1178void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1179 Value *Dst, QualType DstType,
1181 bool OBTrapInvolved) {
1182 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1192 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1193 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1195 if (SrcBits <= DstBits)
1198 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1205 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1206 (!SrcSigned && DstSigned))
1209 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1210 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1213 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1218 SanitizerDebugLocation SanScope(
1220 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1221 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1237 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1245 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1246 if (OBT->isWrapKind())
1249 if (ignoredBySanitizer && !OBTrapInvolved)
1252 llvm::Constant *StaticArgs[] = {
1255 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1256 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1258 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1265 llvm::Type *VTy =
V->getType();
1268 return llvm::ConstantInt::getFalse(VTy->getContext());
1270 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1271 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1272 llvm::Twine(Name) +
"." +
V->getName() +
1273 ".negativitycheck");
1278static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1279 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1282 llvm::Type *SrcTy = Src->
getType();
1283 llvm::Type *DstTy = Dst->
getType();
1286 "non-integer llvm type");
1292 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1293 unsigned DstBits = DstTy->getScalarSizeInBits();
1297 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1298 "either the widths should be different, or the signednesses.");
1301 llvm::Value *SrcIsNegative =
1304 llvm::Value *DstIsNegative =
1310 llvm::Value *Check =
nullptr;
1311 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1313 return std::make_pair(
1314 ScalarExprEmitter::ICCK_IntegerSignChange,
1315 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1318void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1319 Value *Dst, QualType DstType,
1321 bool OBTrapInvolved) {
1322 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1326 llvm::Type *SrcTy = Src->
getType();
1327 llvm::Type *DstTy = Dst->
getType();
1337 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1338 unsigned DstBits = DstTy->getScalarSizeInBits();
1345 if (SrcSigned == DstSigned && SrcBits == DstBits)
1349 if (!SrcSigned && !DstSigned)
1354 if ((DstBits > SrcBits) && DstSigned)
1356 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1357 (SrcBits > DstBits) && SrcSigned) {
1366 if (!OBTrapInvolved) {
1369 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1373 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1378 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1379 SanitizerDebugLocation SanScope(
1381 {SanitizerKind::SO_ImplicitIntegerSignChange,
1382 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1383 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1386 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1387 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1391 ImplicitConversionCheckKind CheckKind;
1392 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1399 CheckKind = Check.first;
1400 Checks.emplace_back(Check.second);
1402 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1403 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1409 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1410 Checks.emplace_back(Check.second);
1414 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1415 if (OBTrapInvolved) {
1416 llvm::Value *Combined = Check.second.first;
1417 for (
const auto &
C : Checks)
1418 Combined = Builder.CreateAnd(Combined,
C.first);
1424 llvm::Constant *StaticArgs[] = {
1427 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1428 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1430 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1435static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1436 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1442 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1443 if (!SrcSigned && !DstSigned)
1444 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1446 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1448 llvm::Value *Check =
nullptr;
1450 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1452 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1455 return std::make_pair(
1457 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1462static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1463 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1467 llvm::Value *SrcIsNegative =
1470 llvm::Value *DstIsNegative =
1476 llvm::Value *Check =
nullptr;
1478 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1480 return std::make_pair(
1481 ScalarExprEmitter::ICCK_IntegerSignChange,
1482 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1490 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1508 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1509 unsigned DstBits = Info.
Size;
1514 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1516 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1518 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1519 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1523 bool EmitTruncation = DstBits < SrcBits;
1527 bool EmitTruncationFromUnsignedToSigned =
1528 EmitTruncation && DstSigned && !SrcSigned;
1530 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1531 bool BothUnsigned = !SrcSigned && !DstSigned;
1532 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1539 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1544 else if (EmitSignChange) {
1545 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1546 "either the widths should be different, or the signednesses.");
1552 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1553 if (EmitTruncationFromUnsignedToSigned)
1554 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1556 llvm::Constant *StaticArgs[] = {
1559 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1560 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1562 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1566 QualType DstType, llvm::Type *SrcTy,
1568 ScalarConversionOpts Opts) {
1570 llvm::Type *SrcElementTy;
1571 llvm::Type *DstElementTy;
1581 "cannot cast between matrix and non-matrix types");
1582 SrcElementTy = SrcTy;
1583 DstElementTy = DstTy;
1584 SrcElementType = SrcType;
1585 DstElementType = DstType;
1590 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1595 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1597 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1598 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1602 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1609 llvm::Intrinsic::ID IID =
1610 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1611 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1615 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1616 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1619 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1620 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1621 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1623 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1624 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1625 return Builder.CreateFPExt(Src, DstTy,
"conv");
1630Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1633 ScalarConversionOpts Opts) {
1648 return Builder.CreateIsNotNull(Src,
"tobool");
1651 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1654 "Unhandled scalar conversion from a fixed point type to another type.");
1658 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1661 "Unhandled scalar conversion to a fixed point type from another type.");
1664 QualType NoncanonicalSrcType = SrcType;
1665 QualType NoncanonicalDstType = DstType;
1669 if (SrcType == DstType)
return Src;
1673 llvm::Value *OrigSrc = Src;
1674 QualType OrigSrcType = SrcType;
1675 llvm::Type *SrcTy = Src->
getType();
1679 return EmitConversionToBool(Src, SrcType);
1681 llvm::Type *DstTy = ConvertType(DstType);
1690 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1691 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1692 bool OBTrapInvolved =
1693 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1694 bool OBWrapInvolved =
1695 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1700 if (DstTy->isFloatingPointTy())
1701 return Builder.CreateFPExt(Src, DstTy,
"conv");
1705 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1711 if (SrcTy == DstTy) {
1712 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1713 (OBTrapInvolved && !OBWrapInvolved))
1714 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1715 NoncanonicalDstType, Loc, OBTrapInvolved);
1723 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1728 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1733 llvm::Value* IntResult =
1734 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1736 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1742 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1749 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1751 "Splatted expr doesn't match with vector element type?");
1755 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1759 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1763 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1764 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1765 if (SrcSize == DstSize)
1766 return Builder.CreateBitCast(Src, DstTy,
"conv");
1779 assert(((SrcElementTy->isIntegerTy() &&
1780 DstElementTy->isIntegerTy()) ||
1781 (SrcElementTy->isFloatingPointTy() &&
1782 DstElementTy->isFloatingPointTy())) &&
1783 "unexpected conversion between a floating-point vector and an "
1787 if (SrcElementTy->isIntegerTy())
1788 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1791 if (SrcSize > DstSize)
1792 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1795 return Builder.CreateFPExt(Src, DstTy,
"conv");
1799 Value *Res =
nullptr;
1800 llvm::Type *ResTy = DstTy;
1807 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1809 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1817 if (SrcTy->isFloatingPointTy())
1818 return Builder.CreateFPTrunc(Src, CGF.
CGM.
HalfTy,
"conv");
1823 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1825 if (DstTy != ResTy) {
1826 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1829 assert(ResTy->isIntegerTy(16) &&
1830 "Only half FP requires extra conversion");
1831 Res = Builder.CreateBitCast(Res, ResTy);
1835 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1836 !OBWrapInvolved && !Opts.PatternExcluded)
1837 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1838 NoncanonicalDstType, Loc, OBTrapInvolved);
1840 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1841 (OBTrapInvolved && !OBWrapInvolved))
1842 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1843 NoncanonicalDstType, Loc, OBTrapInvolved);
1848Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1850 SourceLocation Loc) {
1851 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1854 Result = FPBuilder.CreateFloatingToFixed(Src,
1857 Result = FPBuilder.CreateFixedToFloating(Src,
1859 ConvertType(DstTy));
1865 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1866 DstFPSema.getWidth(),
1867 DstFPSema.isSigned());
1869 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1872 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1879Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1881 SourceLocation Loc) {
1883 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1888 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1889 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1890 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1897 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1900Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1908void ScalarExprEmitter::EmitBinOpCheck(
1909 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1910 const BinOpInfo &Info) {
1913 SmallVector<llvm::Constant *, 4> StaticData;
1914 SmallVector<llvm::Value *, 2> DynamicData;
1922 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1923 if (UO && UO->
getOpcode() == UO_Minus) {
1924 Check = SanitizerHandler::NegateOverflow;
1926 DynamicData.push_back(Info.RHS);
1930 Check = SanitizerHandler::ShiftOutOfBounds;
1932 StaticData.push_back(
1934 StaticData.push_back(
1936 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1938 Check = SanitizerHandler::DivremOverflow;
1942 int ArithOverflowKind = 0;
1945 Check = SanitizerHandler::AddOverflow;
1946 ArithOverflowKind = diag::UBSanArithKind::Add;
1950 Check = SanitizerHandler::SubOverflow;
1951 ArithOverflowKind = diag::UBSanArithKind::Sub;
1955 Check = SanitizerHandler::MulOverflow;
1956 ArithOverflowKind = diag::UBSanArithKind::Mul;
1960 llvm_unreachable(
"unexpected opcode for bin op check");
1964 SanitizerKind::UnsignedIntegerOverflow) ||
1966 SanitizerKind::SignedIntegerOverflow)) {
1970 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1974 DynamicData.push_back(Info.LHS);
1975 DynamicData.push_back(Info.RHS);
1978 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1985Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1993ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1995 unsigned AddrSpace =
1997 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2000 llvm::Type *ExprTy = ConvertType(E->
getType());
2001 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2005Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2007 auto It = E->
begin();
2008 return Builder.getInt((*It)->getValue());
2011Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2019 unsigned LHSElts = LTy->getNumElements();
2027 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2028 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2036 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2037 MTy->getNumElements());
2038 Value* NewV = llvm::PoisonValue::get(RTy);
2039 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2040 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2041 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2043 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2044 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2052 SmallVector<int, 32> Indices;
2056 if (Idx.isSigned() && Idx.isAllOnes())
2057 Indices.push_back(-1);
2059 Indices.push_back(Idx.getZExtValue());
2062 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2065Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2073 if (SrcType == DstType)
return Src;
2076 "ConvertVector source type must be a vector");
2078 "ConvertVector destination type must be a vector");
2080 llvm::Type *SrcTy = Src->
getType();
2081 llvm::Type *DstTy = ConvertType(DstType);
2087 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2088 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2090 assert(SrcTy->isVectorTy() &&
2091 "ConvertVector source IR type must be a vector");
2092 assert(DstTy->isVectorTy() &&
2093 "ConvertVector destination IR type must be a vector");
2098 if (DstEltType->isBooleanType()) {
2099 assert((SrcEltTy->isFloatingPointTy() ||
2102 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2103 if (SrcEltTy->isFloatingPointTy()) {
2104 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2105 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2107 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2112 Value *Res =
nullptr;
2117 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2119 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2121 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2123 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2126 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2127 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2128 if (DstEltType->isSignedIntegerOrEnumerationType())
2129 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2131 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2133 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2134 "Unknown real conversion");
2135 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2136 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2137 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2139 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2145Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2154 return Builder.getInt(
Value);
2158 llvm::Value *
Result = EmitLoadOfLValue(E);
2164 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2165 if (llvm::GetElementPtrInst *GEP =
2166 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2167 if (llvm::Instruction *
Pointer =
2168 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2180Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2181 TestAndClearIgnoreResultAssign();
2189 return EmitLoadOfLValue(E);
2197 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2200 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2204 Ret = Builder.CreateInsertElement(
2205 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2211Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2212 MatrixSingleSubscriptExpr *E) {
2213 TestAndClearIgnoreResultAssign();
2216 unsigned NumRows = MatrixTy->getNumRows();
2217 unsigned NumColumns = MatrixTy->getNumColumns();
2221 llvm::MatrixBuilder MB(Builder);
2225 MB.CreateIndexAssumption(RowIdx, NumRows);
2229 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2230 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2232 bool IsMatrixRowMajor =
2235 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2236 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2237 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2238 IsMatrixRowMajor,
"matrix_row_idx");
2240 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2241 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2242 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2248Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2249 TestAndClearIgnoreResultAssign();
2257 llvm::MatrixBuilder MB(Builder);
2260 unsigned NumCols = MatrixTy->getNumColumns();
2261 unsigned NumRows = MatrixTy->getNumRows();
2262 bool IsMatrixRowMajor =
2264 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2267 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2272 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2277 int MV = SVI->getMaskValue(Idx);
2284 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2285 "Index operand too large for shufflevector mask!");
2286 return C->getZExtValue();
2289Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2290 bool Ignore = TestAndClearIgnoreResultAssign();
2293 assert((Ignore ==
false ||
2295 "init list ignored");
2312 llvm::VectorType *VType =
2313 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2316 if (NumInitElements == 0) {
2318 return EmitNullValue(E->
getType());
2325 if (NumInitElements == 0) {
2327 return EmitNullValue(E->
getType());
2330 if (NumInitElements == 1) {
2331 Expr *InitVector = E->
getInit(0);
2336 return Visit(InitVector);
2339 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2346 const ConstantMatrixType *ColMajorMT =
nullptr;
2347 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2356 unsigned CurIdx = 0;
2357 bool VIsPoisonShuffle =
false;
2358 llvm::Value *
V = llvm::PoisonValue::get(VType);
2359 for (
unsigned i = 0; i != NumInitElements; ++i) {
2362 SmallVector<int, 16> Args;
2364 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2374 ->getNumElements() == ResElts) {
2376 Value *LHS =
nullptr, *RHS =
nullptr;
2381 Args.resize(ResElts, -1);
2383 LHS = EI->getVectorOperand();
2385 VIsPoisonShuffle =
true;
2386 }
else if (VIsPoisonShuffle) {
2389 for (
unsigned j = 0; j != CurIdx; ++j)
2391 Args.push_back(ResElts +
C->getZExtValue());
2392 Args.resize(ResElts, -1);
2395 RHS = EI->getVectorOperand();
2396 VIsPoisonShuffle =
false;
2398 if (!Args.empty()) {
2399 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2405 unsigned InsertIdx =
2409 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2411 VIsPoisonShuffle =
false;
2421 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2424 Value *SVOp = SVI->getOperand(0);
2427 if (OpTy->getNumElements() == ResElts) {
2428 for (
unsigned j = 0; j != CurIdx; ++j) {
2431 if (VIsPoisonShuffle) {
2437 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2439 Args.resize(ResElts, -1);
2441 if (VIsPoisonShuffle)
2451 for (
unsigned j = 0; j != InitElts; ++j)
2453 Args.resize(ResElts, -1);
2454 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2457 for (
unsigned j = 0; j != CurIdx; ++j)
2459 for (
unsigned j = 0; j != InitElts; ++j)
2460 Args.push_back(j + Offset);
2461 Args.resize(ResElts, -1);
2468 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2475 llvm::Type *EltTy = VType->getElementType();
2478 for (; CurIdx < ResElts; ++CurIdx) {
2479 unsigned InsertIdx =
2482 Value *Idx = Builder.getInt32(InsertIdx);
2483 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2484 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2497 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2501 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2504 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2523 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2527 if (
const auto *CE = dyn_cast<CastExpr>(E))
2528 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2529 CE->getCastKind() == CK_ArrayToPointerDecay)
2540 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2550 if (ICE->isGLValue())
2565 assert(LoadList.size() >= VecTy->getNumElements() &&
2566 "Flattened type on RHS must have the same number or more elements "
2567 "than vector on LHS.");
2571 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2574 "All flattened source values should be scalars.");
2577 VecTy->getElementType(), Loc);
2578 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2583 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2584 "Flattened type on RHS must have the same number or more elements "
2585 "than vector on LHS.");
2592 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2593 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2596 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2599 "All flattened source values should be scalars.");
2602 MatTy->getElementType(), Loc);
2603 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2604 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2611 "Destination type must be a vector, matrix, or builtin type.");
2613 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2622 llvm::scope_exit RestoreCurCast(
2623 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2627 QualType DestTy = CE->
getType();
2629 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2633 bool Ignored = TestAndClearIgnoreResultAssign();
2639 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2640 case CK_BuiltinFnToFnPtr:
2641 llvm_unreachable(
"builtin functions are handled elsewhere");
2643 case CK_LValueBitCast:
2644 case CK_ObjCObjectLValueCast: {
2648 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2651 case CK_LValueToRValueBitCast: {
2657 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2660 case CK_CPointerToObjCPointerCast:
2661 case CK_BlockPointerToObjCPointerCast:
2662 case CK_AnyPointerToBlockPointerCast:
2664 Value *Src = Visit(E);
2665 llvm::Type *SrcTy = Src->
getType();
2666 llvm::Type *DstTy = ConvertType(DestTy);
2677 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2691 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2692 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2697 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2698 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2699 "Address-space cast must be used to convert address spaces");
2701 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2702 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2704 PT->getPointeeType(),
2715 const QualType SrcType = E->
getType();
2720 Src = Builder.CreateLaunderInvariantGroup(Src);
2725 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2729 if (!PointeeType.
isNull())
2738 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2739 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2742 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2743 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2744 ScalableDstTy = llvm::ScalableVectorType::get(
2745 FixedSrcTy->getElementType(),
2747 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2749 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2750 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2751 llvm::Value *
Result = Builder.CreateInsertVector(
2752 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2754 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2755 if (
Result->getType() != ScalableDstTy)
2757 if (
Result->getType() != DstTy)
2767 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2768 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2771 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2772 FixedDstTy->getElementType()->isIntegerTy(8)) {
2773 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2774 ScalableSrcTy = llvm::ScalableVectorType::get(
2775 ScalableSrcTy->getElementType(),
2777 ScalableSrcTy->getElementCount().getKnownMinValue()));
2778 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2779 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2783 ScalableSrcTy = llvm::ScalableVectorType::get(
2784 FixedDstTy->getElementType(),
2785 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2786 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2788 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2789 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2810 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2813 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2816 case CK_AddressSpaceConversion: {
2817 llvm::Type *DestLTy = ConvertType(DestTy);
2820 auto IsWasmFuncref = [](llvm::Type *
T) {
2821 auto *TET = dyn_cast<llvm::TargetExtType>(
T);
2822 return TET && TET->getName() ==
"wasm.funcref";
2824 bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->
getType()));
2825 bool DestIsFuncref = IsWasmFuncref(DestLTy);
2826 if (SrcIsFuncref && DestIsFuncref) {
2831 if (SrcIsFuncref && !DestIsFuncref) {
2835 llvm::Function *ToPtr =
2837 return CGF.
Builder.CreateCall(ToPtr, {Visit(E)});
2839 if (!SrcIsFuncref && DestIsFuncref) {
2842 Expr::EvalResult NullResult;
2847 return llvm::Constant::getNullValue(DestLTy);
2850 llvm::Function *ToFuncref =
2852 return CGF.
Builder.CreateCall(ToFuncref, {Visit(E)});
2856 Result.Val.isNullPointer()) {
2860 if (
Result.HasSideEffects)
2868 case CK_AtomicToNonAtomic:
2869 case CK_NonAtomicToAtomic:
2870 case CK_UserDefinedConversion:
2877 case CK_BaseToDerived: {
2879 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2893 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2901 case CK_UncheckedDerivedToBase:
2902 case CK_DerivedToBase: {
2915 case CK_ArrayToPointerDecay:
2918 case CK_FunctionToPointerDecay:
2919 return EmitLValue(E).getPointer(CGF);
2921 case CK_NullToPointer:
2922 if (MustVisitNullValue(E))
2928 case CK_NullToMemberPointer: {
2929 if (MustVisitNullValue(E))
2932 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2936 case CK_ReinterpretMemberPointer:
2937 case CK_BaseToDerivedMemberPointer:
2938 case CK_DerivedToBaseMemberPointer: {
2939 Value *Src = Visit(E);
2950 case CK_ARCProduceObject:
2952 case CK_ARCConsumeObject:
2954 case CK_ARCReclaimReturnedObject:
2956 case CK_ARCExtendBlockObject:
2959 case CK_CopyAndAutoreleaseBlockObject:
2962 case CK_FloatingRealToComplex:
2963 case CK_FloatingComplexCast:
2964 case CK_IntegralRealToComplex:
2965 case CK_IntegralComplexCast:
2966 case CK_IntegralComplexToFloatingComplex:
2967 case CK_FloatingComplexToIntegralComplex:
2968 case CK_ConstructorConversion:
2970 case CK_HLSLArrayRValue:
2971 llvm_unreachable(
"scalar cast to non-scalar value");
2973 case CK_LValueToRValue:
2975 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2978 case CK_IntegralToPointer: {
2979 Value *Src = Visit(E);
2983 auto DestLLVMTy = ConvertType(DestTy);
2986 llvm::Value* IntResult =
2987 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2989 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2995 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
3001 case CK_PointerToIntegral: {
3002 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
3005 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3011 case CK_MatrixCast: {
3012 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3019 case CK_HLSLAggregateSplatCast:
3020 case CK_VectorSplat: {
3021 llvm::Type *DstTy = ConvertType(DestTy);
3022 Value *Elt = Visit(E);
3024 llvm::ElementCount NumElements =
3026 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3029 case CK_FixedPointCast:
3030 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3033 case CK_FixedPointToBoolean:
3035 "Expected src type to be fixed point type");
3036 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3037 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3040 case CK_FixedPointToIntegral:
3042 "Expected src type to be fixed point type");
3043 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3044 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3047 case CK_IntegralToFixedPoint:
3049 "Expected src type to be an integer");
3051 "Expected dest type to be fixed point type");
3052 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3055 case CK_IntegralCast: {
3057 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3058 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3062 ScalarConversionOpts Opts;
3063 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3064 if (!ICE->isPartOfExplicitCast())
3065 Opts = ScalarConversionOpts(CGF.
SanOpts);
3067 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3070 case CK_IntegralToFloating: {
3073 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3075 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3076 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3078 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3079 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3082 case CK_FloatingToIntegral: {
3085 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3087 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3088 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3090 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3091 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3094 case CK_FloatingCast: {
3097 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3098 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3099 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3100 SrcElTy->
castAs<BuiltinType>()->getKind())
3101 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3102 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3104 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3105 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3108 case CK_FixedPointToFloating:
3109 case CK_FloatingToFixedPoint: {
3110 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3111 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3114 case CK_BooleanToSignedIntegral: {
3115 ScalarConversionOpts Opts;
3116 Opts.TreatBooleanAsSigned =
true;
3117 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3120 case CK_IntegralToBoolean:
3121 return EmitIntToBoolConversion(Visit(E));
3122 case CK_PointerToBoolean:
3123 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3124 case CK_FloatingToBoolean: {
3125 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3126 return EmitFloatToBoolConversion(Visit(E));
3128 case CK_MemberPointerToBoolean: {
3129 llvm::Value *MemPtr = Visit(E);
3130 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3134 case CK_FloatingComplexToReal:
3135 case CK_IntegralComplexToReal:
3138 case CK_FloatingComplexToBoolean:
3139 case CK_IntegralComplexToBoolean: {
3143 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3147 case CK_ZeroToOCLOpaqueType: {
3150 "CK_ZeroToOCLEvent cast on non-event type");
3151 return llvm::Constant::getNullValue(ConvertType(DestTy));
3154 case CK_IntToOCLSampler:
3157 case CK_HLSLVectorTruncation: {
3159 "Destination type must be a vector or builtin type.");
3160 Value *Vec = Visit(E);
3161 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3162 SmallVector<int> Mask;
3163 unsigned NumElts = VecTy->getNumElements();
3164 for (
unsigned I = 0; I != NumElts; ++I)
3167 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3169 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3170 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3172 case CK_HLSLMatrixTruncation: {
3174 "Destination type must be a matrix or builtin type.");
3175 Value *Mat = Visit(E);
3176 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3177 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3178 unsigned NumCols = MatTy->getNumColumns();
3179 unsigned NumRows = MatTy->getNumRows();
3180 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3181 assert(SrcMatTy &&
"Source type must be a matrix type.");
3182 assert(NumRows <= SrcMatTy->getNumRows());
3183 assert(NumCols <= SrcMatTy->getNumColumns());
3190 for (
unsigned R = 0;
R < NumRows;
R++)
3191 for (
unsigned C = 0;
C < NumCols;
C++)
3192 Mask[MatTy->getFlattenedIndex(R,
C, IsDstRowMajor)] =
3193 SrcMatTy->getFlattenedIndex(R,
C, IsSrcRowMajor);
3195 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3197 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3198 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3200 case CK_HLSLElementwiseCast: {
3220 llvm_unreachable(
"unknown scalar cast");
3223Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3224 CodeGenFunction::StmtExprEvaluation eval(CGF);
3233Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3234 CodeGenFunction::RunCleanupsScope Scope(CGF);
3238 Scope.ForceCleanup({&
V});
3247 llvm::Value *InVal,
bool IsInc,
3251 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3253 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3254 BinOp.FPFeatures = FPFeatures;
3259llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3260 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3263 llvm::Value *Amount =
3264 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3265 StringRef Name = IsInc ?
"inc" :
"dec";
3269 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3270 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3272 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3273 case LangOptions::OB_Wrap:
3274 return Builder.CreateAdd(InVal, Amount, Name);
3275 case LangOptions::OB_SignedAndDefined:
3277 return Builder.CreateAdd(InVal, Amount, Name);
3279 case LangOptions::OB_Unset:
3281 return Builder.CreateAdd(InVal, Amount, Name);
3283 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3284 : Builder.CreateAdd(InVal, Amount, Name);
3286 case LangOptions::OB_Trap:
3288 return Builder.CreateAdd(InVal, Amount, Name);
3291 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3292 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3293 : Builder.CreateAdd(InVal, Amount, Name);
3294 return EmitOverflowCheckedBinOp(Info);
3296 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3301class OMPLastprivateConditionalUpdateRAII {
3303 CodeGenFunction &CGF;
3304 const UnaryOperator *E;
3307 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3308 const UnaryOperator *E)
3310 ~OMPLastprivateConditionalUpdateRAII() {
3319ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3320 bool isInc,
bool isPre) {
3322 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3324 llvm::PHINode *atomicPHI =
nullptr;
3328 QualType SrcType = E->
getType();
3330 int amount = (isInc ? 1 : -1);
3331 bool isSubtraction = !isInc;
3333 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3334 type = atomicTy->getValueType();
3335 if (isInc &&
type->isBooleanType()) {
3338 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3339 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3340 return Builder.getTrue();
3344 return Builder.CreateAtomicRMW(
3345 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3346 llvm::AtomicOrdering::SequentiallyConsistent);
3351 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3352 !(
type->isUnsignedIntegerType() &&
3353 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3355 LangOptions::SOB_Trapping) {
3356 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3357 llvm::AtomicRMWInst::Sub;
3358 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3359 llvm::Instruction::Sub;
3361 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3363 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3364 llvm::AtomicOrdering::SequentiallyConsistent);
3365 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3369 if (
type->isFloatingType()) {
3370 llvm::Type *Ty = ConvertType(
type);
3371 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3372 llvm::AtomicRMWInst::BinOp aop =
3373 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3374 llvm::Instruction::BinaryOps op =
3375 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3376 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3377 llvm::AtomicRMWInst *old =
3379 llvm::AtomicOrdering::SequentiallyConsistent);
3381 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3384 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3387 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3390 Builder.CreateBr(opBB);
3391 Builder.SetInsertPoint(opBB);
3392 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3393 atomicPHI->addIncoming(value, startBB);
3396 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3407 if (isInc &&
type->isBooleanType()) {
3408 value = Builder.getTrue();
3411 }
else if (
type->isIntegerType()) {
3412 QualType promotedType;
3413 bool canPerformLossyDemotionCheck =
false;
3417 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3418 canPerformLossyDemotionCheck =
true;
3419 canPerformLossyDemotionCheck &=
3422 canPerformLossyDemotionCheck &=
3424 type, promotedType);
3425 assert((!canPerformLossyDemotionCheck ||
3426 type->isSignedIntegerOrEnumerationType() ||
3428 ConvertType(
type)->getScalarSizeInBits() ==
3429 ConvertType(promotedType)->getScalarSizeInBits()) &&
3430 "The following check expects that if we do promotion to different "
3431 "underlying canonical type, at least one of the types (either "
3432 "base or promoted) will be signed, or the bitwidths will match.");
3435 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3436 SanitizerKind::ImplicitBitfieldConversion) &&
3437 canPerformLossyDemotionCheck) {
3451 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3452 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3453 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3457 ScalarConversionOpts Opts;
3458 if (!LV.isBitField())
3459 Opts = ScalarConversionOpts(CGF.
SanOpts);
3460 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3462 SrcType = promotedType;
3466 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3472 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3473 type->isUnsignedIntegerType()) {
3474 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3479 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3480 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3484 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3485 QualType
type = ptr->getPointeeType();
3488 if (
const VariableArrayType *vla
3491 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3494 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3497 elemTy, value, numElts,
false, isSubtraction,
3501 }
else if (
type->isFunctionType()) {
3502 llvm::Value *amt = Builder.getInt32(amount);
3505 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3509 false, isSubtraction,
3514 llvm::Value *amt = Builder.getInt32(amount);
3517 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3520 elemTy, value, amt,
false, isSubtraction,
3525 }
else if (
type->isVectorType()) {
3526 if (
type->hasIntegerRepresentation()) {
3527 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3529 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3531 value = Builder.CreateFAdd(
3533 llvm::ConstantFP::get(value->getType(), amount),
3534 isInc ?
"inc" :
"dec");
3538 }
else if (
type->isRealFloatingType()) {
3541 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3547 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3550 if (value->getType()->isFloatTy())
3551 amt = llvm::ConstantFP::get(VMContext,
3552 llvm::APFloat(
static_cast<float>(amount)));
3553 else if (value->getType()->isDoubleTy())
3554 amt = llvm::ConstantFP::get(VMContext,
3555 llvm::APFloat(
static_cast<double>(amount)));
3559 llvm::APFloat F(
static_cast<float>(amount));
3561 const llvm::fltSemantics *FS;
3564 if (value->getType()->isFP128Ty())
3566 else if (value->getType()->isHalfTy())
3568 else if (value->getType()->isBFloatTy())
3570 else if (value->getType()->isPPC_FP128Ty())
3574 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3575 amt = llvm::ConstantFP::get(VMContext, F);
3577 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3580 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3581 value = Builder.CreateBitCast(value, input->getType());
3585 }
else if (
type->isFixedPointType()) {
3592 Info.Opcode = isInc ? BO_Add : BO_Sub;
3594 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3597 if (
type->isSignedFixedPointType()) {
3598 Info.Opcode = isInc ? BO_Sub : BO_Add;
3599 Info.RHS = Builder.CreateNeg(Info.RHS);
3604 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3606 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3607 value = EmitFixedPointBinOp(Info);
3611 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3614 if (!isInc) size = -size;
3615 llvm::Value *sizeValue =
3616 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3619 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3622 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3624 value = Builder.CreateBitCast(value, input->getType());
3628 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3633 llvm::Value *
success = Pair.second;
3634 atomicPHI->addIncoming(old, curBlock);
3635 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3636 Builder.SetInsertPoint(contBB);
3637 return isPre ? value : input;
3641 if (LV.isBitField()) {
3651 return isPre ? value : input;
3655Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3656 QualType PromotionType) {
3657 QualType promotionTy = PromotionType.
isNull()
3660 Value *result = VisitPlus(E, promotionTy);
3661 if (result && !promotionTy.
isNull())
3662 result = EmitUnPromotedValue(result, E->
getType());
3666Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3667 QualType PromotionType) {
3669 TestAndClearIgnoreResultAssign();
3670 if (!PromotionType.
isNull())
3675Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3676 QualType PromotionType) {
3677 QualType promotionTy = PromotionType.
isNull()
3680 Value *result = VisitMinus(E, promotionTy);
3681 if (result && !promotionTy.
isNull())
3682 result = EmitUnPromotedValue(result, E->
getType());
3686Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3687 QualType PromotionType) {
3688 TestAndClearIgnoreResultAssign();
3690 if (!PromotionType.
isNull())
3696 if (Op->
getType()->isFPOrFPVectorTy()) {
3697 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3698 return Builder.CreateFNeg(Op,
"fneg");
3704 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3706 BinOp.Opcode = BO_Sub;
3709 return EmitSub(BinOp);
3712Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3713 TestAndClearIgnoreResultAssign();
3715 return Builder.CreateNot(Op,
"not");
3718Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3722 VectorKind::Generic) {
3726 if (Oper->
getType()->isFPOrFPVectorTy()) {
3727 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3729 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3731 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3732 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3741 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3744 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3747Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3749 Expr::EvalResult EVResult;
3752 return Builder.getInt(
Value);
3757 llvm::Type* ResultType = ConvertType(E->
getType());
3758 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3760 for (
unsigned i = 0; i != n; ++i) {
3762 llvm::Value *Offset =
nullptr;
3769 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3776 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3780 Offset = Builder.CreateMul(Idx, ElemSize);
3785 FieldDecl *MemberDecl = ON.
getField();
3795 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3798 CurrentType = MemberDecl->
getType();
3803 llvm_unreachable(
"dependent __builtin_offsetof");
3820 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3832ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3833 const UnaryExprOrTypeTraitExpr *E) {
3836 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3837 if (
const VariableArrayType *VAT =
3842 bool EvaluateExtent =
true;
3843 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3845 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3847 if (EvaluateExtent) {
3858 if (Kind == UETT_CountOf)
3867 if (!eltSize.
isOne())
3870 return VlaSize.NumElts;
3873 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3879 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3880 }
else if (E->
getKind() == UETT_VectorElements) {
3882 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3890Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3891 QualType PromotionType) {
3892 QualType promotionTy = PromotionType.
isNull()
3895 Value *result = VisitReal(E, promotionTy);
3896 if (result && !promotionTy.
isNull())
3897 result = EmitUnPromotedValue(result, E->
getType());
3901Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3902 QualType PromotionType) {
3909 if (!PromotionType.
isNull()) {
3911 Op, IgnoreResultAssign,
true);
3926 if (!PromotionType.
isNull())
3931Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3932 QualType PromotionType) {
3933 QualType promotionTy = PromotionType.
isNull()
3936 Value *result = VisitImag(E, promotionTy);
3937 if (result && !promotionTy.
isNull())
3938 result = EmitUnPromotedValue(result, E->
getType());
3942Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3943 QualType PromotionType) {
3950 if (!PromotionType.
isNull()) {
3952 Op,
true, IgnoreResultAssign);
3956 return result.second
3972 else if (!PromotionType.
isNull())
3976 if (!PromotionType.
isNull())
3977 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3978 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3985Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3986 QualType PromotionType) {
3987 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3990Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3991 QualType ExprType) {
3992 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3995Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3997 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3999#define HANDLE_BINOP(OP) \
4001 return Emit##OP(EmitBinOps(BO, PromotionType));
4010 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4013 return VisitImag(UO, PromotionType);
4015 return VisitReal(UO, PromotionType);
4017 return VisitMinus(UO, PromotionType);
4019 return VisitPlus(UO, PromotionType);
4024 auto result = Visit(
const_cast<Expr *
>(E));
4026 if (!PromotionType.
isNull())
4027 return EmitPromotedValue(result, PromotionType);
4029 return EmitUnPromotedValue(result, E->
getType());
4034BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4035 QualType PromotionType) {
4036 TestAndClearIgnoreResultAssign();
4040 if (!PromotionType.
isNull())
4041 Result.Ty = PromotionType;
4050LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4051 const CompoundAssignOperator *E,
4052 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4063 QualType PromotionTypeCR;
4065 if (PromotionTypeCR.
isNull())
4068 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4069 if (!PromotionTypeRHS.
isNull())
4072 OpInfo.RHS = Visit(E->
getRHS());
4073 OpInfo.Ty = PromotionTypeCR;
4080 llvm::PHINode *atomicPHI =
nullptr;
4081 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4083 QualType AtomicValueTy = atomicTy->getValueType();
4092 bool CanEmitAtomicRMW;
4094 llvm::Type *IRTy = CGF.
ConvertType(AtomicValueTy);
4098 !OpInfo.FPFeatures.isFPConstrained() &&
4100 llvm::isPowerOf2_64(StoreBits);
4106 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4108 LangOptions::SOB_Trapping;
4110 if (CanEmitAtomicRMW) {
4111 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4112 llvm::Instruction::BinaryOps Op;
4114 switch (OpInfo.Opcode) {
4116 AtomicOp = llvm::AtomicRMWInst::FAdd;
4117 Op = llvm::Instruction::FAdd;
4120 AtomicOp = llvm::AtomicRMWInst::FSub;
4121 Op = llvm::Instruction::FSub;
4127 switch (OpInfo.Opcode) {
4129 case BO_MulAssign:
case BO_DivAssign:
4135 AtomicOp = llvm::AtomicRMWInst::Add;
4136 Op = llvm::Instruction::Add;
4139 AtomicOp = llvm::AtomicRMWInst::Sub;
4140 Op = llvm::Instruction::Sub;
4143 AtomicOp = llvm::AtomicRMWInst::And;
4144 Op = llvm::Instruction::And;
4147 AtomicOp = llvm::AtomicRMWInst::Xor;
4148 Op = llvm::Instruction::Xor;
4151 AtomicOp = llvm::AtomicRMWInst::Or;
4152 Op = llvm::Instruction::Or;
4155 llvm_unreachable(
"Invalid compound assignment type");
4158 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4160 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4164 llvm::AtomicRMWInst *OldVal =
4169 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4175 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4177 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4178 OpInfo.LHS = CGF.
EmitToMemory(OpInfo.LHS, AtomicValueTy);
4179 Builder.CreateBr(opBB);
4180 Builder.SetInsertPoint(opBB);
4181 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4182 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4183 OpInfo.LHS = atomicPHI;
4186 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4188 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4190 if (!PromotionTypeLHS.
isNull())
4191 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4194 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4205 if (LHSLV.isBitField()) {
4207 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4208 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4210 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4211 Loc, ScalarConversionOpts(CGF.
SanOpts));
4213 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4214 ScalarConversionOpts(CGF.
SanOpts));
4218 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4222 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4223 llvm::Value *
success = Pair.second;
4224 atomicPHI->addIncoming(old, curBlock);
4225 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4226 Builder.SetInsertPoint(contBB);
4234 if (LHSLV.isBitField()) {
4250Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4251 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4252 bool Ignore = TestAndClearIgnoreResultAssign();
4253 Value *RHS =
nullptr;
4254 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4265 if (!LHS.isVolatileQualified())
4269 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4272void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4273 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4274 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4277 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4278 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4279 SanitizerKind::SO_IntegerDivideByZero));
4283 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4284 Ops.Ty->hasSignedIntegerRepresentation() &&
4286 Ops.mayHaveIntegerOverflow() &&
4288 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4291 llvm::Value *IntMin =
4292 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4293 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4295 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4296 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4297 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4299 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4302 if (Checks.size() > 0)
4303 EmitBinOpCheck(Checks, Ops);
4306Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4308 SanitizerDebugLocation SanScope(&CGF,
4309 {SanitizerKind::SO_IntegerDivideByZero,
4310 SanitizerKind::SO_SignedIntegerOverflow,
4311 SanitizerKind::SO_FloatDivideByZero},
4312 SanitizerHandler::DivremOverflow);
4313 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4314 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4315 Ops.Ty->isIntegerType() &&
4316 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4317 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4318 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4319 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4320 Ops.Ty->isRealFloatingType() &&
4321 Ops.mayHaveFloatDivisionByZero()) {
4322 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4323 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4325 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4329 if (Ops.Ty->isConstantMatrixType()) {
4330 llvm::MatrixBuilder MB(Builder);
4337 "first operand must be a matrix");
4339 "second operand must be an arithmetic type");
4340 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4341 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4342 Ops.Ty->hasUnsignedIntegerRepresentation());
4345 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4347 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4348 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4352 else if (Ops.isFixedPointOp())
4353 return EmitFixedPointBinOp(Ops);
4354 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4355 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4357 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4360Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4362 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4363 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4364 Ops.Ty->isIntegerType() &&
4365 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4366 SanitizerDebugLocation SanScope(&CGF,
4367 {SanitizerKind::SO_IntegerDivideByZero,
4368 SanitizerKind::SO_SignedIntegerOverflow},
4369 SanitizerHandler::DivremOverflow);
4370 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4371 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4374 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4375 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4377 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4378 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4380 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4383Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4388 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4389 switch (Ops.Opcode) {
4393 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4394 llvm::Intrinsic::uadd_with_overflow;
4395 OverflowKind = SanitizerHandler::AddOverflow;
4400 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4401 llvm::Intrinsic::usub_with_overflow;
4402 OverflowKind = SanitizerHandler::SubOverflow;
4407 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4408 llvm::Intrinsic::umul_with_overflow;
4409 OverflowKind = SanitizerHandler::MulOverflow;
4412 llvm_unreachable(
"Unsupported operation for overflow detection");
4418 SanitizerDebugLocation SanScope(&CGF,
4419 {SanitizerKind::SO_SignedIntegerOverflow,
4420 SanitizerKind::SO_UnsignedIntegerOverflow},
4426 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4427 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4428 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4431 const std::string *handlerName =
4433 if (handlerName->empty()) {
4439 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4440 llvm::Value *NotOf = Builder.CreateNot(overflow);
4442 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4445 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4448 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4449 llvm::Value *NotOf = Builder.CreateNot(overflow);
4451 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4454 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4459 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4460 llvm::BasicBlock *continueBB =
4464 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4468 Builder.SetInsertPoint(overflowBB);
4471 llvm::Type *Int8Ty = CGF.
Int8Ty;
4472 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4473 llvm::FunctionType *handlerTy =
4474 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4475 llvm::FunctionCallee handler =
4480 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4481 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4485 llvm::Value *handlerArgs[] = {
4488 Builder.getInt8(OpID),
4491 llvm::Value *handlerResult =
4495 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4496 Builder.CreateBr(continueBB);
4498 Builder.SetInsertPoint(continueBB);
4499 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4500 phi->addIncoming(result, initialBB);
4501 phi->addIncoming(handlerResult, overflowBB);
4510 bool isSubtraction) {
4515 Value *pointer = op.LHS;
4516 Expr *pointerOperand =
expr->getLHS();
4518 Expr *indexOperand =
expr->getRHS();
4521 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4522 std::swap(pointer,
index);
4523 std::swap(pointerOperand, indexOperand);
4527 index, isSubtraction);
4533 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4537 auto &DL =
CGM.getDataLayout();
4560 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4562 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4563 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4564 PtrTy->getPointerAddressSpace()))
4567 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4568 auto CheckHandler = SanitizerHandler::PointerOverflow;
4570 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4572 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4573 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4575 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4576 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4581 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4592 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4602 llvm::Value *objectSize =
4608 return Builder.CreateBitCast(result, pointer->getType());
4613 getContext().getAsVariableArrayType(elementType)) {
4615 llvm::Value *numElements =
getVLASize(vla).NumElts;
4624 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4644 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4657 bool negMul,
bool negAdd) {
4658 Value *MulOp0 = MulOp->getOperand(0);
4659 Value *MulOp1 = MulOp->getOperand(1);
4661 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4663 Addend = Builder.CreateFNeg(Addend,
"neg");
4665 Value *FMulAdd =
nullptr;
4666 if (Builder.getIsFPConstrained()) {
4668 "Only constrained operation should be created when Builder is in FP "
4669 "constrained mode");
4670 FMulAdd = Builder.CreateConstrainedFPCall(
4671 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4673 {MulOp0, MulOp1, Addend});
4675 FMulAdd = Builder.CreateCall(
4677 {MulOp0, MulOp1, Addend});
4679 MulOp->eraseFromParent();
4694 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4695 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4696 "Only fadd/fsub can be the root of an fmuladd.");
4699 if (!op.FPFeatures.allowFPContractWithinStatement())
4702 Value *LHS = op.LHS;
4703 Value *RHS = op.RHS;
4707 bool NegLHS =
false;
4708 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4709 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4710 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4711 LHS = LHSUnOp->getOperand(0);
4716 bool NegRHS =
false;
4717 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4718 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4719 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4720 RHS = RHSUnOp->getOperand(0);
4728 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4729 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4730 (LHSBinOp->use_empty() || NegLHS)) {
4734 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4737 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4738 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4739 (RHSBinOp->use_empty() || NegRHS)) {
4743 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4747 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4748 if (LHSBinOp->getIntrinsicID() ==
4749 llvm::Intrinsic::experimental_constrained_fmul &&
4750 (LHSBinOp->use_empty() || NegLHS)) {
4754 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4757 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4758 if (RHSBinOp->getIntrinsicID() ==
4759 llvm::Intrinsic::experimental_constrained_fmul &&
4760 (RHSBinOp->use_empty() || NegRHS)) {
4764 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4771Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4772 if (op.LHS->getType()->isPointerTy() ||
4773 op.RHS->getType()->isPointerTy())
4776 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4777 op.Ty->isUnsignedIntegerType()) {
4778 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4780 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4781 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4782 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4783 case LangOptions::OB_Wrap:
4784 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4785 case LangOptions::OB_SignedAndDefined:
4787 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4789 case LangOptions::OB_Unset:
4791 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4792 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4794 case LangOptions::OB_Trap:
4795 if (CanElideOverflowCheck(CGF.
getContext(), op))
4796 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4797 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4798 return EmitOverflowCheckedBinOp(op);
4803 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4804 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4810 if (op.Ty->isConstantMatrixType()) {
4811 llvm::MatrixBuilder MB(Builder);
4812 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4813 return MB.CreateAdd(op.LHS, op.RHS);
4816 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4817 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4818 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4821 if (op.isFixedPointOp())
4822 return EmitFixedPointBinOp(op);
4824 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4829Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4831 using llvm::ConstantInt;
4837 QualType ResultTy = op.Ty;
4838 QualType LHSTy, RHSTy;
4839 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4840 RHSTy = BinOp->getRHS()->getType();
4841 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4846 LHSTy = CAO->getComputationLHSType();
4847 ResultTy = CAO->getComputationResultType();
4849 LHSTy = BinOp->getLHS()->getType();
4850 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4851 LHSTy = UnOp->getSubExpr()->getType();
4852 RHSTy = UnOp->getSubExpr()->getType();
4855 Value *LHS = op.LHS;
4856 Value *RHS = op.RHS;
4861 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4865 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4866 switch (op.Opcode) {
4869 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4873 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4877 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4881 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4885 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4889 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4892 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4894 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4896 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4898 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4903 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4905 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4909 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4922 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4928 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4933Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4935 if (!op.LHS->getType()->isPointerTy()) {
4936 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4937 op.Ty->isUnsignedIntegerType()) {
4938 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4940 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4941 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4942 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4943 case LangOptions::OB_Wrap:
4944 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4945 case LangOptions::OB_SignedAndDefined:
4947 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4949 case LangOptions::OB_Unset:
4951 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4952 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4954 case LangOptions::OB_Trap:
4955 if (CanElideOverflowCheck(CGF.
getContext(), op))
4956 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4957 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4958 return EmitOverflowCheckedBinOp(op);
4963 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4964 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4970 if (op.Ty->isConstantMatrixType()) {
4971 llvm::MatrixBuilder MB(Builder);
4972 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4973 return MB.CreateSub(op.LHS, op.RHS);
4976 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4977 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4978 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4981 if (op.isFixedPointOp())
4982 return EmitFixedPointBinOp(op);
4984 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4989 if (!op.RHS->getType()->isPointerTy())
4999 LHS = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
5000 RHS = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
5002 LHS = Builder.CreatePtrToAddr(op.LHS,
"sub.ptr.lhs.cast");
5003 RHS = Builder.CreatePtrToAddr(op.RHS,
"sub.ptr.rhs.cast");
5005 LHS = Builder.CreateZExtOrTrunc(LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5007 RHS = Builder.CreateZExtOrTrunc(RHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5009 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
5013 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
5015 llvm::Value *divisor =
nullptr;
5018 if (
const VariableArrayType *vla
5021 elementType = VlaSize.Type;
5022 divisor = VlaSize.NumElts;
5026 if (!eltSize.
isOne())
5033 CharUnits elementSize;
5042 if (elementSize.
isOne())
5049 return Builder.CreateSDiv(diffInChars, divisor,
"sub.ptr.div");
5053 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5056Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5058 llvm::IntegerType *Ty;
5059 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5067 llvm::Type *RHSTy = RHS->
getType();
5068 llvm::APInt RHSMax =
5069 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5070 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5071 if (RHSMax.ult(Ty->getBitWidth()))
5072 return llvm::ConstantInt::get(RHSTy, RHSMax);
5073 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5077 const Twine &Name) {
5078 llvm::IntegerType *Ty;
5079 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5084 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5085 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5087 return Builder.CreateURem(
5088 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5091Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5093 if (Ops.isFixedPointOp())
5094 return EmitFixedPointBinOp(Ops);
5098 Value *RHS = Ops.RHS;
5099 if (Ops.LHS->getType() != RHS->
getType())
5100 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5102 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5103 Ops.Ty->hasSignedIntegerRepresentation() &&
5106 bool SanitizeUnsignedBase =
5107 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5108 Ops.Ty->hasUnsignedIntegerRepresentation();
5109 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5110 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5113 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5114 else if ((SanitizeBase || SanitizeExponent) &&
5116 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5117 if (SanitizeSignedBase)
5118 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5119 if (SanitizeUnsignedBase)
5120 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5121 if (SanitizeExponent)
5122 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5124 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5125 SanitizerHandler::ShiftOutOfBounds);
5126 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5127 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5128 llvm::Value *WidthMinusOne =
5129 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5130 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5132 if (SanitizeExponent) {
5134 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5141 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5144 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5145 llvm::Value *PromotedWidthMinusOne =
5146 (RHS == Ops.RHS) ? WidthMinusOne
5147 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5149 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5150 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5159 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5160 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5162 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5163 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5165 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5166 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5167 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5168 Checks.push_back(std::make_pair(
5169 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5170 : SanitizerKind::SO_UnsignedShiftBase));
5173 assert(!Checks.empty());
5174 EmitBinOpCheck(Checks, Ops);
5177 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5180Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5182 if (Ops.isFixedPointOp())
5183 return EmitFixedPointBinOp(Ops);
5187 Value *RHS = Ops.RHS;
5188 if (Ops.LHS->getType() != RHS->
getType())
5189 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5193 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5194 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5196 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5197 SanitizerHandler::ShiftOutOfBounds);
5198 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5199 llvm::Value *
Valid = Builder.CreateICmpULE(
5200 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5201 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5204 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5205 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5206 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5214 default: llvm_unreachable(
"unexpected element type");
5215 case BuiltinType::Char_U:
5216 case BuiltinType::UChar:
5217 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5218 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5219 case BuiltinType::Char_S:
5220 case BuiltinType::SChar:
5221 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5222 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5223 case BuiltinType::UShort:
5224 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5225 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5226 case BuiltinType::Short:
5227 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5228 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5229 case BuiltinType::UInt:
5230 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5231 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5232 case BuiltinType::Int:
5233 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5234 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5235 case BuiltinType::ULong:
5236 case BuiltinType::ULongLong:
5237 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5238 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5239 case BuiltinType::Long:
5240 case BuiltinType::LongLong:
5241 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5242 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5243 case BuiltinType::Float:
5244 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5245 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5246 case BuiltinType::Double:
5247 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5248 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5249 case BuiltinType::UInt128:
5250 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5251 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5252 case BuiltinType::Int128:
5253 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5254 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5258Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5259 llvm::CmpInst::Predicate UICmpOpc,
5260 llvm::CmpInst::Predicate SICmpOpc,
5261 llvm::CmpInst::Predicate FCmpOpc,
5263 TestAndClearIgnoreResultAssign();
5267 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5273 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5275 BinOpInfo BOInfo = EmitBinOps(E);
5276 Value *LHS = BOInfo.LHS;
5277 Value *RHS = BOInfo.RHS;
5283 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5285 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5288 Value *FirstVecArg = LHS,
5289 *SecondVecArg = RHS;
5291 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5295 default: llvm_unreachable(
"is not a comparison operation");
5307 std::swap(FirstVecArg, SecondVecArg);
5314 if (ElementKind == BuiltinType::Float) {
5316 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5317 std::swap(FirstVecArg, SecondVecArg);
5325 if (ElementKind == BuiltinType::Float) {
5327 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5332 std::swap(FirstVecArg, SecondVecArg);
5337 Value *CR6Param = Builder.getInt32(CR6);
5339 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5347 if (ResultTy->getBitWidth() > 1 &&
5349 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5354 if (BOInfo.isFixedPointOp()) {
5355 Result = EmitFixedPointBinOp(BOInfo);
5356 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5357 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5359 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5361 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5363 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5366 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5372 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5381 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5383 CETy = CTy->getElementType();
5385 LHS.first = Visit(E->
getLHS());
5386 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5389 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5392 CTy->getElementType()) &&
5393 "The element types must always match.");
5396 RHS.first = Visit(E->
getRHS());
5397 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5399 "The element types must always match.");
5402 Value *ResultR, *ResultI;
5406 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5407 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5411 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5412 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5416 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5419 "Complex comparison other than == or != ?");
5420 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5432 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5433 CastKind Kind = ICE->getCastKind();
5434 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5435 *SrcType = ICE->getSubExpr()->getType();
5448 bool Ignore = TestAndClearIgnoreResultAssign();
5482 RHS = Visit(E->
getRHS());
5498 RHS = Visit(E->
getRHS());
5538 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5541Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5552 if (LHS->
getType()->isFPOrFPVectorTy()) {
5553 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5555 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5556 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5558 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5559 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5561 Value *
And = Builder.CreateAnd(LHS, RHS);
5562 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5566 llvm::Type *ResTy = ConvertType(E->
getType());
5585 if (InstrumentRegions &&
5589 llvm::BasicBlock *RHSSkip =
5592 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5609 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5620 return llvm::Constant::getNullValue(ResTy);
5631 llvm::BasicBlock *LHSFalseBlock =
5634 CodeGenFunction::ConditionalEvaluation eval(CGF);
5649 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5651 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5653 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5662 RHSBlock = Builder.GetInsertBlock();
5667 llvm::BasicBlock *ContIncoming = RHSBlock;
5668 if (InstrumentRegions &&
5672 llvm::BasicBlock *RHSBlockSkip =
5674 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5678 PN->addIncoming(RHSCond, RHSBlockCnt);
5683 ContIncoming = RHSBlockSkip;
5694 PN->addIncoming(RHSCond, ContIncoming);
5703 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5707 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5710Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5721 if (LHS->
getType()->isFPOrFPVectorTy()) {
5722 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5724 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5725 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5727 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5728 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5730 Value *
Or = Builder.CreateOr(LHS, RHS);
5731 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5735 llvm::Type *ResTy = ConvertType(E->
getType());
5754 if (InstrumentRegions &&
5758 llvm::BasicBlock *RHSSkip =
5761 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5778 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5789 return llvm::ConstantInt::get(ResTy, 1);
5799 llvm::BasicBlock *LHSTrueBlock =
5802 CodeGenFunction::ConditionalEvaluation eval(CGF);
5818 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5820 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5822 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5834 RHSBlock = Builder.GetInsertBlock();
5839 llvm::BasicBlock *ContIncoming = RHSBlock;
5840 if (InstrumentRegions &&
5844 llvm::BasicBlock *RHSTrueBlock =
5846 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5850 PN->addIncoming(RHSCond, RHSBlockCnt);
5855 ContIncoming = RHSTrueBlock;
5862 PN->addIncoming(RHSCond, ContIncoming);
5869 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5872Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5875 return Visit(E->
getRHS());
5882Value *ScalarExprEmitter::
5883VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5884 TestAndClearIgnoreResultAssign();
5887 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5889 Expr *condExpr = E->
getCond();
5897 Expr *live = lhsExpr, *dead = rhsExpr;
5898 if (!CondExprBool) std::swap(live, dead);
5925 llvm::Value *LHS = Visit(lhsExpr);
5926 llvm::Value *RHS = Visit(rhsExpr);
5928 llvm::Type *condType = ConvertType(condExpr->
getType());
5931 unsigned numElem = vecTy->getNumElements();
5932 llvm::Type *elemType = vecTy->getElementType();
5934 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5935 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5936 llvm::Value *tmp = Builder.CreateSExt(
5937 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5938 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5941 llvm::Value *RHSTmp = RHS;
5942 llvm::Value *LHSTmp = LHS;
5943 bool wasCast =
false;
5945 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5946 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5947 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5951 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5952 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5953 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5955 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5965 llvm::Value *LHS = Visit(lhsExpr);
5966 llvm::Value *RHS = Visit(rhsExpr);
5968 llvm::Type *CondType = ConvertType(condExpr->
getType());
5971 if (VecTy->getElementType()->isIntegerTy(1))
5972 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5975 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5977 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5979 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5980 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5992 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5996 llvm::Value *LHS = Visit(lhsExpr);
5997 llvm::Value *RHS = Visit(rhsExpr);
6000 assert(!RHS &&
"LHS and RHS types must match");
6003 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6014 CodeGenFunction::ConditionalEvaluation eval(CGF);
6028 Value *LHS = Visit(lhsExpr);
6031 LHSBlock = Builder.GetInsertBlock();
6032 Builder.CreateBr(ContBlock);
6044 Value *RHS = Visit(rhsExpr);
6047 RHSBlock = Builder.GetInsertBlock();
6057 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6058 PN->addIncoming(LHS, LHSBlock);
6059 PN->addIncoming(RHS, RHSBlock);
6064Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6068Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6070 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6075Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6081 Value *Src,
unsigned NumElementsDst) {
6082 static constexpr int Mask[] = {0, 1, 2, -1};
6083 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6103 const llvm::DataLayout &DL,
6104 Value *Src, llvm::Type *DstTy,
6105 StringRef Name =
"") {
6109 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6110 return Builder.CreateBitCast(Src, DstTy, Name);
6113 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6114 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6117 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6119 if (!DstTy->isIntegerTy())
6120 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6122 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6126 if (!SrcTy->isIntegerTy())
6127 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6129 return Builder.CreateIntToPtr(Src, DstTy, Name);
6132Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6134 llvm::Type *DstTy = ConvertType(E->
getType());
6136 llvm::Type *SrcTy = Src->
getType();
6137 unsigned NumElementsSrc =
6141 unsigned NumElementsDst =
6152 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6157 Src->setName(
"astype");
6164 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6165 auto *Vec4Ty = llvm::FixedVectorType::get(
6171 Src->setName(
"astype");
6176 Src, DstTy,
"astype");
6179Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6191 "Invalid scalar expression to emit");
6193 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6194 .Visit(
const_cast<Expr *
>(E));
6203 "Invalid scalar expression to emit");
6204 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6214 "Invalid complex -> scalar conversion");
6215 return ScalarExprEmitter(*
this)
6216 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6223 if (!PromotionType.
isNull())
6224 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6226 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6232 bool isInc,
bool isPre) {
6233 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6243 llvm::Type *BaseTy =
6259 ScalarExprEmitter Scalar(*
this);
6262#define COMPOUND_OP(Op) \
6263 case BO_##Op##Assign: \
6264 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6301 llvm_unreachable(
"Not valid compound assignment operators");
6304 llvm_unreachable(
"Unhandled compound assignment operator");
6325 llvm::Value *TotalOffset =
nullptr;
6327 auto *IntPtrTy = DL.getAddressType(BasePtr->
getType());
6330 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6331 auto *SAddIntrinsic =
6332 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6333 auto *SMulIntrinsic =
6334 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6337 llvm::Value *OffsetOverflows = Builder.getFalse();
6341 llvm::Value *RHS) -> llvm::Value * {
6342 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6345 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6346 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6348 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6351 OffsetOverflows = Builder.getTrue();
6352 return llvm::ConstantInt::get(VMContext, N);
6357 auto *ResultAndOverflow = Builder.CreateCall(
6358 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6359 OffsetOverflows = Builder.CreateOr(
6360 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6361 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6365 for (
auto GTI = llvm::gep_type_begin(ElemTy, IdxList),
6366 GTE = llvm::gep_type_end(ElemTy, IdxList);
6367 GTI != GTE; ++GTI) {
6368 llvm::Value *LocalOffset;
6369 auto *Index = GTI.getOperand();
6371 if (
auto *STy = GTI.getStructTypeOrNull()) {
6375 LocalOffset = llvm::ConstantInt::get(
6376 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6381 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6382 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6383 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6388 if (!TotalOffset || TotalOffset ==
Zero)
6389 TotalOffset = LocalOffset;
6391 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6394 return {TotalOffset, OffsetOverflows};
6399 ArrayRef<Value *> IdxList,
6400 bool SignedIndices,
bool IsSubtraction,
6401 SourceLocation Loc,
const Twine &Name) {
6402 llvm::Type *PtrTy =
Ptr->getType();
6404 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6405 if (!SignedIndices && !IsSubtraction)
6406 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6408 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6411 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6415 bool PerformNullCheck = !NullPointerIsDefined(
6416 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6419 bool PerformOverflowCheck =
6422 if (!(PerformNullCheck || PerformOverflowCheck))
6425 const auto &DL = CGM.getDataLayout();
6427 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6428 auto CheckHandler = SanitizerHandler::PointerOverflow;
6429 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6430 llvm::Type *IntPtrTy = DL.getAddressType(PtrTy);
6433 Ptr, ElemTy, IdxList, getLLVMContext(), CGM, Builder);
6435 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6445 auto *IntPtr = Builder.CreatePtrToAddr(Ptr);
6446 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6448 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6452 if (PerformNullCheck) {
6460 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6461 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6462 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6463 Checks.emplace_back(
Valid, CheckOrdinal);
6466 if (PerformOverflowCheck) {
6471 llvm::Value *ValidGEP;
6472 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6473 if (SignedIndices) {
6479 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6480 auto *PosOrZeroOffset =
6482 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6484 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6485 }
else if (!IsSubtraction) {
6490 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6496 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6498 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6499 Checks.emplace_back(ValidGEP, CheckOrdinal);
6502 assert(!Checks.empty() &&
"Should have produced some checks.");
6504 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6506 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6507 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6513 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6514 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6515 const Twine &Name) {
6516 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6517 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6518 if (!SignedIndices && !IsSubtraction)
6519 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6521 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6525 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6526 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6527 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, llvm::Type *ElemTy, ArrayRef< Value * > IdxList, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Compute the total offset in bytes that indexing BasePtr with ElemTy and IdxList applies,...
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 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 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 mlir::Value tryEmitFMulAdd(mlir::Location loc, const BinOpInfo &op, CIRGenBuilderTy &builder, bool isSub=false)
static mlir::Value buildFMulAdd(mlir::Location addLoc, cir::FMulOp mulOp, mlir::Value addend, CIRGenBuilderTy &builder, bool negMul, bool negAdd)
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 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.
bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, const ASTContext &Ctx)
Check whether E is cheap enough and side-effect-free enough to evaluate unconditionally instead of co...
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)
Top level wrappers for InstallAPI frontend operations.
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.