35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
201 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
206 switch (OBT->getBehaviorKind()) {
207 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
209 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
212 llvm_unreachable(
"Unknown OverflowBehaviorKind");
219 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
227 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
231static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
233 "Expected a unary or binary operator");
237 if (!Op.mayHaveIntegerOverflow())
244 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
245 if (BO && BO->hasExcludedOverflowPattern())
248 if (Op.Ty.isWrapType())
250 if (Op.Ty.isTrapType())
253 if (Op.Ty->isSignedIntegerType() &&
259 if (Op.Ty->isUnsignedIntegerType() &&
284 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
290 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
291 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
295class ScalarExprEmitter
297 CodeGenFunction &CGF;
298 CGBuilderTy &Builder;
299 bool IgnoreResultAssign;
300 llvm::LLVMContext &VMContext;
303 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
304 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
305 VMContext(cgf.getLLVMContext()) {
312 bool TestAndClearIgnoreResultAssign() {
313 bool I = IgnoreResultAssign;
314 IgnoreResultAssign =
false;
318 llvm::Type *ConvertType(QualType T) {
return CGF.
ConvertType(T); }
319 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
325 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
326 const BinOpInfo &Info);
328 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
332 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
333 const AlignValueAttr *AVAttr =
nullptr;
334 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
335 const ValueDecl *VD = DRE->getDecl();
338 if (
const auto *TTy =
340 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
350 AVAttr = VD->
getAttr<AlignValueAttr>();
355 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
356 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
369 Value *EmitLoadOfLValue(
const Expr *E) {
373 EmitLValueAlignmentAssumption(E,
V);
379 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
383 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
384 Value *Src, QualType SrcType, QualType DstType,
385 llvm::Type *DstTy, SourceLocation Loc);
390 enum ImplicitConversionCheckKind :
unsigned char {
391 ICCK_IntegerTruncation = 0,
392 ICCK_UnsignedIntegerTruncation = 1,
393 ICCK_SignedIntegerTruncation = 2,
394 ICCK_IntegerSignChange = 3,
395 ICCK_SignedIntegerTruncationOrSignChange = 4,
400 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
401 QualType DstType, SourceLocation Loc,
402 bool OBTrapInvolved =
false);
407 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
408 QualType DstType, SourceLocation Loc);
412 struct ScalarConversionOpts {
413 bool TreatBooleanAsSigned;
414 bool EmitImplicitIntegerTruncationChecks;
415 bool EmitImplicitIntegerSignChangeChecks;
417 ScalarConversionOpts()
418 : TreatBooleanAsSigned(
false),
419 EmitImplicitIntegerTruncationChecks(
false),
420 EmitImplicitIntegerSignChangeChecks(
false) {}
422 ScalarConversionOpts(clang::SanitizerSet SanOpts)
423 : TreatBooleanAsSigned(
false),
424 EmitImplicitIntegerTruncationChecks(
425 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
426 EmitImplicitIntegerSignChangeChecks(
427 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
429 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
430 llvm::Type *SrcTy, llvm::Type *DstTy,
431 ScalarConversionOpts Opts);
433 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
435 ScalarConversionOpts Opts = ScalarConversionOpts());
439 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
445 QualType SrcTy, QualType DstTy,
449 Value *EmitNullValue(QualType Ty);
454 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
455 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
459 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
462 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
469 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
470 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
476 ZI->eraseFromParent();
481 return Builder.CreateIsNotNull(
V,
"tobool");
488 Value *Visit(Expr *E) {
489 ApplyDebugLocation DL(CGF, E);
490 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
493 Value *VisitStmt(Stmt *S) {
495 llvm_unreachable(
"Stmt can't have complex result type!");
497 Value *VisitExpr(Expr *S);
499 Value *VisitConstantExpr(ConstantExpr *E) {
505 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
520 Value *VisitParenExpr(ParenExpr *PE) {
523 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
526 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
527 return Visit(
GE->getResultExpr());
529 Value *VisitCoawaitExpr(CoawaitExpr *S) {
532 Value *VisitCoyieldExpr(CoyieldExpr *S) {
535 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
540 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
541 return Builder.getInt(E->
getValue());
543 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
544 return Builder.getInt(E->
getValue());
546 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
547 return llvm::ConstantFP::get(VMContext, E->
getValue());
549 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
552 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
555 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
556 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
558 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
559 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
561 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
565 return EmitNullValue(E->
getType());
567 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
568 return EmitNullValue(E->
getType());
570 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
571 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
572 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
574 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
577 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
581 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
585 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
586 Value *VisitEmbedExpr(EmbedExpr *E);
588 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
597 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
598 llvm_unreachable(
"Codegen for this isn't defined/implemented");
602 Value *VisitDeclRefExpr(DeclRefExpr *E) {
605 return EmitLoadOfLValue(E);
608 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
611 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
614 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
615 return EmitLoadOfLValue(E);
617 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
620 return EmitLoadOfLValue(E);
624 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
630 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
636 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
641 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
642 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
643 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
644 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
645 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
646 Value *VisitMemberExpr(MemberExpr *E);
647 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
648 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
649 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
655 return EmitLoadOfLValue(E);
658 Value *VisitInitListExpr(InitListExpr *E);
660 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
662 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
666 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
667 return EmitNullValue(E->
getType());
669 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
671 return VisitCastExpr(E);
675 Value *VisitCallExpr(
const CallExpr *E) {
677 return EmitLoadOfLValue(E);
681 EmitLValueAlignmentAssumption(E,
V);
685 Value *VisitStmtExpr(
const StmtExpr *E);
688 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
690 return EmitScalarPrePostIncDec(E, LV,
false,
false);
692 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
694 return EmitScalarPrePostIncDec(E, LV,
true,
false);
696 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
698 return EmitScalarPrePostIncDec(E, LV,
false,
true);
700 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
702 return EmitScalarPrePostIncDec(E, LV,
true,
true);
705 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
709 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
710 bool isInc,
bool isPre);
713 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
717 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
719 Value *VisitUnaryDeref(
const UnaryOperator *E) {
722 return EmitLoadOfLValue(E);
725 Value *VisitUnaryPlus(
const UnaryOperator *E,
726 QualType PromotionType = QualType());
727 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
728 Value *VisitUnaryMinus(
const UnaryOperator *E,
729 QualType PromotionType = QualType());
730 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
732 Value *VisitUnaryNot (
const UnaryOperator *E);
733 Value *VisitUnaryLNot (
const UnaryOperator *E);
734 Value *VisitUnaryReal(
const UnaryOperator *E,
735 QualType PromotionType = QualType());
736 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
737 Value *VisitUnaryImag(
const UnaryOperator *E,
738 QualType PromotionType = QualType());
739 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
740 Value *VisitUnaryExtension(
const UnaryOperator *E) {
745 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
746 return EmitLoadOfLValue(E);
748 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
756 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
757 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
760 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
761 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
764 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
768 Value *VisitExprWithCleanups(ExprWithCleanups *E);
769 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
772 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
777 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
779 return llvm::ConstantInt::get(ConvertType(E->
getType()),
782 return llvm::ConstantInt::get(ConvertType(E->
getType()),
786 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
794 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
795 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
798 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
799 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
802 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
812 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
813 return EmitNullValue(E->
getType());
816 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
821 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
822 return Builder.getInt1(E->
getValue());
826 Value *EmitMul(
const BinOpInfo &Ops) {
827 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
828 Ops.Ty->isUnsignedIntegerType()) {
829 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
831 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
832 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
833 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
834 case LangOptions::OB_Wrap:
835 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
836 case LangOptions::OB_SignedAndDefined:
838 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
840 case LangOptions::OB_Unset:
842 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
843 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
845 case LangOptions::OB_Trap:
846 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
847 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
848 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
849 return EmitOverflowCheckedBinOp(Ops);
853 if (Ops.Ty->isConstantMatrixType()) {
854 llvm::MatrixBuilder MB(Builder);
858 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
859 BO->getLHS()->getType().getCanonicalType());
860 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
861 BO->getRHS()->getType().getCanonicalType());
862 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
863 if (LHSMatTy && RHSMatTy)
864 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
865 LHSMatTy->getNumColumns(),
866 RHSMatTy->getNumColumns());
867 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
870 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
872 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
873 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
875 if (Ops.isFixedPointOp())
876 return EmitFixedPointBinOp(Ops);
877 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
881 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
884 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
885 llvm::Value *
Zero,
bool isDiv);
887 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
893 Value *EmitDiv(
const BinOpInfo &Ops);
894 Value *EmitRem(
const BinOpInfo &Ops);
895 Value *EmitAdd(
const BinOpInfo &Ops);
896 Value *EmitSub(
const BinOpInfo &Ops);
897 Value *EmitShl(
const BinOpInfo &Ops);
898 Value *EmitShr(
const BinOpInfo &Ops);
899 Value *EmitAnd(
const BinOpInfo &Ops) {
900 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
902 Value *EmitXor(
const BinOpInfo &Ops) {
903 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
905 Value *EmitOr (
const BinOpInfo &Ops) {
906 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
910 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
912 BinOpInfo EmitBinOps(
const BinaryOperator *E,
913 QualType PromotionTy = QualType());
915 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
916 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
917 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
919 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
920 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
923 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
924 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
926 QualType getPromotionType(QualType Ty) {
928 if (
auto *CT = Ty->
getAs<ComplexType>()) {
929 QualType ElementType = CT->getElementType();
935 if (
auto *VT = Ty->
getAs<VectorType>()) {
936 unsigned NumElements = VT->getNumElements();
946#define HANDLEBINOP(OP) \
947 Value *VisitBin##OP(const BinaryOperator *E) { \
948 QualType promotionTy = getPromotionType(E->getType()); \
949 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
950 if (result && !promotionTy.isNull()) \
951 result = EmitUnPromotedValue(result, E->getType()); \
954 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
955 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
956 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
972 llvm::CmpInst::Predicate SICmpOpc,
973 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
974#define VISITCOMP(CODE, UI, SI, FP, SIG) \
975 Value *VisitBin##CODE(const BinaryOperator *E) { \
976 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
977 llvm::FCmpInst::FP, SIG); }
978 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
992 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
993 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
995 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1000 Value *VisitBlockExpr(
const BlockExpr *BE);
1001 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1002 Value *VisitChooseExpr(ChooseExpr *CE);
1003 Value *VisitVAArgExpr(VAArgExpr *VE);
1004 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1007 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1010 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1013 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1016 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1017 Value *VisitAtomicExpr(AtomicExpr *AE);
1018 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1031 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1034 return EmitFloatToBoolConversion(Src);
1036 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1040 "Unknown scalar type to convert");
1043 return EmitIntToBoolConversion(Src);
1046 return EmitPointerToBoolConversion(Src, SrcType);
1049void ScalarExprEmitter::EmitFloatConversionCheck(
1050 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1051 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1052 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1056 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1057 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1058 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1059 using llvm::APFloat;
1062 llvm::Value *Check =
nullptr;
1063 const llvm::fltSemantics &SrcSema =
1073 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1074 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1075 APFloat::opOverflow)
1078 MinSrc = APFloat::getInf(SrcSema,
true);
1082 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1085 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1086 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1087 APFloat::opOverflow)
1090 MaxSrc = APFloat::getInf(SrcSema,
false);
1094 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1099 const llvm::fltSemantics &Sema =
1102 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1103 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1107 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1109 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1110 Check = Builder.CreateAnd(GE, LE);
1115 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1121static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1122 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1125 llvm::Type *SrcTy = Src->
getType();
1126 llvm::Type *DstTy = Dst->
getType();
1131 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1133 "non-integer llvm type");
1140 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1142 if (!SrcSigned && !DstSigned) {
1143 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1144 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1146 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1147 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1150 llvm::Value *Check =
nullptr;
1152 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1154 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1156 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1164void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1165 Value *Dst, QualType DstType,
1167 bool OBTrapInvolved) {
1168 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1178 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1179 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1181 if (SrcBits <= DstBits)
1184 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1191 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1192 (!SrcSigned && DstSigned))
1195 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1196 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1199 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1204 SanitizerDebugLocation SanScope(
1206 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1207 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1223 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1231 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1232 if (OBT->isWrapKind())
1235 if (ignoredBySanitizer && !OBTrapInvolved)
1238 llvm::Constant *StaticArgs[] = {
1241 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1242 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1244 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1251 llvm::Type *VTy =
V->getType();
1254 return llvm::ConstantInt::getFalse(VTy->getContext());
1256 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1257 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1258 llvm::Twine(Name) +
"." +
V->getName() +
1259 ".negativitycheck");
1264static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1265 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1268 llvm::Type *SrcTy = Src->
getType();
1269 llvm::Type *DstTy = Dst->
getType();
1272 "non-integer llvm type");
1278 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1279 unsigned DstBits = DstTy->getScalarSizeInBits();
1283 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1284 "either the widths should be different, or the signednesses.");
1287 llvm::Value *SrcIsNegative =
1290 llvm::Value *DstIsNegative =
1296 llvm::Value *Check =
nullptr;
1297 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1299 return std::make_pair(
1300 ScalarExprEmitter::ICCK_IntegerSignChange,
1301 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1304void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1305 Value *Dst, QualType DstType,
1306 SourceLocation Loc) {
1307 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1310 llvm::Type *SrcTy = Src->
getType();
1311 llvm::Type *DstTy = Dst->
getType();
1321 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1322 unsigned DstBits = DstTy->getScalarSizeInBits();
1329 if (SrcSigned == DstSigned && SrcBits == DstBits)
1333 if (!SrcSigned && !DstSigned)
1338 if ((DstBits > SrcBits) && DstSigned)
1340 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1341 (SrcBits > DstBits) && SrcSigned) {
1350 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1354 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1358 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1359 SanitizerDebugLocation SanScope(
1361 {SanitizerKind::SO_ImplicitIntegerSignChange,
1362 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1363 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1366 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1367 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1371 ImplicitConversionCheckKind CheckKind;
1372 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1379 CheckKind = Check.first;
1380 Checks.emplace_back(Check.second);
1382 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1383 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1389 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1390 Checks.emplace_back(Check.second);
1394 llvm::Constant *StaticArgs[] = {
1397 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1398 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1400 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1405static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1406 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1412 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1413 if (!SrcSigned && !DstSigned)
1414 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1416 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1418 llvm::Value *Check =
nullptr;
1420 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1422 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1425 return std::make_pair(
1427 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1432static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1433 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1437 llvm::Value *SrcIsNegative =
1440 llvm::Value *DstIsNegative =
1446 llvm::Value *Check =
nullptr;
1448 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1450 return std::make_pair(
1451 ScalarExprEmitter::ICCK_IntegerSignChange,
1452 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1460 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1478 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1479 unsigned DstBits = Info.
Size;
1484 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1486 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1488 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1489 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1493 bool EmitTruncation = DstBits < SrcBits;
1497 bool EmitTruncationFromUnsignedToSigned =
1498 EmitTruncation && DstSigned && !SrcSigned;
1500 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1501 bool BothUnsigned = !SrcSigned && !DstSigned;
1502 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1509 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1514 else if (EmitSignChange) {
1515 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1516 "either the widths should be different, or the signednesses.");
1522 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1523 if (EmitTruncationFromUnsignedToSigned)
1524 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1526 llvm::Constant *StaticArgs[] = {
1529 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1530 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1532 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1536 QualType DstType, llvm::Type *SrcTy,
1538 ScalarConversionOpts Opts) {
1540 llvm::Type *SrcElementTy;
1541 llvm::Type *DstElementTy;
1551 "cannot cast between matrix and non-matrix types");
1552 SrcElementTy = SrcTy;
1553 DstElementTy = DstTy;
1554 SrcElementType = SrcType;
1555 DstElementType = DstType;
1560 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1565 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1567 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1568 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1572 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1579 llvm::Intrinsic::ID IID =
1580 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1581 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1585 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1586 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1589 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1590 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1591 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1593 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1594 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1595 return Builder.CreateFPExt(Src, DstTy,
"conv");
1600Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1603 ScalarConversionOpts Opts) {
1618 return Builder.CreateIsNotNull(Src,
"tobool");
1621 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1624 "Unhandled scalar conversion from a fixed point type to another type.");
1628 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1631 "Unhandled scalar conversion to a fixed point type from another type.");
1634 QualType NoncanonicalSrcType = SrcType;
1635 QualType NoncanonicalDstType = DstType;
1639 if (SrcType == DstType)
return Src;
1643 llvm::Value *OrigSrc = Src;
1644 QualType OrigSrcType = SrcType;
1645 llvm::Type *SrcTy = Src->
getType();
1649 return EmitConversionToBool(Src, SrcType);
1651 llvm::Type *DstTy = ConvertType(DstType);
1656 if (DstTy->isFloatingPointTy()) {
1659 return Builder.CreateFPExt(BitCast, DstTy,
"conv");
1668 Src = Builder.CreateBitCast(Src, CGF.
CGM.
HalfTy);
1671 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1678 if (SrcTy == DstTy) {
1679 if (Opts.EmitImplicitIntegerSignChangeChecks)
1680 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1681 NoncanonicalDstType, Loc);
1689 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1694 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1699 llvm::Value* IntResult =
1700 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1702 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1708 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1715 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1717 "Splatted expr doesn't match with vector element type?");
1721 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1725 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1729 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1730 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1731 if (SrcSize == DstSize)
1732 return Builder.CreateBitCast(Src, DstTy,
"conv");
1745 assert(((SrcElementTy->isIntegerTy() &&
1746 DstElementTy->isIntegerTy()) ||
1747 (SrcElementTy->isFloatingPointTy() &&
1748 DstElementTy->isFloatingPointTy())) &&
1749 "unexpected conversion between a floating-point vector and an "
1753 if (SrcElementTy->isIntegerTy())
1754 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1757 if (SrcSize > DstSize)
1758 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1761 return Builder.CreateFPExt(Src, DstTy,
"conv");
1765 Value *Res =
nullptr;
1766 llvm::Type *ResTy = DstTy;
1773 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1775 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1781 if (SrcTy->isFloatingPointTy()) {
1790 assert(DstTy->isIntegerTy(16) &&
1792 "Only half FP requires extra conversion");
1793 return Builder.CreateBitCast(Res, DstTy);
1799 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1801 if (DstTy != ResTy) {
1802 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1805 assert(ResTy->isIntegerTy(16) &&
1807 "Only half FP requires extra conversion");
1808 Res = Builder.CreateBitCast(Res, ResTy);
1819 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1820 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1821 bool OBTrapInvolved =
1822 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1823 bool OBWrapInvolved =
1824 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1826 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1828 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1829 NoncanonicalDstType, Loc, OBTrapInvolved);
1831 if (Opts.EmitImplicitIntegerSignChangeChecks)
1832 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1833 NoncanonicalDstType, Loc);
1838Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1840 SourceLocation Loc) {
1841 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1844 Result = FPBuilder.CreateFloatingToFixed(Src,
1847 Result = FPBuilder.CreateFixedToFloating(Src,
1849 ConvertType(DstTy));
1855 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1856 DstFPSema.getWidth(),
1857 DstFPSema.isSigned());
1859 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1862 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1869Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1871 SourceLocation Loc) {
1873 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1878 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1879 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1880 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1887 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1890Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1898void ScalarExprEmitter::EmitBinOpCheck(
1899 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1900 const BinOpInfo &Info) {
1903 SmallVector<llvm::Constant *, 4> StaticData;
1904 SmallVector<llvm::Value *, 2> DynamicData;
1912 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1913 if (UO && UO->
getOpcode() == UO_Minus) {
1914 Check = SanitizerHandler::NegateOverflow;
1916 DynamicData.push_back(Info.RHS);
1920 Check = SanitizerHandler::ShiftOutOfBounds;
1922 StaticData.push_back(
1924 StaticData.push_back(
1926 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1928 Check = SanitizerHandler::DivremOverflow;
1932 int ArithOverflowKind = 0;
1935 Check = SanitizerHandler::AddOverflow;
1936 ArithOverflowKind = diag::UBSanArithKind::Add;
1940 Check = SanitizerHandler::SubOverflow;
1941 ArithOverflowKind = diag::UBSanArithKind::Sub;
1945 Check = SanitizerHandler::MulOverflow;
1946 ArithOverflowKind = diag::UBSanArithKind::Mul;
1950 llvm_unreachable(
"unexpected opcode for bin op check");
1954 SanitizerKind::UnsignedIntegerOverflow) ||
1956 SanitizerKind::SignedIntegerOverflow)) {
1960 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1964 DynamicData.push_back(Info.LHS);
1965 DynamicData.push_back(Info.RHS);
1968 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1975Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1983ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1985 unsigned AddrSpace =
1987 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1990 llvm::Type *ExprTy = ConvertType(E->
getType());
1991 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1995Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1997 auto It = E->
begin();
1998 return Builder.getInt((*It)->getValue());
2001Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2009 unsigned LHSElts = LTy->getNumElements();
2017 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2018 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2026 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2027 MTy->getNumElements());
2028 Value* NewV = llvm::PoisonValue::get(RTy);
2029 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2030 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2031 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2033 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2034 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2042 SmallVector<int, 32> Indices;
2046 if (Idx.isSigned() && Idx.isAllOnes())
2047 Indices.push_back(-1);
2049 Indices.push_back(Idx.getZExtValue());
2052 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2055Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2063 if (SrcType == DstType)
return Src;
2066 "ConvertVector source type must be a vector");
2068 "ConvertVector destination type must be a vector");
2070 llvm::Type *SrcTy = Src->
getType();
2071 llvm::Type *DstTy = ConvertType(DstType);
2077 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2078 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2080 assert(SrcTy->isVectorTy() &&
2081 "ConvertVector source IR type must be a vector");
2082 assert(DstTy->isVectorTy() &&
2083 "ConvertVector destination IR type must be a vector");
2088 if (DstEltType->isBooleanType()) {
2089 assert((SrcEltTy->isFloatingPointTy() ||
2092 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2093 if (SrcEltTy->isFloatingPointTy()) {
2094 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2095 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2097 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2102 Value *Res =
nullptr;
2107 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2109 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2111 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2113 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2116 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2117 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2118 if (DstEltType->isSignedIntegerOrEnumerationType())
2119 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2121 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2123 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2124 "Unknown real conversion");
2125 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2126 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2127 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2129 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2135Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2144 return Builder.getInt(
Value);
2148 llvm::Value *
Result = EmitLoadOfLValue(E);
2154 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2155 if (llvm::GetElementPtrInst *GEP =
2156 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2157 if (llvm::Instruction *
Pointer =
2158 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2170Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2171 TestAndClearIgnoreResultAssign();
2179 return EmitLoadOfLValue(E);
2187 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2190 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2193Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2194 MatrixSingleSubscriptExpr *E) {
2195 TestAndClearIgnoreResultAssign();
2198 unsigned NumRows = MatrixTy->getNumRows();
2199 unsigned NumColumns = MatrixTy->getNumColumns();
2203 llvm::MatrixBuilder MB(Builder);
2207 MB.CreateIndexAssumption(RowIdx, NumRows);
2211 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2212 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2214 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2215 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2216 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2217 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2218 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2219 IsMatrixRowMajor,
"matrix_row_idx");
2221 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2222 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2223 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2229Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2230 TestAndClearIgnoreResultAssign();
2238 llvm::MatrixBuilder MB(Builder);
2241 unsigned NumCols = MatrixTy->getNumColumns();
2242 unsigned NumRows = MatrixTy->getNumRows();
2243 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2244 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2245 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2248 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2253 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2258 int MV = SVI->getMaskValue(Idx);
2265 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2266 "Index operand too large for shufflevector mask!");
2267 return C->getZExtValue();
2270Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2271 bool Ignore = TestAndClearIgnoreResultAssign();
2274 assert((Ignore ==
false ||
2276 "init list ignored");
2293 llvm::VectorType *VType =
2294 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2297 if (NumInitElements == 0) {
2299 return EmitNullValue(E->
getType());
2306 if (NumInitElements == 0) {
2308 return EmitNullValue(E->
getType());
2311 if (NumInitElements == 1) {
2312 Expr *InitVector = E->
getInit(0);
2317 return Visit(InitVector);
2320 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2330 unsigned CurIdx = 0;
2331 bool VIsPoisonShuffle =
false;
2332 llvm::Value *
V = llvm::PoisonValue::get(VType);
2333 for (
unsigned i = 0; i != NumInitElements; ++i) {
2336 SmallVector<int, 16> Args;
2338 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2348 ->getNumElements() == ResElts) {
2350 Value *LHS =
nullptr, *RHS =
nullptr;
2355 Args.resize(ResElts, -1);
2357 LHS = EI->getVectorOperand();
2359 VIsPoisonShuffle =
true;
2360 }
else if (VIsPoisonShuffle) {
2363 for (
unsigned j = 0; j != CurIdx; ++j)
2365 Args.push_back(ResElts +
C->getZExtValue());
2366 Args.resize(ResElts, -1);
2369 RHS = EI->getVectorOperand();
2370 VIsPoisonShuffle =
false;
2372 if (!Args.empty()) {
2373 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2379 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2381 VIsPoisonShuffle =
false;
2391 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2394 Value *SVOp = SVI->getOperand(0);
2397 if (OpTy->getNumElements() == ResElts) {
2398 for (
unsigned j = 0; j != CurIdx; ++j) {
2401 if (VIsPoisonShuffle) {
2407 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2409 Args.resize(ResElts, -1);
2411 if (VIsPoisonShuffle)
2421 for (
unsigned j = 0; j != InitElts; ++j)
2423 Args.resize(ResElts, -1);
2424 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2427 for (
unsigned j = 0; j != CurIdx; ++j)
2429 for (
unsigned j = 0; j != InitElts; ++j)
2430 Args.push_back(j + Offset);
2431 Args.resize(ResElts, -1);
2438 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2445 llvm::Type *EltTy = VType->getElementType();
2448 for (; CurIdx < ResElts; ++CurIdx) {
2449 Value *Idx = Builder.getInt32(CurIdx);
2450 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2451 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2458 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2459 MT && CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2460 LangOptions::MatrixMemoryLayout::MatrixColMajor) {
2461 SmallVector<int, 16> Mask;
2462 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I)
2463 Mask.push_back(MT->mapColumnMajorToRowMajorFlattenedIndex(I));
2464 V = Builder.CreateShuffleVector(
V, Mask,
"matrix.rowmajor2colmajor");
2477 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2481 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2484 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2503 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2507 if (
const auto *CE = dyn_cast<CastExpr>(E))
2508 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2509 CE->getCastKind() == CK_ArrayToPointerDecay)
2520 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2530 if (ICE->isGLValue())
2545 assert(LoadList.size() >= VecTy->getNumElements() &&
2546 "Flattened type on RHS must have the same number or more elements "
2547 "than vector on LHS.");
2551 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2554 "All flattened source values should be scalars.");
2557 VecTy->getElementType(), Loc);
2558 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2563 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2564 "Flattened type on RHS must have the same number or more elements "
2565 "than vector on LHS.");
2567 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2573 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2574 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2577 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2580 "All flattened source values should be scalars.");
2583 MatTy->getElementType(), Loc);
2584 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2585 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2592 "Destination type must be a vector, matrix, or builtin type.");
2594 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2603 llvm::scope_exit RestoreCurCast(
2604 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2608 QualType DestTy = CE->
getType();
2610 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2614 bool Ignored = TestAndClearIgnoreResultAssign();
2620 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2621 case CK_BuiltinFnToFnPtr:
2622 llvm_unreachable(
"builtin functions are handled elsewhere");
2624 case CK_LValueBitCast:
2625 case CK_ObjCObjectLValueCast: {
2626 Address
Addr = EmitLValue(E).getAddress();
2629 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2632 case CK_LValueToRValueBitCast: {
2638 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2641 case CK_CPointerToObjCPointerCast:
2642 case CK_BlockPointerToObjCPointerCast:
2643 case CK_AnyPointerToBlockPointerCast:
2645 Value *Src = Visit(E);
2646 llvm::Type *SrcTy = Src->
getType();
2647 llvm::Type *DstTy = ConvertType(DestTy);
2658 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2662 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2663 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2664 "Address-space cast must be used to convert address spaces");
2666 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2667 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2669 PT->getPointeeType(),
2680 const QualType SrcType = E->
getType();
2685 Src = Builder.CreateLaunderInvariantGroup(Src);
2693 Src = Builder.CreateStripInvariantGroup(Src);
2698 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2702 if (!PointeeType.
isNull())
2711 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2712 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2715 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2716 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2717 ScalableDstTy = llvm::ScalableVectorType::get(
2718 FixedSrcTy->getElementType(),
2720 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2722 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2723 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2724 llvm::Value *
Result = Builder.CreateInsertVector(
2725 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2727 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2728 if (
Result->getType() != ScalableDstTy)
2730 if (
Result->getType() != DstTy)
2740 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2741 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2744 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2745 FixedDstTy->getElementType()->isIntegerTy(8)) {
2746 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2747 ScalableSrcTy = llvm::ScalableVectorType::get(
2748 ScalableSrcTy->getElementType(),
2750 ScalableSrcTy->getElementCount().getKnownMinValue()));
2751 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2752 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2756 ScalableSrcTy = llvm::ScalableVectorType::get(
2757 FixedDstTy->getElementType(),
2758 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2759 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2761 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2762 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2783 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2786 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2789 case CK_AddressSpaceConversion: {
2792 Result.Val.isNullPointer()) {
2796 if (
Result.HasSideEffects)
2799 ConvertType(DestTy)), DestTy);
2805 case CK_AtomicToNonAtomic:
2806 case CK_NonAtomicToAtomic:
2807 case CK_UserDefinedConversion:
2814 case CK_BaseToDerived: {
2816 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2830 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2838 case CK_UncheckedDerivedToBase:
2839 case CK_DerivedToBase: {
2852 case CK_ArrayToPointerDecay:
2855 case CK_FunctionToPointerDecay:
2856 return EmitLValue(E).getPointer(CGF);
2858 case CK_NullToPointer:
2859 if (MustVisitNullValue(E))
2865 case CK_NullToMemberPointer: {
2866 if (MustVisitNullValue(E))
2869 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2873 case CK_ReinterpretMemberPointer:
2874 case CK_BaseToDerivedMemberPointer:
2875 case CK_DerivedToBaseMemberPointer: {
2876 Value *Src = Visit(E);
2887 case CK_ARCProduceObject:
2889 case CK_ARCConsumeObject:
2891 case CK_ARCReclaimReturnedObject:
2893 case CK_ARCExtendBlockObject:
2896 case CK_CopyAndAutoreleaseBlockObject:
2899 case CK_FloatingRealToComplex:
2900 case CK_FloatingComplexCast:
2901 case CK_IntegralRealToComplex:
2902 case CK_IntegralComplexCast:
2903 case CK_IntegralComplexToFloatingComplex:
2904 case CK_FloatingComplexToIntegralComplex:
2905 case CK_ConstructorConversion:
2907 case CK_HLSLArrayRValue:
2908 llvm_unreachable(
"scalar cast to non-scalar value");
2910 case CK_LValueToRValue:
2912 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2915 case CK_IntegralToPointer: {
2916 Value *Src = Visit(E);
2920 auto DestLLVMTy = ConvertType(DestTy);
2923 llvm::Value* IntResult =
2924 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2926 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2932 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2938 case CK_PointerToIntegral: {
2939 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2940 auto *PtrExpr = Visit(E);
2943 const QualType SrcType = E->
getType();
2948 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2952 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2958 case CK_MatrixCast: {
2959 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2966 case CK_HLSLAggregateSplatCast:
2967 case CK_VectorSplat: {
2968 llvm::Type *DstTy = ConvertType(DestTy);
2969 Value *Elt = Visit(E);
2971 llvm::ElementCount NumElements =
2973 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2976 case CK_FixedPointCast:
2977 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2980 case CK_FixedPointToBoolean:
2982 "Expected src type to be fixed point type");
2983 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2984 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2987 case CK_FixedPointToIntegral:
2989 "Expected src type to be fixed point type");
2990 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2991 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2994 case CK_IntegralToFixedPoint:
2996 "Expected src type to be an integer");
2998 "Expected dest type to be fixed point type");
2999 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3002 case CK_IntegralCast: {
3004 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3005 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3009 ScalarConversionOpts Opts;
3010 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3011 if (!ICE->isPartOfExplicitCast())
3012 Opts = ScalarConversionOpts(CGF.
SanOpts);
3014 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3017 case CK_IntegralToFloating: {
3020 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3022 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3023 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3025 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3026 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3029 case CK_FloatingToIntegral: {
3032 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3034 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3035 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3037 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3038 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3041 case CK_FloatingCast: {
3044 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3045 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3046 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3047 SrcElTy->
castAs<BuiltinType>()->getKind())
3048 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3049 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3051 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3052 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3055 case CK_FixedPointToFloating:
3056 case CK_FloatingToFixedPoint: {
3057 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3058 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3061 case CK_BooleanToSignedIntegral: {
3062 ScalarConversionOpts Opts;
3063 Opts.TreatBooleanAsSigned =
true;
3064 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3067 case CK_IntegralToBoolean:
3068 return EmitIntToBoolConversion(Visit(E));
3069 case CK_PointerToBoolean:
3070 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3071 case CK_FloatingToBoolean: {
3072 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3073 return EmitFloatToBoolConversion(Visit(E));
3075 case CK_MemberPointerToBoolean: {
3076 llvm::Value *MemPtr = Visit(E);
3077 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3081 case CK_FloatingComplexToReal:
3082 case CK_IntegralComplexToReal:
3085 case CK_FloatingComplexToBoolean:
3086 case CK_IntegralComplexToBoolean: {
3090 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3094 case CK_ZeroToOCLOpaqueType: {
3097 "CK_ZeroToOCLEvent cast on non-event type");
3098 return llvm::Constant::getNullValue(ConvertType(DestTy));
3101 case CK_IntToOCLSampler:
3104 case CK_HLSLVectorTruncation: {
3106 "Destination type must be a vector or builtin type.");
3107 Value *Vec = Visit(E);
3108 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3109 SmallVector<int> Mask;
3110 unsigned NumElts = VecTy->getNumElements();
3111 for (
unsigned I = 0; I != NumElts; ++I)
3114 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3116 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3117 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3119 case CK_HLSLMatrixTruncation: {
3121 "Destination type must be a matrix or builtin type.");
3122 Value *Mat = Visit(E);
3123 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3124 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3125 unsigned NumCols = MatTy->getNumColumns();
3126 unsigned NumRows = MatTy->getNumRows();
3127 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3128 assert(SrcMatTy &&
"Source type must be a matrix type.");
3129 assert(NumRows <= SrcMatTy->getNumRows());
3130 assert(NumCols <= SrcMatTy->getNumColumns());
3131 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
3132 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
3133 for (
unsigned R = 0; R < NumRows; R++)
3134 for (
unsigned C = 0;
C < NumCols;
C++)
3135 Mask[MatTy->getFlattenedIndex(R,
C, IsRowMajor)] =
3136 SrcMatTy->getFlattenedIndex(R,
C, IsRowMajor);
3138 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3140 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3141 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3143 case CK_HLSLElementwiseCast: {
3163 llvm_unreachable(
"unknown scalar cast");
3166Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3167 CodeGenFunction::StmtExprEvaluation eval(CGF);
3176Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3177 CodeGenFunction::RunCleanupsScope Scope(CGF);
3181 Scope.ForceCleanup({&
V});
3190 llvm::Value *InVal,
bool IsInc,
3194 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3196 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3197 BinOp.FPFeatures = FPFeatures;
3202llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3203 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3206 llvm::Value *Amount =
3207 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3208 StringRef Name = IsInc ?
"inc" :
"dec";
3212 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3213 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3215 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3216 case LangOptions::OB_Wrap:
3217 return Builder.CreateAdd(InVal, Amount, Name);
3218 case LangOptions::OB_SignedAndDefined:
3220 return Builder.CreateAdd(InVal, Amount, Name);
3222 case LangOptions::OB_Unset:
3224 return Builder.CreateAdd(InVal, Amount, Name);
3226 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3227 : Builder.CreateAdd(InVal, Amount, Name);
3229 case LangOptions::OB_Trap:
3231 return Builder.CreateAdd(InVal, Amount, Name);
3234 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3235 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3236 : Builder.CreateAdd(InVal, Amount, Name);
3237 return EmitOverflowCheckedBinOp(Info);
3239 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3244class OMPLastprivateConditionalUpdateRAII {
3246 CodeGenFunction &CGF;
3247 const UnaryOperator *E;
3250 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3251 const UnaryOperator *E)
3253 ~OMPLastprivateConditionalUpdateRAII() {
3262ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3263 bool isInc,
bool isPre) {
3265 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3267 llvm::PHINode *atomicPHI =
nullptr;
3271 QualType SrcType = E->
getType();
3273 int amount = (isInc ? 1 : -1);
3274 bool isSubtraction = !isInc;
3276 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3277 type = atomicTy->getValueType();
3278 if (isInc &&
type->isBooleanType()) {
3281 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3282 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3283 return Builder.getTrue();
3287 return Builder.CreateAtomicRMW(
3288 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3289 llvm::AtomicOrdering::SequentiallyConsistent);
3294 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3295 !(
type->isUnsignedIntegerType() &&
3296 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3298 LangOptions::SOB_Trapping) {
3299 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3300 llvm::AtomicRMWInst::Sub;
3301 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3302 llvm::Instruction::Sub;
3304 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3306 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3307 llvm::AtomicOrdering::SequentiallyConsistent);
3308 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3312 if (
type->isFloatingType()) {
3313 llvm::Type *Ty = ConvertType(
type);
3314 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3315 llvm::AtomicRMWInst::BinOp aop =
3316 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3317 llvm::Instruction::BinaryOps op =
3318 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3319 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3320 llvm::AtomicRMWInst *old =
3322 llvm::AtomicOrdering::SequentiallyConsistent);
3324 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3327 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3330 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3333 Builder.CreateBr(opBB);
3334 Builder.SetInsertPoint(opBB);
3335 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3336 atomicPHI->addIncoming(value, startBB);
3339 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3350 if (isInc &&
type->isBooleanType()) {
3351 value = Builder.getTrue();
3354 }
else if (
type->isIntegerType()) {
3355 QualType promotedType;
3356 bool canPerformLossyDemotionCheck =
false;
3360 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3361 canPerformLossyDemotionCheck =
true;
3362 canPerformLossyDemotionCheck &=
3365 canPerformLossyDemotionCheck &=
3367 type, promotedType);
3368 assert((!canPerformLossyDemotionCheck ||
3369 type->isSignedIntegerOrEnumerationType() ||
3371 ConvertType(
type)->getScalarSizeInBits() ==
3372 ConvertType(promotedType)->getScalarSizeInBits()) &&
3373 "The following check expects that if we do promotion to different "
3374 "underlying canonical type, at least one of the types (either "
3375 "base or promoted) will be signed, or the bitwidths will match.");
3378 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3379 SanitizerKind::ImplicitBitfieldConversion) &&
3380 canPerformLossyDemotionCheck) {
3394 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3395 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3396 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3400 ScalarConversionOpts Opts;
3401 if (!LV.isBitField())
3402 Opts = ScalarConversionOpts(CGF.
SanOpts);
3403 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3405 SrcType = promotedType;
3408 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3414 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3415 type->isUnsignedIntegerType()) {
3416 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3421 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3422 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3426 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3427 QualType
type = ptr->getPointeeType();
3430 if (
const VariableArrayType *vla
3433 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3436 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3439 elemTy, value, numElts,
false, isSubtraction,
3443 }
else if (
type->isFunctionType()) {
3444 llvm::Value *amt = Builder.getInt32(amount);
3447 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3451 false, isSubtraction,
3456 llvm::Value *amt = Builder.getInt32(amount);
3459 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3462 elemTy, value, amt,
false, isSubtraction,
3467 }
else if (
type->isVectorType()) {
3468 if (
type->hasIntegerRepresentation()) {
3469 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3471 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3473 value = Builder.CreateFAdd(
3475 llvm::ConstantFP::get(value->getType(), amount),
3476 isInc ?
"inc" :
"dec");
3480 }
else if (
type->isRealFloatingType()) {
3483 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3489 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3492 if (value->getType()->isFloatTy())
3493 amt = llvm::ConstantFP::get(VMContext,
3494 llvm::APFloat(
static_cast<float>(amount)));
3495 else if (value->getType()->isDoubleTy())
3496 amt = llvm::ConstantFP::get(VMContext,
3497 llvm::APFloat(
static_cast<double>(amount)));
3501 llvm::APFloat F(
static_cast<float>(amount));
3503 const llvm::fltSemantics *FS;
3506 if (value->getType()->isFP128Ty())
3508 else if (value->getType()->isHalfTy())
3510 else if (value->getType()->isBFloatTy())
3512 else if (value->getType()->isPPC_FP128Ty())
3516 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3517 amt = llvm::ConstantFP::get(VMContext, F);
3519 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3522 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3523 value = Builder.CreateBitCast(value, input->getType());
3527 }
else if (
type->isFixedPointType()) {
3534 Info.Opcode = isInc ? BO_Add : BO_Sub;
3536 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3539 if (
type->isSignedFixedPointType()) {
3540 Info.Opcode = isInc ? BO_Sub : BO_Add;
3541 Info.RHS = Builder.CreateNeg(Info.RHS);
3546 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3548 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3549 value = EmitFixedPointBinOp(Info);
3553 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3556 if (!isInc) size = -size;
3557 llvm::Value *sizeValue =
3558 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3561 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3564 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3566 value = Builder.CreateBitCast(value, input->getType());
3570 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3575 llvm::Value *
success = Pair.second;
3576 atomicPHI->addIncoming(old, curBlock);
3577 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3578 Builder.SetInsertPoint(contBB);
3579 return isPre ? value : input;
3583 if (LV.isBitField()) {
3593 return isPre ? value : input;
3597Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3598 QualType PromotionType) {
3599 QualType promotionTy = PromotionType.
isNull()
3602 Value *result = VisitPlus(E, promotionTy);
3603 if (result && !promotionTy.
isNull())
3604 result = EmitUnPromotedValue(result, E->
getType());
3608Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3609 QualType PromotionType) {
3611 TestAndClearIgnoreResultAssign();
3612 if (!PromotionType.
isNull())
3617Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3618 QualType PromotionType) {
3619 QualType promotionTy = PromotionType.
isNull()
3622 Value *result = VisitMinus(E, promotionTy);
3623 if (result && !promotionTy.
isNull())
3624 result = EmitUnPromotedValue(result, E->
getType());
3628Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3629 QualType PromotionType) {
3630 TestAndClearIgnoreResultAssign();
3632 if (!PromotionType.
isNull())
3638 if (Op->
getType()->isFPOrFPVectorTy())
3639 return Builder.CreateFNeg(Op,
"fneg");
3644 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3646 BinOp.Opcode = BO_Sub;
3649 return EmitSub(BinOp);
3652Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3653 TestAndClearIgnoreResultAssign();
3655 return Builder.CreateNot(Op,
"not");
3658Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3662 VectorKind::Generic) {
3666 if (Oper->
getType()->isFPOrFPVectorTy()) {
3667 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3669 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3671 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3672 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3681 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3684 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3687Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3689 Expr::EvalResult EVResult;
3692 return Builder.getInt(
Value);
3697 llvm::Type* ResultType = ConvertType(E->
getType());
3698 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3700 for (
unsigned i = 0; i != n; ++i) {
3702 llvm::Value *Offset =
nullptr;
3709 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3716 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3720 Offset = Builder.CreateMul(Idx, ElemSize);
3725 FieldDecl *MemberDecl = ON.
getField();
3733 FieldEnd = RD->field_end();
3734 Field != FieldEnd; ++Field, ++i) {
3735 if (*Field == MemberDecl)
3738 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3743 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3746 CurrentType = MemberDecl->
getType();
3751 llvm_unreachable(
"dependent __builtin_offsetof");
3768 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3780ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3781 const UnaryExprOrTypeTraitExpr *E) {
3784 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3785 if (
const VariableArrayType *VAT =
3790 bool EvaluateExtent =
true;
3791 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3793 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3795 if (EvaluateExtent) {
3806 if (Kind == UETT_CountOf)
3815 if (!eltSize.
isOne())
3818 return VlaSize.NumElts;
3821 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3827 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3828 }
else if (E->
getKind() == UETT_VectorElements) {
3830 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3838Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3839 QualType PromotionType) {
3840 QualType promotionTy = PromotionType.
isNull()
3843 Value *result = VisitReal(E, promotionTy);
3844 if (result && !promotionTy.
isNull())
3845 result = EmitUnPromotedValue(result, E->
getType());
3849Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3850 QualType PromotionType) {
3857 if (!PromotionType.
isNull()) {
3859 Op, IgnoreResultAssign,
true);
3874 if (!PromotionType.
isNull())
3879Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3880 QualType PromotionType) {
3881 QualType promotionTy = PromotionType.
isNull()
3884 Value *result = VisitImag(E, promotionTy);
3885 if (result && !promotionTy.
isNull())
3886 result = EmitUnPromotedValue(result, E->
getType());
3890Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3891 QualType PromotionType) {
3898 if (!PromotionType.
isNull()) {
3900 Op,
true, IgnoreResultAssign);
3904 return result.second
3920 else if (!PromotionType.
isNull())
3924 if (!PromotionType.
isNull())
3925 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3926 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3933Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3934 QualType PromotionType) {
3935 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3938Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3939 QualType ExprType) {
3940 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3943Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3945 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3947#define HANDLE_BINOP(OP) \
3949 return Emit##OP(EmitBinOps(BO, PromotionType));
3958 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3961 return VisitImag(UO, PromotionType);
3963 return VisitReal(UO, PromotionType);
3965 return VisitMinus(UO, PromotionType);
3967 return VisitPlus(UO, PromotionType);
3972 auto result = Visit(
const_cast<Expr *
>(E));
3974 if (!PromotionType.
isNull())
3975 return EmitPromotedValue(result, PromotionType);
3977 return EmitUnPromotedValue(result, E->
getType());
3982BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3983 QualType PromotionType) {
3984 TestAndClearIgnoreResultAssign();
3988 if (!PromotionType.
isNull())
3989 Result.Ty = PromotionType;
3998LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3999 const CompoundAssignOperator *E,
4000 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4011 QualType PromotionTypeCR;
4013 if (PromotionTypeCR.
isNull())
4016 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4017 if (!PromotionTypeRHS.
isNull())
4020 OpInfo.RHS = Visit(E->
getRHS());
4021 OpInfo.Ty = PromotionTypeCR;
4028 llvm::PHINode *atomicPHI =
nullptr;
4029 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4030 QualType
type = atomicTy->getValueType();
4031 if (!
type->isBooleanType() &&
type->isIntegerType() &&
4032 !(
type->isUnsignedIntegerType() &&
4033 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4035 LangOptions::SOB_Trapping) {
4036 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4037 llvm::Instruction::BinaryOps Op;
4038 switch (OpInfo.Opcode) {
4040 case BO_MulAssign:
case BO_DivAssign:
4046 AtomicOp = llvm::AtomicRMWInst::Add;
4047 Op = llvm::Instruction::Add;
4050 AtomicOp = llvm::AtomicRMWInst::Sub;
4051 Op = llvm::Instruction::Sub;
4054 AtomicOp = llvm::AtomicRMWInst::And;
4055 Op = llvm::Instruction::And;
4058 AtomicOp = llvm::AtomicRMWInst::Xor;
4059 Op = llvm::Instruction::Xor;
4062 AtomicOp = llvm::AtomicRMWInst::Or;
4063 Op = llvm::Instruction::Or;
4066 llvm_unreachable(
"Invalid compound assignment type");
4068 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4070 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4074 llvm::AtomicRMWInst *OldVal =
4079 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4085 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4087 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4089 Builder.CreateBr(opBB);
4090 Builder.SetInsertPoint(opBB);
4091 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4092 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4093 OpInfo.LHS = atomicPHI;
4096 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4098 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4100 if (!PromotionTypeLHS.
isNull())
4101 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4104 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4115 if (LHSLV.isBitField()) {
4117 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4118 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4120 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4121 Loc, ScalarConversionOpts(CGF.
SanOpts));
4123 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4124 ScalarConversionOpts(CGF.
SanOpts));
4128 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4132 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4133 llvm::Value *
success = Pair.second;
4134 atomicPHI->addIncoming(old, curBlock);
4135 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4136 Builder.SetInsertPoint(contBB);
4144 if (LHSLV.isBitField()) {
4160Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4161 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4162 bool Ignore = TestAndClearIgnoreResultAssign();
4163 Value *RHS =
nullptr;
4164 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4175 if (!LHS.isVolatileQualified())
4179 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4182void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4183 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4184 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4187 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4188 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4189 SanitizerKind::SO_IntegerDivideByZero));
4193 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4194 Ops.Ty->hasSignedIntegerRepresentation() &&
4196 Ops.mayHaveIntegerOverflow() && !Ops.Ty.isWrapType()) {
4199 llvm::Value *IntMin =
4200 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4201 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4203 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4204 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4205 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4207 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4210 if (Checks.size() > 0)
4211 EmitBinOpCheck(Checks, Ops);
4214Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4216 SanitizerDebugLocation SanScope(&CGF,
4217 {SanitizerKind::SO_IntegerDivideByZero,
4218 SanitizerKind::SO_SignedIntegerOverflow,
4219 SanitizerKind::SO_FloatDivideByZero},
4220 SanitizerHandler::DivremOverflow);
4221 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4222 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4223 Ops.Ty->isIntegerType() &&
4224 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4225 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4226 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4227 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4228 Ops.Ty->isRealFloatingType() &&
4229 Ops.mayHaveFloatDivisionByZero()) {
4230 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4231 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4233 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4237 if (Ops.Ty->isConstantMatrixType()) {
4238 llvm::MatrixBuilder MB(Builder);
4245 "first operand must be a matrix");
4247 "second operand must be an arithmetic type");
4248 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4249 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4250 Ops.Ty->hasUnsignedIntegerRepresentation());
4253 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4255 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4256 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4260 else if (Ops.isFixedPointOp())
4261 return EmitFixedPointBinOp(Ops);
4262 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4263 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4265 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4268Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4270 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4271 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4272 Ops.Ty->isIntegerType() &&
4273 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4274 SanitizerDebugLocation SanScope(&CGF,
4275 {SanitizerKind::SO_IntegerDivideByZero,
4276 SanitizerKind::SO_SignedIntegerOverflow},
4277 SanitizerHandler::DivremOverflow);
4278 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4279 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4282 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4283 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4285 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4286 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4288 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4291Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4296 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4297 switch (Ops.Opcode) {
4301 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4302 llvm::Intrinsic::uadd_with_overflow;
4303 OverflowKind = SanitizerHandler::AddOverflow;
4308 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4309 llvm::Intrinsic::usub_with_overflow;
4310 OverflowKind = SanitizerHandler::SubOverflow;
4315 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4316 llvm::Intrinsic::umul_with_overflow;
4317 OverflowKind = SanitizerHandler::MulOverflow;
4320 llvm_unreachable(
"Unsupported operation for overflow detection");
4326 SanitizerDebugLocation SanScope(&CGF,
4327 {SanitizerKind::SO_SignedIntegerOverflow,
4328 SanitizerKind::SO_UnsignedIntegerOverflow},
4334 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4335 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4336 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4339 const std::string *handlerName =
4341 if (handlerName->empty()) {
4347 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4348 llvm::Value *NotOf = Builder.CreateNot(overflow);
4350 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4353 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4356 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4357 llvm::Value *NotOf = Builder.CreateNot(overflow);
4359 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4362 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4367 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4368 llvm::BasicBlock *continueBB =
4372 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4376 Builder.SetInsertPoint(overflowBB);
4379 llvm::Type *Int8Ty = CGF.
Int8Ty;
4380 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4381 llvm::FunctionType *handlerTy =
4382 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4383 llvm::FunctionCallee handler =
4388 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4389 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4393 llvm::Value *handlerArgs[] = {
4396 Builder.getInt8(OpID),
4399 llvm::Value *handlerResult =
4403 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4404 Builder.CreateBr(continueBB);
4406 Builder.SetInsertPoint(continueBB);
4407 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4408 phi->addIncoming(result, initialBB);
4409 phi->addIncoming(handlerResult, overflowBB);
4418 bool isSubtraction) {
4423 Value *pointer = op.LHS;
4424 Expr *pointerOperand =
expr->getLHS();
4426 Expr *indexOperand =
expr->getRHS();
4429 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4430 std::swap(pointer,
index);
4431 std::swap(pointerOperand, indexOperand);
4435 index, isSubtraction);
4441 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4445 auto &DL =
CGM.getDataLayout();
4468 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4470 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4471 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4472 PtrTy->getPointerAddressSpace()))
4475 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4476 auto CheckHandler = SanitizerHandler::PointerOverflow;
4478 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4480 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4481 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4483 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4484 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4489 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4500 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4510 llvm::Value *objectSize =
4516 return Builder.CreateBitCast(result, pointer->getType());
4521 getContext().getAsVariableArrayType(elementType)) {
4523 llvm::Value *numElements =
getVLASize(vla).NumElts;
4532 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4552 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4565 bool negMul,
bool negAdd) {
4566 Value *MulOp0 = MulOp->getOperand(0);
4567 Value *MulOp1 = MulOp->getOperand(1);
4569 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4571 Addend = Builder.CreateFNeg(Addend,
"neg");
4573 Value *FMulAdd =
nullptr;
4574 if (Builder.getIsFPConstrained()) {
4576 "Only constrained operation should be created when Builder is in FP "
4577 "constrained mode");
4578 FMulAdd = Builder.CreateConstrainedFPCall(
4579 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4581 {MulOp0, MulOp1, Addend});
4583 FMulAdd = Builder.CreateCall(
4585 {MulOp0, MulOp1, Addend});
4587 MulOp->eraseFromParent();
4602 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4603 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4604 "Only fadd/fsub can be the root of an fmuladd.");
4607 if (!op.FPFeatures.allowFPContractWithinStatement())
4610 Value *LHS = op.LHS;
4611 Value *RHS = op.RHS;
4615 bool NegLHS =
false;
4616 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4617 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4618 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4619 LHS = LHSUnOp->getOperand(0);
4624 bool NegRHS =
false;
4625 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4626 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4627 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4628 RHS = RHSUnOp->getOperand(0);
4636 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4637 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4638 (LHSBinOp->use_empty() || NegLHS)) {
4642 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4645 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4646 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4647 (RHSBinOp->use_empty() || NegRHS)) {
4651 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4655 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4656 if (LHSBinOp->getIntrinsicID() ==
4657 llvm::Intrinsic::experimental_constrained_fmul &&
4658 (LHSBinOp->use_empty() || NegLHS)) {
4662 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4665 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4666 if (RHSBinOp->getIntrinsicID() ==
4667 llvm::Intrinsic::experimental_constrained_fmul &&
4668 (RHSBinOp->use_empty() || NegRHS)) {
4672 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4679Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4680 if (op.LHS->getType()->isPointerTy() ||
4681 op.RHS->getType()->isPointerTy())
4684 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4685 op.Ty->isUnsignedIntegerType()) {
4686 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4688 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4689 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4690 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4691 case LangOptions::OB_Wrap:
4692 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4693 case LangOptions::OB_SignedAndDefined:
4695 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4697 case LangOptions::OB_Unset:
4699 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4700 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4702 case LangOptions::OB_Trap:
4703 if (CanElideOverflowCheck(CGF.
getContext(), op))
4704 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4705 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4706 return EmitOverflowCheckedBinOp(op);
4711 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4712 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4718 if (op.Ty->isConstantMatrixType()) {
4719 llvm::MatrixBuilder MB(Builder);
4720 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4721 return MB.CreateAdd(op.LHS, op.RHS);
4724 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4725 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4726 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4729 if (op.isFixedPointOp())
4730 return EmitFixedPointBinOp(op);
4732 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4737Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4739 using llvm::ConstantInt;
4745 QualType ResultTy = op.Ty;
4746 QualType LHSTy, RHSTy;
4747 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4748 RHSTy = BinOp->getRHS()->getType();
4749 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4754 LHSTy = CAO->getComputationLHSType();
4755 ResultTy = CAO->getComputationResultType();
4757 LHSTy = BinOp->getLHS()->getType();
4758 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4759 LHSTy = UnOp->getSubExpr()->getType();
4760 RHSTy = UnOp->getSubExpr()->getType();
4763 Value *LHS = op.LHS;
4764 Value *RHS = op.RHS;
4769 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4773 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4774 switch (op.Opcode) {
4777 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4781 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4785 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4789 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4793 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4797 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4800 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4802 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4804 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4806 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4811 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4813 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4817 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4830 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4836 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4841Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4843 if (!op.LHS->getType()->isPointerTy()) {
4844 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4845 op.Ty->isUnsignedIntegerType()) {
4846 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4848 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4849 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4850 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4851 case LangOptions::OB_Wrap:
4852 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4853 case LangOptions::OB_SignedAndDefined:
4855 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4857 case LangOptions::OB_Unset:
4859 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4860 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4862 case LangOptions::OB_Trap:
4863 if (CanElideOverflowCheck(CGF.
getContext(), op))
4864 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4865 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4866 return EmitOverflowCheckedBinOp(op);
4871 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4872 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4878 if (op.Ty->isConstantMatrixType()) {
4879 llvm::MatrixBuilder MB(Builder);
4880 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4881 return MB.CreateSub(op.LHS, op.RHS);
4884 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4885 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4886 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4889 if (op.isFixedPointOp())
4890 return EmitFixedPointBinOp(op);
4892 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4897 if (!op.RHS->getType()->isPointerTy())
4904 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4906 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4907 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4911 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4913 llvm::Value *divisor =
nullptr;
4916 if (
const VariableArrayType *vla
4919 elementType = VlaSize.Type;
4920 divisor = VlaSize.NumElts;
4924 if (!eltSize.
isOne())
4931 CharUnits elementSize;
4940 if (elementSize.
isOne())
4949 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4952Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4954 llvm::IntegerType *Ty;
4955 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4963 llvm::Type *RHSTy = RHS->
getType();
4964 llvm::APInt RHSMax =
4965 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4966 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4967 if (RHSMax.ult(Ty->getBitWidth()))
4968 return llvm::ConstantInt::get(RHSTy, RHSMax);
4969 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4973 const Twine &Name) {
4974 llvm::IntegerType *Ty;
4975 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4980 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4981 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4983 return Builder.CreateURem(
4984 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4987Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4989 if (Ops.isFixedPointOp())
4990 return EmitFixedPointBinOp(Ops);
4994 Value *RHS = Ops.RHS;
4995 if (Ops.LHS->getType() != RHS->
getType())
4996 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4998 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4999 Ops.Ty->hasSignedIntegerRepresentation() &&
5002 bool SanitizeUnsignedBase =
5003 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5004 Ops.Ty->hasUnsignedIntegerRepresentation();
5005 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5006 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5009 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5010 else if ((SanitizeBase || SanitizeExponent) &&
5012 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5013 if (SanitizeSignedBase)
5014 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5015 if (SanitizeUnsignedBase)
5016 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5017 if (SanitizeExponent)
5018 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5020 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5021 SanitizerHandler::ShiftOutOfBounds);
5022 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5023 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5024 llvm::Value *WidthMinusOne =
5025 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5026 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5028 if (SanitizeExponent) {
5030 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5037 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5040 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5041 llvm::Value *PromotedWidthMinusOne =
5042 (RHS == Ops.RHS) ? WidthMinusOne
5043 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5045 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5046 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5055 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5056 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5058 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5059 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5061 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5062 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5063 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5064 Checks.push_back(std::make_pair(
5065 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5066 : SanitizerKind::SO_UnsignedShiftBase));
5069 assert(!Checks.empty());
5070 EmitBinOpCheck(Checks, Ops);
5073 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5076Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5078 if (Ops.isFixedPointOp())
5079 return EmitFixedPointBinOp(Ops);
5083 Value *RHS = Ops.RHS;
5084 if (Ops.LHS->getType() != RHS->
getType())
5085 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5089 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5090 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5092 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5093 SanitizerHandler::ShiftOutOfBounds);
5094 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5095 llvm::Value *
Valid = Builder.CreateICmpULE(
5096 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5097 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5100 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5101 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5102 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5110 default: llvm_unreachable(
"unexpected element type");
5111 case BuiltinType::Char_U:
5112 case BuiltinType::UChar:
5113 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5114 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5115 case BuiltinType::Char_S:
5116 case BuiltinType::SChar:
5117 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5118 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5119 case BuiltinType::UShort:
5120 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5121 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5122 case BuiltinType::Short:
5123 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5124 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5125 case BuiltinType::UInt:
5126 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5127 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5128 case BuiltinType::Int:
5129 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5130 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5131 case BuiltinType::ULong:
5132 case BuiltinType::ULongLong:
5133 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5134 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5135 case BuiltinType::Long:
5136 case BuiltinType::LongLong:
5137 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5138 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5139 case BuiltinType::Float:
5140 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5141 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5142 case BuiltinType::Double:
5143 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5144 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5145 case BuiltinType::UInt128:
5146 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5147 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5148 case BuiltinType::Int128:
5149 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5150 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5154Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5155 llvm::CmpInst::Predicate UICmpOpc,
5156 llvm::CmpInst::Predicate SICmpOpc,
5157 llvm::CmpInst::Predicate FCmpOpc,
5159 TestAndClearIgnoreResultAssign();
5163 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5169 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5171 BinOpInfo BOInfo = EmitBinOps(E);
5172 Value *LHS = BOInfo.LHS;
5173 Value *RHS = BOInfo.RHS;
5179 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5181 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5184 Value *FirstVecArg = LHS,
5185 *SecondVecArg = RHS;
5187 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5191 default: llvm_unreachable(
"is not a comparison operation");
5203 std::swap(FirstVecArg, SecondVecArg);
5210 if (ElementKind == BuiltinType::Float) {
5212 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5213 std::swap(FirstVecArg, SecondVecArg);
5221 if (ElementKind == BuiltinType::Float) {
5223 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5228 std::swap(FirstVecArg, SecondVecArg);
5233 Value *CR6Param = Builder.getInt32(CR6);
5235 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5243 if (ResultTy->getBitWidth() > 1 &&
5245 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5250 if (BOInfo.isFixedPointOp()) {
5251 Result = EmitFixedPointBinOp(BOInfo);
5252 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5253 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5255 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5257 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5259 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5274 LHS = Builder.CreateStripInvariantGroup(LHS);
5276 RHS = Builder.CreateStripInvariantGroup(RHS);
5279 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5285 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5291 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5293 CETy = CTy->getElementType();
5295 LHS.first = Visit(E->
getLHS());
5296 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5299 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5302 CTy->getElementType()) &&
5303 "The element types must always match.");
5306 RHS.first = Visit(E->
getRHS());
5307 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5309 "The element types must always match.");
5312 Value *ResultR, *ResultI;
5316 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5317 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5321 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5322 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5326 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5329 "Complex comparison other than == or != ?");
5330 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5342 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5343 CastKind Kind = ICE->getCastKind();
5344 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5345 *SrcType = ICE->getSubExpr()->getType();
5358 bool Ignore = TestAndClearIgnoreResultAssign();
5392 RHS = Visit(E->
getRHS());
5408 RHS = Visit(E->
getRHS());
5448 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5451Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5462 if (LHS->
getType()->isFPOrFPVectorTy()) {
5463 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5465 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5466 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5468 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5469 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5471 Value *
And = Builder.CreateAnd(LHS, RHS);
5472 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5476 llvm::Type *ResTy = ConvertType(E->
getType());
5495 if (InstrumentRegions &&
5499 llvm::BasicBlock *RHSSkip =
5502 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5519 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5530 return llvm::Constant::getNullValue(ResTy);
5541 llvm::BasicBlock *LHSFalseBlock =
5544 CodeGenFunction::ConditionalEvaluation eval(CGF);
5559 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5561 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5563 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5572 RHSBlock = Builder.GetInsertBlock();
5577 llvm::BasicBlock *ContIncoming = RHSBlock;
5578 if (InstrumentRegions &&
5582 llvm::BasicBlock *RHSBlockSkip =
5584 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5588 PN->addIncoming(RHSCond, RHSBlockCnt);
5593 ContIncoming = RHSBlockSkip;
5604 PN->addIncoming(RHSCond, ContIncoming);
5613 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5617 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5620Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5631 if (LHS->
getType()->isFPOrFPVectorTy()) {
5632 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5634 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5635 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5637 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5638 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5640 Value *
Or = Builder.CreateOr(LHS, RHS);
5641 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5645 llvm::Type *ResTy = ConvertType(E->
getType());
5664 if (InstrumentRegions &&
5668 llvm::BasicBlock *RHSSkip =
5671 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5688 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5699 return llvm::ConstantInt::get(ResTy, 1);
5709 llvm::BasicBlock *LHSTrueBlock =
5712 CodeGenFunction::ConditionalEvaluation eval(CGF);
5728 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5730 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5732 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5744 RHSBlock = Builder.GetInsertBlock();
5749 llvm::BasicBlock *ContIncoming = RHSBlock;
5750 if (InstrumentRegions &&
5754 llvm::BasicBlock *RHSTrueBlock =
5756 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5760 PN->addIncoming(RHSCond, RHSBlockCnt);
5765 ContIncoming = RHSTrueBlock;
5772 PN->addIncoming(RHSCond, ContIncoming);
5779 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5782Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5785 return Visit(E->
getRHS());
5810Value *ScalarExprEmitter::
5811VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5812 TestAndClearIgnoreResultAssign();
5815 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5817 Expr *condExpr = E->
getCond();
5825 Expr *live = lhsExpr, *dead = rhsExpr;
5826 if (!CondExprBool) std::swap(live, dead);
5853 llvm::Value *LHS = Visit(lhsExpr);
5854 llvm::Value *RHS = Visit(rhsExpr);
5856 llvm::Type *condType = ConvertType(condExpr->
getType());
5859 unsigned numElem = vecTy->getNumElements();
5860 llvm::Type *elemType = vecTy->getElementType();
5862 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5863 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5864 llvm::Value *tmp = Builder.CreateSExt(
5865 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5866 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5869 llvm::Value *RHSTmp = RHS;
5870 llvm::Value *LHSTmp = LHS;
5871 bool wasCast =
false;
5873 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5874 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5875 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5879 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5880 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5881 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5883 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5893 llvm::Value *LHS = Visit(lhsExpr);
5894 llvm::Value *RHS = Visit(rhsExpr);
5896 llvm::Type *CondType = ConvertType(condExpr->
getType());
5899 if (VecTy->getElementType()->isIntegerTy(1))
5900 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5903 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5905 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5907 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5908 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5918 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5922 llvm::Value *LHS = Visit(lhsExpr);
5923 llvm::Value *RHS = Visit(rhsExpr);
5926 assert(!RHS &&
"LHS and RHS types must match");
5929 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5940 CodeGenFunction::ConditionalEvaluation eval(CGF);
5954 Value *LHS = Visit(lhsExpr);
5957 LHSBlock = Builder.GetInsertBlock();
5958 Builder.CreateBr(ContBlock);
5970 Value *RHS = Visit(rhsExpr);
5973 RHSBlock = Builder.GetInsertBlock();
5983 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5984 PN->addIncoming(LHS, LHSBlock);
5985 PN->addIncoming(RHS, RHSBlock);
5990Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5994Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5996 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6001Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6007 Value *Src,
unsigned NumElementsDst) {
6008 static constexpr int Mask[] = {0, 1, 2, -1};
6009 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6029 const llvm::DataLayout &DL,
6030 Value *Src, llvm::Type *DstTy,
6031 StringRef Name =
"") {
6035 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6036 return Builder.CreateBitCast(Src, DstTy, Name);
6039 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6040 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6043 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6045 if (!DstTy->isIntegerTy())
6046 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6048 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6052 if (!SrcTy->isIntegerTy())
6053 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6055 return Builder.CreateIntToPtr(Src, DstTy, Name);
6058Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6060 llvm::Type *DstTy = ConvertType(E->
getType());
6062 llvm::Type *SrcTy = Src->
getType();
6063 unsigned NumElementsSrc =
6067 unsigned NumElementsDst =
6078 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6083 Src->setName(
"astype");
6090 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6091 auto *Vec4Ty = llvm::FixedVectorType::get(
6097 Src->setName(
"astype");
6102 Src, DstTy,
"astype");
6105Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6117 "Invalid scalar expression to emit");
6119 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6120 .Visit(
const_cast<Expr *
>(E));
6129 "Invalid scalar expression to emit");
6130 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6140 "Invalid complex -> scalar conversion");
6141 return ScalarExprEmitter(*
this)
6142 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6149 if (!PromotionType.
isNull())
6150 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6152 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6158 bool isInc,
bool isPre) {
6159 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6169 llvm::Type *BaseTy =
6185 ScalarExprEmitter Scalar(*
this);
6188#define COMPOUND_OP(Op) \
6189 case BO_##Op##Assign: \
6190 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6227 llvm_unreachable(
"Not valid compound assignment operators");
6230 llvm_unreachable(
"Unhandled compound assignment operator");
6245 llvm::LLVMContext &VMContext,
6251 llvm::Value *TotalOffset =
nullptr;
6257 Value *BasePtr_int =
6258 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6260 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6261 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6262 return {TotalOffset, Builder.getFalse()};
6266 assert(GEP->getPointerOperand() == BasePtr &&
6267 "BasePtr must be the base of the GEP.");
6268 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6270 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6273 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6274 auto *SAddIntrinsic =
6275 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6276 auto *SMulIntrinsic =
6277 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6280 llvm::Value *OffsetOverflows = Builder.getFalse();
6284 llvm::Value *RHS) -> llvm::Value * {
6285 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6288 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6289 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6291 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6294 OffsetOverflows = Builder.getTrue();
6295 return llvm::ConstantInt::get(VMContext, N);
6300 auto *ResultAndOverflow = Builder.CreateCall(
6301 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6302 OffsetOverflows = Builder.CreateOr(
6303 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6304 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6308 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6309 GTI != GTE; ++GTI) {
6310 llvm::Value *LocalOffset;
6311 auto *Index = GTI.getOperand();
6313 if (
auto *STy = GTI.getStructTypeOrNull()) {
6317 LocalOffset = llvm::ConstantInt::get(
6318 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6323 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6324 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6325 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6330 if (!TotalOffset || TotalOffset ==
Zero)
6331 TotalOffset = LocalOffset;
6333 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6336 return {TotalOffset, OffsetOverflows};
6341 ArrayRef<Value *> IdxList,
6342 bool SignedIndices,
bool IsSubtraction,
6343 SourceLocation Loc,
const Twine &Name) {
6344 llvm::Type *PtrTy = Ptr->
getType();
6346 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6347 if (!SignedIndices && !IsSubtraction)
6348 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6350 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6353 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6357 bool PerformNullCheck = !NullPointerIsDefined(
6358 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6361 bool PerformOverflowCheck =
6364 if (!(PerformNullCheck || PerformOverflowCheck))
6367 const auto &DL = CGM.getDataLayout();
6369 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6370 auto CheckHandler = SanitizerHandler::PointerOverflow;
6371 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6372 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6374 GEPOffsetAndOverflow EvaluatedGEP =
6379 "If the offset got constant-folded, we don't expect that there was an "
6382 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6390 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6391 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6393 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6397 if (PerformNullCheck) {
6405 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6406 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6407 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6408 Checks.emplace_back(
Valid, CheckOrdinal);
6411 if (PerformOverflowCheck) {
6416 llvm::Value *ValidGEP;
6417 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6418 if (SignedIndices) {
6424 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6425 auto *PosOrZeroOffset =
6427 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6429 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6430 }
else if (!IsSubtraction) {
6435 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6441 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6443 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6444 Checks.emplace_back(ValidGEP, CheckOrdinal);
6447 assert(!Checks.empty() &&
"Should have produced some checks.");
6449 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6451 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6452 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6458 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6459 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6460 const Twine &Name) {
6461 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6462 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6463 if (!SignedIndices && !IsSubtraction)
6464 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6466 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6470 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6471 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6472 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * 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.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
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.
specific_decl_iterator< FieldDecl > field_iterator
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether conversions to and from __fp16 should go through an integer bitcast with i16.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool BitCast(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Result
The result type of a method or function.
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 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.