37#include "llvm/ADT/APFixedPoint.h"
38#include "llvm/ADT/ScopeExit.h"
39#include "llvm/Analysis/ValueTracking.h"
40#include "llvm/IR/Argument.h"
41#include "llvm/IR/CFG.h"
42#include "llvm/IR/Constants.h"
43#include "llvm/IR/DataLayout.h"
44#include "llvm/IR/DerivedTypes.h"
45#include "llvm/IR/FixedPointBuilder.h"
46#include "llvm/IR/Function.h"
47#include "llvm/IR/GEPNoWrapFlags.h"
48#include "llvm/IR/GetElementPtrTypeIterator.h"
49#include "llvm/IR/GlobalVariable.h"
50#include "llvm/IR/Intrinsics.h"
51#include "llvm/IR/IntrinsicsPowerPC.h"
52#include "llvm/IR/IntrinsicsWebAssembly.h"
53#include "llvm/IR/MatrixBuilder.h"
54#include "llvm/IR/Module.h"
55#include "llvm/Support/TypeSize.h"
78bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
83 const auto &LHSAP = LHS->getValue();
84 const auto &RHSAP = RHS->getValue();
85 if (Opcode == BO_Add) {
87 : LHSAP.uadd_ov(RHSAP, Overflow);
88 }
else if (Opcode == BO_Sub) {
90 : LHSAP.usub_ov(RHSAP, Overflow);
91 }
else if (Opcode == BO_Mul) {
93 : LHSAP.umul_ov(RHSAP, Overflow);
94 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
95 if (
Signed && !RHS->isZero())
96 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
108 FPOptions FPFeatures;
112 bool mayHaveIntegerOverflow()
const {
114 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
115 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
116 if (!LHSCI || !RHSCI)
120 return ::mayHaveIntegerOverflow(
125 bool isDivremOp()
const {
131 bool mayHaveIntegerDivisionByZero()
const {
133 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
139 bool mayHaveFloatDivisionByZero()
const {
141 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
142 return CFP->isZero();
149 bool isFixedPointOp()
const {
152 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
153 QualType LHSType = BinOp->getLHS()->getType();
154 QualType RHSType = BinOp->getRHS()->getType();
157 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
158 return UnOp->getSubExpr()->getType()->isFixedPointType();
163 bool rhsHasSignedIntegerRepresentation()
const {
164 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
165 QualType RHSType = BinOp->getRHS()->getType();
172static bool MustVisitNullValue(
const Expr *E) {
195static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
205 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
210 switch (OBT->getBehaviorKind()) {
211 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
213 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
216 llvm_unreachable(
"Unknown OverflowBehaviorKind");
223 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
231 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
235static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
237 "Expected a unary or binary operator");
241 if (!Op.mayHaveIntegerOverflow())
248 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
249 if (BO && BO->hasExcludedOverflowPattern())
252 if (Op.Ty.isWrapType())
254 if (Op.Ty.isTrapType())
257 if (Op.Ty->isSignedIntegerType() &&
263 if (Op.Ty->isUnsignedIntegerType() &&
288 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
294 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
295 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
299class ScalarExprEmitter
301 CodeGenFunction &CGF;
302 CGBuilderTy &Builder;
303 bool IgnoreResultAssign;
304 llvm::LLVMContext &VMContext;
307 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
308 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
309 VMContext(cgf.getLLVMContext()) {
316 bool TestAndClearIgnoreResultAssign() {
317 bool I = IgnoreResultAssign;
318 IgnoreResultAssign =
false;
322 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
323 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
329 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
330 const BinOpInfo &Info);
332 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
336 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
337 const AlignValueAttr *AVAttr =
nullptr;
338 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
339 const ValueDecl *VD = DRE->getDecl();
342 if (
const auto *TTy =
344 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
354 AVAttr = VD->
getAttr<AlignValueAttr>();
359 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
360 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
373 Value *EmitLoadOfLValue(
const Expr *E) {
380 EmitLValueAlignmentAssumption(E,
V);
386 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
390 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
391 Value *Src, QualType SrcType, QualType DstType,
392 llvm::Type *DstTy, SourceLocation Loc);
397 enum ImplicitConversionCheckKind :
unsigned char {
398 ICCK_IntegerTruncation = 0,
399 ICCK_UnsignedIntegerTruncation = 1,
400 ICCK_SignedIntegerTruncation = 2,
401 ICCK_IntegerSignChange = 3,
402 ICCK_SignedIntegerTruncationOrSignChange = 4,
407 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
408 QualType DstType, SourceLocation Loc,
409 bool OBTrapInvolved =
false);
414 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
415 QualType DstType, SourceLocation Loc,
416 bool OBTrapInvolved =
false);
420 struct ScalarConversionOpts {
421 bool TreatBooleanAsSigned;
422 bool EmitImplicitIntegerTruncationChecks;
423 bool EmitImplicitIntegerSignChangeChecks;
425 bool PatternExcluded;
427 ScalarConversionOpts()
428 : TreatBooleanAsSigned(
false),
429 EmitImplicitIntegerTruncationChecks(
false),
430 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
432 ScalarConversionOpts(clang::SanitizerSet SanOpts)
433 : TreatBooleanAsSigned(
false),
434 EmitImplicitIntegerTruncationChecks(
435 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
436 EmitImplicitIntegerSignChangeChecks(
437 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
438 PatternExcluded(
false) {}
440 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
441 llvm::Type *SrcTy, llvm::Type *DstTy,
442 ScalarConversionOpts Opts);
444 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
446 ScalarConversionOpts Opts = ScalarConversionOpts());
450 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
456 QualType SrcTy, QualType DstTy,
460 Value *EmitNullValue(QualType Ty);
465 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
466 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
470 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
473 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
480 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
481 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
487 ZI->eraseFromParent();
492 return Builder.CreateIsNotNull(
V,
"tobool");
499 Value *Visit(Expr *E) {
500 ApplyDebugLocation DL(CGF, E);
501 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
504 Value *VisitStmt(Stmt *S) {
506 llvm_unreachable(
"Stmt can't have complex result type!");
508 Value *VisitExpr(Expr *S);
510 Value *VisitConstantExpr(ConstantExpr *E) {
516 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
531 Value *VisitParenExpr(ParenExpr *PE) {
534 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
537 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
538 return Visit(
GE->getResultExpr());
540 Value *VisitCoawaitExpr(CoawaitExpr *S) {
543 Value *VisitCoyieldExpr(CoyieldExpr *S) {
546 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
551 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
552 return Builder.getInt(E->
getValue());
554 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
555 return Builder.getInt(E->
getValue());
557 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
558 return llvm::ConstantFP::get(VMContext, E->
getValue());
560 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
563 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
566 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
567 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
569 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
570 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
572 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
576 return EmitNullValue(E->
getType());
578 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
579 return EmitNullValue(E->
getType());
581 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
582 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
583 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
585 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
588 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
592 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
596 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
597 Value *VisitEmbedExpr(EmbedExpr *E);
599 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
608 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
609 llvm_unreachable(
"Codegen for this isn't defined/implemented");
613 Value *VisitDeclRefExpr(DeclRefExpr *E) {
616 return EmitLoadOfLValue(E);
619 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
622 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
625 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
626 return EmitLoadOfLValue(E);
628 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
631 return EmitLoadOfLValue(E);
635 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
641 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
647 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
652 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
653 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
654 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
655 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
656 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
657 Value *VisitMemberExpr(MemberExpr *E);
658 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
659 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
660 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
666 return EmitLoadOfLValue(E);
669 Value *VisitInitListExpr(InitListExpr *E);
671 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
673 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
677 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
678 return EmitNullValue(E->
getType());
680 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
682 return VisitCastExpr(E);
686 Value *VisitCallExpr(
const CallExpr *E) {
688 return EmitLoadOfLValue(E);
690 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
694 EmitLValueAlignmentAssumption(E,
V);
698 Value *VisitStmtExpr(
const StmtExpr *E);
701 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
703 return EmitScalarPrePostIncDec(E, LV,
false,
false);
705 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
707 return EmitScalarPrePostIncDec(E, LV,
true,
false);
709 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
711 return EmitScalarPrePostIncDec(E, LV,
false,
true);
713 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
715 return EmitScalarPrePostIncDec(E, LV,
true,
true);
718 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
722 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
723 bool isInc,
bool isPre);
726 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
730 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
732 Value *VisitUnaryDeref(
const UnaryOperator *E) {
735 return EmitLoadOfLValue(E);
738 Value *VisitUnaryPlus(
const UnaryOperator *E,
739 QualType PromotionType = QualType());
740 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
741 Value *VisitUnaryMinus(
const UnaryOperator *E,
742 QualType PromotionType = QualType());
743 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
745 Value *VisitUnaryNot (
const UnaryOperator *E);
746 Value *VisitUnaryLNot (
const UnaryOperator *E);
747 Value *VisitUnaryReal(
const UnaryOperator *E,
748 QualType PromotionType = QualType());
749 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
750 Value *VisitUnaryImag(
const UnaryOperator *E,
751 QualType PromotionType = QualType());
752 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
753 Value *VisitUnaryExtension(
const UnaryOperator *E) {
758 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
759 return EmitLoadOfLValue(E);
761 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
769 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
770 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
773 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
774 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
777 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
781 Value *VisitExprWithCleanups(ExprWithCleanups *E);
782 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
785 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
790 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
792 return llvm::ConstantInt::get(ConvertType(E->
getType()),
796 return llvm::ConstantInt::get(ConvertType(E->
getType()),
800 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
808 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
809 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
812 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
813 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
816 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
826 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
827 return EmitNullValue(E->
getType());
830 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
835 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
836 return Builder.getInt1(E->
getValue());
840 Value *EmitMul(
const BinOpInfo &Ops) {
841 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
842 Ops.Ty->isUnsignedIntegerType()) {
843 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
845 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
846 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
847 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
848 case LangOptions::OB_Wrap:
849 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
850 case LangOptions::OB_SignedAndDefined:
852 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
854 case LangOptions::OB_Unset:
856 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
857 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
859 case LangOptions::OB_Trap:
860 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
861 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
862 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
863 return EmitOverflowCheckedBinOp(Ops);
867 if (Ops.Ty->isConstantMatrixType()) {
868 llvm::MatrixBuilder MB(Builder);
872 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
873 BO->getLHS()->getType().getCanonicalType());
874 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
875 BO->getRHS()->getType().getCanonicalType());
876 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
877 if (LHSMatTy && RHSMatTy)
878 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
879 LHSMatTy->getNumColumns(),
880 RHSMatTy->getNumColumns());
881 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
884 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
886 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
887 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
889 if (Ops.isFixedPointOp())
890 return EmitFixedPointBinOp(Ops);
891 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
895 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
898 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
899 llvm::Value *
Zero,
bool isDiv);
901 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
907 Value *EmitDiv(
const BinOpInfo &Ops);
908 Value *EmitRem(
const BinOpInfo &Ops);
909 Value *EmitAdd(
const BinOpInfo &Ops);
910 Value *EmitSub(
const BinOpInfo &Ops);
911 Value *EmitShl(
const BinOpInfo &Ops);
912 Value *EmitShr(
const BinOpInfo &Ops);
913 Value *EmitAnd(
const BinOpInfo &Ops) {
914 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
916 Value *EmitXor(
const BinOpInfo &Ops) {
917 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
919 Value *EmitOr (
const BinOpInfo &Ops) {
920 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
924 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
926 BinOpInfo EmitBinOps(
const BinaryOperator *E,
927 QualType PromotionTy = QualType());
929 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
930 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
931 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
933 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
934 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
937 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
938 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
940 QualType getPromotionType(QualType Ty) {
942 if (
auto *CT = Ty->
getAs<ComplexType>()) {
943 QualType ElementType = CT->getElementType();
944 if (ElementType.UseExcessPrecision(Ctx))
949 if (
auto *VT = Ty->
getAs<VectorType>()) {
950 unsigned NumElements = VT->getNumElements();
960#define HANDLEBINOP(OP) \
961 Value *VisitBin##OP(const BinaryOperator *E) { \
962 QualType promotionTy = getPromotionType(E->getType()); \
963 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
964 if (result && !promotionTy.isNull()) \
965 result = EmitUnPromotedValue(result, E->getType()); \
968 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
969 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
970 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
986 llvm::CmpInst::Predicate SICmpOpc,
987 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
988#define VISITCOMP(CODE, UI, SI, FP, SIG) \
989 Value *VisitBin##CODE(const BinaryOperator *E) { \
990 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
991 llvm::FCmpInst::FP, SIG); }
992 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
1006 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
1007 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1009 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1014 Value *VisitBlockExpr(
const BlockExpr *BE);
1015 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1016 Value *VisitChooseExpr(ChooseExpr *CE);
1017 Value *VisitVAArgExpr(VAArgExpr *VE);
1018 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1021 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1024 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1027 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1030 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1031 Value *VisitAtomicExpr(AtomicExpr *AE);
1032 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1045 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1048 return EmitFloatToBoolConversion(Src);
1050 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1054 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1058 "Unknown scalar type to convert");
1061 return EmitIntToBoolConversion(Src);
1064 return EmitPointerToBoolConversion(Src, SrcType);
1067void ScalarExprEmitter::EmitFloatConversionCheck(
1068 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1069 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1070 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1074 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1075 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1076 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1077 using llvm::APFloat;
1080 llvm::Value *Check =
nullptr;
1081 const llvm::fltSemantics &SrcSema =
1091 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1092 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1093 APFloat::opOverflow)
1096 MinSrc = APFloat::getInf(SrcSema,
true);
1100 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1103 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1104 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1105 APFloat::opOverflow)
1108 MaxSrc = APFloat::getInf(SrcSema,
false);
1112 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1117 const llvm::fltSemantics &Sema =
1120 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1121 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1125 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1127 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1128 Check = Builder.CreateAnd(GE, LE);
1133 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1139static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1140 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1143 llvm::Type *SrcTy = Src->
getType();
1144 llvm::Type *DstTy = Dst->
getType();
1149 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1151 "non-integer llvm type");
1158 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1160 if (!SrcSigned && !DstSigned) {
1161 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1162 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1164 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1165 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1168 llvm::Value *Check =
nullptr;
1170 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1172 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1174 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1182void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1183 Value *Dst, QualType DstType,
1185 bool OBTrapInvolved) {
1186 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1196 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1197 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1199 if (SrcBits <= DstBits)
1202 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1209 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1210 (!SrcSigned && DstSigned))
1213 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1214 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1217 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1222 SanitizerDebugLocation SanScope(
1224 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1225 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1241 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1249 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1250 if (OBT->isWrapKind())
1253 if (ignoredBySanitizer && !OBTrapInvolved)
1256 llvm::Constant *StaticArgs[] = {
1259 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1260 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1262 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1269 llvm::Type *VTy =
V->getType();
1272 return llvm::ConstantInt::getFalse(VTy->getContext());
1274 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1275 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1276 llvm::Twine(Name) +
"." +
V->getName() +
1277 ".negativitycheck");
1282static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1283 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1286 llvm::Type *SrcTy = Src->
getType();
1287 llvm::Type *DstTy = Dst->
getType();
1290 "non-integer llvm type");
1296 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1297 unsigned DstBits = DstTy->getScalarSizeInBits();
1301 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1302 "either the widths should be different, or the signednesses.");
1305 llvm::Value *SrcIsNegative =
1308 llvm::Value *DstIsNegative =
1314 llvm::Value *Check =
nullptr;
1315 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1317 return std::make_pair(
1318 ScalarExprEmitter::ICCK_IntegerSignChange,
1319 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1322void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1323 Value *Dst, QualType DstType,
1325 bool OBTrapInvolved) {
1326 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1330 llvm::Type *SrcTy = Src->
getType();
1331 llvm::Type *DstTy = Dst->
getType();
1341 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1342 unsigned DstBits = DstTy->getScalarSizeInBits();
1349 if (SrcSigned == DstSigned && SrcBits == DstBits)
1353 if (!SrcSigned && !DstSigned)
1358 if ((DstBits > SrcBits) && DstSigned)
1360 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1361 (SrcBits > DstBits) && SrcSigned) {
1370 if (!OBTrapInvolved) {
1373 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1377 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1382 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1383 SanitizerDebugLocation SanScope(
1385 {SanitizerKind::SO_ImplicitIntegerSignChange,
1386 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1387 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1390 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1391 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1395 ImplicitConversionCheckKind CheckKind;
1396 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1403 CheckKind = Check.first;
1404 Checks.emplace_back(Check.second);
1406 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1407 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1413 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1414 Checks.emplace_back(Check.second);
1418 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1419 if (OBTrapInvolved) {
1420 llvm::Value *Combined = Check.second.first;
1421 for (
const auto &
C : Checks)
1422 Combined = Builder.CreateAnd(Combined,
C.first);
1428 llvm::Constant *StaticArgs[] = {
1431 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1432 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1434 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1439static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1440 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1446 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1447 if (!SrcSigned && !DstSigned)
1448 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1450 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1452 llvm::Value *Check =
nullptr;
1454 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1456 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1459 return std::make_pair(
1461 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1466static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1467 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1471 llvm::Value *SrcIsNegative =
1474 llvm::Value *DstIsNegative =
1480 llvm::Value *Check =
nullptr;
1482 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1484 return std::make_pair(
1485 ScalarExprEmitter::ICCK_IntegerSignChange,
1486 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1494 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1512 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1513 unsigned DstBits = Info.
Size;
1518 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1520 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1522 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1523 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1527 bool EmitTruncation = DstBits < SrcBits;
1531 bool EmitTruncationFromUnsignedToSigned =
1532 EmitTruncation && DstSigned && !SrcSigned;
1534 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1535 bool BothUnsigned = !SrcSigned && !DstSigned;
1536 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1543 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1548 else if (EmitSignChange) {
1549 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1550 "either the widths should be different, or the signednesses.");
1556 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1557 if (EmitTruncationFromUnsignedToSigned)
1558 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1560 llvm::Constant *StaticArgs[] = {
1563 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1564 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1566 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1570 QualType DstType, llvm::Type *SrcTy,
1572 ScalarConversionOpts Opts) {
1574 llvm::Type *SrcElementTy;
1575 llvm::Type *DstElementTy;
1585 "cannot cast between matrix and non-matrix types");
1586 SrcElementTy = SrcTy;
1587 DstElementTy = DstTy;
1588 SrcElementType = SrcType;
1589 DstElementType = DstType;
1594 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1599 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1601 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1602 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1606 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1613 llvm::Intrinsic::ID IID =
1614 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1615 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1619 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1620 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1623 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1624 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1625 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1627 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1628 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1629 return Builder.CreateFPExt(Src, DstTy,
"conv");
1634Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1637 ScalarConversionOpts Opts) {
1652 return Builder.CreateIsNotNull(Src,
"tobool");
1655 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1658 "Unhandled scalar conversion from a fixed point type to another type.");
1662 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1665 "Unhandled scalar conversion to a fixed point type from another type.");
1668 QualType NoncanonicalSrcType = SrcType;
1669 QualType NoncanonicalDstType = DstType;
1673 if (SrcType == DstType)
return Src;
1677 llvm::Value *OrigSrc = Src;
1678 QualType OrigSrcType = SrcType;
1679 llvm::Type *SrcTy = Src->
getType();
1683 return EmitConversionToBool(Src, SrcType);
1685 llvm::Type *DstTy = ConvertType(DstType);
1694 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1695 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1696 bool OBTrapInvolved =
1697 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1698 bool OBWrapInvolved =
1699 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1704 if (DstTy->isFloatingPointTy())
1705 return Builder.CreateFPExt(Src, DstTy,
"conv");
1709 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1715 if (SrcTy == DstTy) {
1716 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1717 (OBTrapInvolved && !OBWrapInvolved))
1718 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1719 NoncanonicalDstType, Loc, OBTrapInvolved);
1727 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1732 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1737 llvm::Value* IntResult =
1738 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1740 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1746 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1753 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1755 "Splatted expr doesn't match with vector element type?");
1759 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1763 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1767 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1768 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1769 if (SrcSize == DstSize)
1770 return Builder.CreateBitCast(Src, DstTy,
"conv");
1783 assert(((SrcElementTy->isIntegerTy() &&
1784 DstElementTy->isIntegerTy()) ||
1785 (SrcElementTy->isFloatingPointTy() &&
1786 DstElementTy->isFloatingPointTy())) &&
1787 "unexpected conversion between a floating-point vector and an "
1791 if (SrcElementTy->isIntegerTy())
1792 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1795 if (SrcSize > DstSize)
1796 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1799 return Builder.CreateFPExt(Src, DstTy,
"conv");
1803 Value *Res =
nullptr;
1804 llvm::Type *ResTy = DstTy;
1811 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1813 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1821 if (SrcTy->isFloatingPointTy())
1822 return Builder.CreateFPTrunc(Src, CGF.
CGM.
HalfTy,
"conv");
1827 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1829 if (DstTy != ResTy) {
1830 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1833 assert(ResTy->isIntegerTy(16) &&
1834 "Only half FP requires extra conversion");
1835 Res = Builder.CreateBitCast(Res, ResTy);
1839 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1840 !OBWrapInvolved && !Opts.PatternExcluded)
1841 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1842 NoncanonicalDstType, Loc, OBTrapInvolved);
1844 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1845 (OBTrapInvolved && !OBWrapInvolved))
1846 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1847 NoncanonicalDstType, Loc, OBTrapInvolved);
1852Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1854 SourceLocation Loc) {
1855 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1858 Result = FPBuilder.CreateFloatingToFixed(Src,
1861 Result = FPBuilder.CreateFixedToFloating(Src,
1863 ConvertType(DstTy));
1869 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1870 DstFPSema.getWidth(),
1871 DstFPSema.isSigned());
1873 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1876 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1883Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1885 SourceLocation Loc) {
1887 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1892 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1893 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1894 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1901 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1904Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1912void ScalarExprEmitter::EmitBinOpCheck(
1913 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1914 const BinOpInfo &Info) {
1917 SmallVector<llvm::Constant *, 4> StaticData;
1918 SmallVector<llvm::Value *, 2> DynamicData;
1926 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1927 if (UO && UO->
getOpcode() == UO_Minus) {
1928 Check = SanitizerHandler::NegateOverflow;
1930 DynamicData.push_back(Info.RHS);
1934 Check = SanitizerHandler::ShiftOutOfBounds;
1936 StaticData.push_back(
1938 StaticData.push_back(
1940 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1942 Check = SanitizerHandler::DivremOverflow;
1946 int ArithOverflowKind = 0;
1949 Check = SanitizerHandler::AddOverflow;
1950 ArithOverflowKind = diag::UBSanArithKind::Add;
1954 Check = SanitizerHandler::SubOverflow;
1955 ArithOverflowKind = diag::UBSanArithKind::Sub;
1959 Check = SanitizerHandler::MulOverflow;
1960 ArithOverflowKind = diag::UBSanArithKind::Mul;
1964 llvm_unreachable(
"unexpected opcode for bin op check");
1968 SanitizerKind::UnsignedIntegerOverflow) ||
1970 SanitizerKind::SignedIntegerOverflow)) {
1974 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1978 DynamicData.push_back(Info.LHS);
1979 DynamicData.push_back(Info.RHS);
1982 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1989Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1997ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1999 unsigned AddrSpace =
2001 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2005 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2009Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2011 auto It = E->
begin();
2012 return Builder.getInt((*It)->getValue());
2015Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2023 unsigned LHSElts = LTy->getNumElements();
2031 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2032 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2040 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2041 MTy->getNumElements());
2042 Value* NewV = llvm::PoisonValue::get(RTy);
2043 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2044 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2045 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2047 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2048 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2056 SmallVector<int, 32> Indices;
2060 if (Idx.isSigned() && Idx.isAllOnes())
2061 Indices.push_back(-1);
2063 Indices.push_back(Idx.getZExtValue());
2066 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2069Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2077 if (SrcType == DstType)
return Src;
2080 "ConvertVector source type must be a vector");
2082 "ConvertVector destination type must be a vector");
2084 llvm::Type *SrcTy = Src->
getType();
2085 llvm::Type *DstTy = ConvertType(DstType);
2091 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2092 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2094 assert(SrcTy->isVectorTy() &&
2095 "ConvertVector source IR type must be a vector");
2096 assert(DstTy->isVectorTy() &&
2097 "ConvertVector destination IR type must be a vector");
2102 if (DstEltType->isBooleanType()) {
2103 assert((SrcEltTy->isFloatingPointTy() ||
2106 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2107 if (SrcEltTy->isFloatingPointTy()) {
2108 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2109 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2111 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2116 Value *Res =
nullptr;
2121 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2123 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2125 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2127 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2130 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2131 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2132 if (DstEltType->isSignedIntegerOrEnumerationType())
2133 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2135 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2137 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2138 "Unknown real conversion");
2139 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2140 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2141 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2143 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2149Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2158 return Builder.getInt(
Value);
2162 llvm::Value *
Result = EmitLoadOfLValue(E);
2168 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2169 if (llvm::GetElementPtrInst *GEP =
2170 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2171 if (llvm::Instruction *
Pointer =
2172 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2184Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2185 TestAndClearIgnoreResultAssign();
2193 return EmitLoadOfLValue(E);
2201 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2204 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2208 Ret = Builder.CreateInsertElement(
2209 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2215Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2216 MatrixSingleSubscriptExpr *E) {
2217 TestAndClearIgnoreResultAssign();
2220 unsigned NumRows = MatrixTy->getNumRows();
2221 unsigned NumColumns = MatrixTy->getNumColumns();
2225 llvm::MatrixBuilder MB(Builder);
2229 MB.CreateIndexAssumption(RowIdx, NumRows);
2232 llvm::Type *ElemTy = CGF.
ConvertType(MatrixTy->getElementType());
2233 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2234 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2236 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2237 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2238 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2239 false,
"matrix_row_idx");
2241 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2242 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2243 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2249Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2250 TestAndClearIgnoreResultAssign();
2258 llvm::MatrixBuilder MB(Builder);
2260 unsigned NumCols = MatrixTy->getNumColumns();
2261 unsigned NumRows = MatrixTy->getNumRows();
2262 bool IsMatrixRowMajor =
2266 MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2269 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2274 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2279 int MV = SVI->getMaskValue(Idx);
2286 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2287 "Index operand too large for shufflevector mask!");
2288 return C->getZExtValue();
2291Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2292 bool Ignore = TestAndClearIgnoreResultAssign();
2295 assert((Ignore ==
false ||
2297 "init list ignored");
2314 llvm::VectorType *VType =
2315 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2318 if (NumInitElements == 0) {
2320 return EmitNullValue(E->
getType());
2327 if (NumInitElements == 0) {
2329 return EmitNullValue(E->
getType());
2332 if (NumInitElements == 1) {
2333 Expr *InitVector = E->
getInit(0);
2338 return Visit(InitVector);
2341 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2348 const ConstantMatrixType *ColMajorMT =
2356 unsigned CurIdx = 0;
2357 bool VIsPoisonShuffle =
false;
2358 llvm::Value *
V = llvm::PoisonValue::get(VType);
2359 for (
unsigned i = 0; i != NumInitElements; ++i) {
2362 SmallVector<int, 16> Args;
2364 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2374 ->getNumElements() == ResElts) {
2376 Value *LHS =
nullptr, *RHS =
nullptr;
2381 Args.resize(ResElts, -1);
2383 LHS = EI->getVectorOperand();
2385 VIsPoisonShuffle =
true;
2386 }
else if (VIsPoisonShuffle) {
2389 for (
unsigned j = 0; j != CurIdx; ++j)
2391 Args.push_back(ResElts +
C->getZExtValue());
2392 Args.resize(ResElts, -1);
2395 RHS = EI->getVectorOperand();
2396 VIsPoisonShuffle =
false;
2398 if (!Args.empty()) {
2399 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2405 unsigned InsertIdx =
2409 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2411 VIsPoisonShuffle =
false;
2421 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2424 Value *SVOp = SVI->getOperand(0);
2427 if (OpTy->getNumElements() == ResElts) {
2428 for (
unsigned j = 0; j != CurIdx; ++j) {
2431 if (VIsPoisonShuffle) {
2437 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2439 Args.resize(ResElts, -1);
2441 if (VIsPoisonShuffle)
2451 for (
unsigned j = 0; j != InitElts; ++j)
2453 Args.resize(ResElts, -1);
2454 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2457 for (
unsigned j = 0; j != CurIdx; ++j)
2459 for (
unsigned j = 0; j != InitElts; ++j)
2460 Args.push_back(j + Offset);
2461 Args.resize(ResElts, -1);
2468 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2475 llvm::Type *EltTy = VType->getElementType();
2478 for (; CurIdx < ResElts; ++CurIdx) {
2479 unsigned InsertIdx =
2482 Value *Idx = Builder.getInt32(InsertIdx);
2483 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2484 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2497 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2501 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2504 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2523 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2527 if (
const auto *CE = dyn_cast<CastExpr>(E))
2528 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2529 CE->getCastKind() == CK_ArrayToPointerDecay)
2540 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2550 if (ICE->isGLValue())
2557template <
typename GetElementTy>
2560 unsigned NumSrcElements,
2563 assert(NumSrcElements >= VecTy->getNumElements() &&
2564 "Flattened type on RHS must have the same number or more elements "
2565 "than vector on LHS.");
2567 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; ++I) {
2568 auto [Element, ElementTy] = GetElement(I);
2570 VecTy->getElementType(), Loc);
2571 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2584 CGF, DestTy, LoadList.size(),
2586 RValue RVal = CGF.EmitLoadOfLValue(LoadList[I], Loc);
2587 assert(RVal.isScalar() &&
2588 "All flattened source values should be scalars.");
2589 return std::pair(RVal.getScalarVal(), LoadList[I].getType());
2594 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2595 "Flattened type on RHS must have the same number or more elements "
2596 "than vector on LHS.");
2598 llvm::Value *
V = llvm::PoisonValue::get(CGF.
ConvertType(DestTy));
2600 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2601 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2604 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2607 "All flattened source values should be scalars.");
2610 MatTy->getElementType(), Loc);
2611 unsigned MatrixIdx = MatTy->getColumnMajorFlattenedIndex(Row, Col);
2612 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2619 "Destination type must be a vector, matrix, or builtin type.");
2621 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2630 llvm::scope_exit RestoreCurCast(
2631 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2635 QualType DestTy = CE->
getType();
2637 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2641 bool Ignored = TestAndClearIgnoreResultAssign();
2647 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2648 case CK_BuiltinFnToFnPtr:
2649 llvm_unreachable(
"builtin functions are handled elsewhere");
2651 case CK_LValueBitCast:
2652 case CK_ObjCObjectLValueCast: {
2656 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2659 case CK_LValueToRValueBitCast: {
2665 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2668 case CK_CPointerToObjCPointerCast:
2669 case CK_BlockPointerToObjCPointerCast:
2670 case CK_AnyPointerToBlockPointerCast:
2672 Value *Src = Visit(E);
2673 llvm::Type *SrcTy = Src->
getType();
2674 llvm::Type *DstTy = ConvertType(DestTy);
2685 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2699 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2700 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2705 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2706 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2707 "Address-space cast must be used to convert address spaces");
2709 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2710 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2712 PT->getPointeeType(),
2723 const QualType SrcType = E->
getType();
2728 Src = Builder.CreateLaunderInvariantGroup(Src);
2733 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2737 if (!PointeeType.
isNull())
2746 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2747 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2750 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2751 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2752 ScalableDstTy = llvm::ScalableVectorType::get(
2753 FixedSrcTy->getElementType(),
2755 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2757 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2758 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2759 llvm::Value *
Result = Builder.CreateInsertVector(
2760 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2762 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2763 if (
Result->getType() != ScalableDstTy)
2765 if (
Result->getType() != DstTy)
2775 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2776 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2779 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2780 FixedDstTy->getElementType()->isIntegerTy(8)) {
2781 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2782 ScalableSrcTy = llvm::ScalableVectorType::get(
2783 ScalableSrcTy->getElementType(),
2785 ScalableSrcTy->getElementCount().getKnownMinValue()));
2786 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2787 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2791 ScalableSrcTy = llvm::ScalableVectorType::get(
2792 FixedDstTy->getElementType(),
2793 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2794 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2796 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2797 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2818 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2821 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2824 case CK_AddressSpaceConversion: {
2825 llvm::Type *DestLTy = ConvertType(DestTy);
2828 auto IsWasmFuncref = [](llvm::Type *
T) {
2829 auto *TET = dyn_cast<llvm::TargetExtType>(
T);
2830 return TET && TET->getName() ==
"wasm.funcref";
2832 bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->
getType()));
2833 bool DestIsFuncref = IsWasmFuncref(DestLTy);
2834 if (SrcIsFuncref && DestIsFuncref) {
2839 if (SrcIsFuncref && !DestIsFuncref) {
2843 llvm::Function *ToPtr =
2845 return CGF.
Builder.CreateCall(ToPtr, {Visit(E)});
2847 if (!SrcIsFuncref && DestIsFuncref) {
2850 Expr::EvalResult NullResult;
2855 return llvm::Constant::getNullValue(DestLTy);
2858 llvm::Function *ToFuncref =
2860 return CGF.
Builder.CreateCall(ToFuncref, {Visit(E)});
2864 Result.Val.isNullPointer()) {
2868 if (
Result.HasSideEffects)
2876 case CK_AtomicToNonAtomic:
2877 case CK_NonAtomicToAtomic:
2878 case CK_UserDefinedConversion:
2885 case CK_BaseToDerived: {
2887 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2901 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2909 case CK_UncheckedDerivedToBase:
2910 case CK_DerivedToBase: {
2923 case CK_ArrayToPointerDecay:
2926 case CK_FunctionToPointerDecay:
2927 return EmitLValue(E).getPointer(CGF);
2929 case CK_NullToPointer:
2930 if (MustVisitNullValue(E))
2936 case CK_NullToMemberPointer: {
2937 if (MustVisitNullValue(E))
2940 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2944 case CK_ReinterpretMemberPointer:
2945 case CK_BaseToDerivedMemberPointer:
2946 case CK_DerivedToBaseMemberPointer: {
2947 Value *Src = Visit(E);
2958 case CK_ARCProduceObject:
2960 case CK_ARCConsumeObject:
2962 case CK_ARCReclaimReturnedObject:
2964 case CK_ARCExtendBlockObject:
2967 case CK_CopyAndAutoreleaseBlockObject:
2970 case CK_FloatingRealToComplex:
2971 case CK_FloatingComplexCast:
2972 case CK_IntegralRealToComplex:
2973 case CK_IntegralComplexCast:
2974 case CK_IntegralComplexToFloatingComplex:
2975 case CK_FloatingComplexToIntegralComplex:
2976 case CK_ConstructorConversion:
2978 case CK_HLSLArrayRValue:
2979 llvm_unreachable(
"scalar cast to non-scalar value");
2981 case CK_LValueToRValue:
2983 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2986 case CK_IntegralToPointer: {
2987 Value *Src = Visit(E);
2991 auto DestLLVMTy = ConvertType(DestTy);
2994 llvm::Value* IntResult =
2995 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2997 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
3003 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
3009 case CK_PointerToIntegral: {
3010 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
3013 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3019 case CK_MatrixCast: {
3020 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3027 case CK_HLSLAggregateSplatCast:
3028 case CK_VectorSplat: {
3029 llvm::Type *DstTy = ConvertType(DestTy);
3030 Value *Elt = Visit(E);
3032 llvm::ElementCount NumElements =
3034 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3037 case CK_FixedPointCast:
3038 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3041 case CK_FixedPointToBoolean:
3043 "Expected src type to be fixed point type");
3044 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3045 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3048 case CK_FixedPointToIntegral:
3050 "Expected src type to be fixed point type");
3051 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3052 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3055 case CK_IntegralToFixedPoint:
3057 "Expected src type to be an integer");
3059 "Expected dest type to be fixed point type");
3060 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3063 case CK_IntegralCast: {
3065 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3066 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3070 ScalarConversionOpts Opts;
3071 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3072 if (!ICE->isPartOfExplicitCast())
3073 Opts = ScalarConversionOpts(CGF.
SanOpts);
3075 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3078 case CK_IntegralToFloating: {
3081 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3083 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3084 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3086 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3087 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3090 case CK_FloatingToIntegral: {
3093 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3095 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3096 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3098 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3099 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3102 case CK_FloatingCast: {
3105 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3106 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3107 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3108 SrcElTy->
castAs<BuiltinType>()->getKind())
3109 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3110 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3112 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3113 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3116 case CK_FixedPointToFloating:
3117 case CK_FloatingToFixedPoint: {
3118 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3119 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3122 case CK_BooleanToSignedIntegral: {
3123 ScalarConversionOpts Opts;
3124 Opts.TreatBooleanAsSigned =
true;
3125 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3128 case CK_IntegralToBoolean:
3129 return EmitIntToBoolConversion(Visit(E));
3130 case CK_PointerToBoolean:
3131 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3132 case CK_FloatingToBoolean: {
3133 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3134 return EmitFloatToBoolConversion(Visit(E));
3136 case CK_MemberPointerToBoolean: {
3137 llvm::Value *MemPtr = Visit(E);
3138 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3142 case CK_FloatingComplexToReal:
3143 case CK_IntegralComplexToReal:
3146 case CK_FloatingComplexToBoolean:
3147 case CK_IntegralComplexToBoolean: {
3151 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3155 case CK_ZeroToOCLOpaqueType: {
3158 "CK_ZeroToOCLEvent cast on non-event type");
3159 return llvm::Constant::getNullValue(ConvertType(DestTy));
3162 case CK_IntToOCLSampler:
3165 case CK_HLSLVectorTruncation: {
3167 "Destination type must be a vector or builtin type.");
3168 Value *Vec = Visit(E);
3169 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3170 SmallVector<int> Mask;
3171 unsigned NumElts = VecTy->getNumElements();
3172 for (
unsigned I = 0; I != NumElts; ++I)
3175 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3177 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3178 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3180 case CK_HLSLMatrixTruncation: {
3182 "Destination type must be a matrix or builtin type.");
3183 Value *Mat = Visit(E);
3184 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3185 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3186 unsigned NumCols = MatTy->getNumColumns();
3187 unsigned NumRows = MatTy->getNumRows();
3188 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3189 assert(SrcMatTy &&
"Source type must be a matrix type.");
3190 assert(NumRows <= SrcMatTy->getNumRows());
3191 assert(NumCols <= SrcMatTy->getNumColumns());
3193 for (
unsigned R = 0;
R < NumRows;
R++)
3194 for (
unsigned C = 0;
C < NumCols;
C++)
3195 Mask[MatTy->getColumnMajorFlattenedIndex(R,
C)] =
3196 SrcMatTy->getColumnMajorFlattenedIndex(R,
C);
3198 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3200 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3201 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3203 case CK_HLSLElementwiseCast: {
3207 if (
const auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>()) {
3209 "Matrix elementwise cast destination must be a vector");
3210 assert(RV.
isScalar() &&
"Matrix rvalue must have scalar representation");
3213 CGF, DestTy, SrcMatTy->getNumElementsFlattened(),
3215 unsigned Row = I / SrcMatTy->getNumColumns();
3216 unsigned Col = I % SrcMatTy->getNumColumns();
3217 unsigned Idx = SrcMatTy->getColumnMajorFlattenedIndex(Row, Col);
3219 Builder.CreateExtractElement(SrcVal, Idx,
"matrixext");
3220 return std::pair(Element, SrcMatTy->getElementType());
3241 llvm_unreachable(
"unknown scalar cast");
3244Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3245 CodeGenFunction::StmtExprEvaluation eval(CGF);
3254Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3255 CodeGenFunction::RunCleanupsScope Scope(CGF);
3259 Scope.ForceCleanup({&
V});
3268 llvm::Value *InVal,
bool IsInc,
3272 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3274 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3275 BinOp.FPFeatures = FPFeatures;
3280llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3281 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3284 llvm::Value *Amount =
3285 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3286 StringRef Name = IsInc ?
"inc" :
"dec";
3290 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3291 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3293 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3294 case LangOptions::OB_Wrap:
3295 return Builder.CreateAdd(InVal, Amount, Name);
3296 case LangOptions::OB_SignedAndDefined:
3298 return Builder.CreateAdd(InVal, Amount, Name);
3300 case LangOptions::OB_Unset:
3302 return Builder.CreateAdd(InVal, Amount, Name);
3304 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3305 : Builder.CreateAdd(InVal, Amount, Name);
3307 case LangOptions::OB_Trap:
3309 return Builder.CreateAdd(InVal, Amount, Name);
3312 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3313 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3314 : Builder.CreateAdd(InVal, Amount, Name);
3315 return EmitOverflowCheckedBinOp(Info);
3317 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3322class OMPLastprivateConditionalUpdateRAII {
3324 CodeGenFunction &CGF;
3325 const UnaryOperator *E;
3328 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3329 const UnaryOperator *E)
3331 ~OMPLastprivateConditionalUpdateRAII() {
3340ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3341 bool isInc,
bool isPre) {
3343 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3345 llvm::PHINode *atomicPHI =
nullptr;
3349 QualType SrcType = E->
getType();
3351 int amount = (isInc ? 1 : -1);
3352 bool isSubtraction = !isInc;
3354 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3355 type = atomicTy->getValueType();
3356 if (isInc &&
type->isBooleanType()) {
3359 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3360 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3361 return Builder.getTrue();
3365 return Builder.CreateAtomicRMW(
3366 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3367 llvm::AtomicOrdering::SequentiallyConsistent);
3372 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3373 !(
type->isUnsignedIntegerType() &&
3374 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3376 LangOptions::SOB_Trapping) {
3377 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3378 llvm::AtomicRMWInst::Sub;
3379 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3380 llvm::Instruction::Sub;
3382 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3384 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3385 llvm::AtomicOrdering::SequentiallyConsistent);
3386 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3390 if (
type->isFloatingType()) {
3391 llvm::Type *Ty = ConvertType(
type);
3392 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3393 llvm::AtomicRMWInst::BinOp aop =
3394 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3395 llvm::Instruction::BinaryOps op =
3396 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3397 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3398 llvm::AtomicRMWInst *old =
3400 llvm::AtomicOrdering::SequentiallyConsistent);
3402 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3405 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3408 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3411 Builder.CreateBr(opBB);
3412 Builder.SetInsertPoint(opBB);
3413 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3414 atomicPHI->addIncoming(value, startBB);
3417 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3428 if (isInc &&
type->isBooleanType()) {
3429 value = Builder.getTrue();
3432 }
else if (
type->isIntegerType()) {
3433 QualType promotedType;
3434 bool canPerformLossyDemotionCheck =
false;
3438 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3439 canPerformLossyDemotionCheck =
true;
3440 canPerformLossyDemotionCheck &=
3443 canPerformLossyDemotionCheck &=
3445 type, promotedType);
3446 assert((!canPerformLossyDemotionCheck ||
3447 type->isSignedIntegerOrEnumerationType() ||
3449 ConvertType(
type)->getScalarSizeInBits() ==
3450 ConvertType(promotedType)->getScalarSizeInBits()) &&
3451 "The following check expects that if we do promotion to different "
3452 "underlying canonical type, at least one of the types (either "
3453 "base or promoted) will be signed, or the bitwidths will match.");
3456 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3457 SanitizerKind::ImplicitBitfieldConversion) &&
3458 canPerformLossyDemotionCheck) {
3472 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3473 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3474 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3478 ScalarConversionOpts Opts;
3479 if (!LV.isBitField())
3480 Opts = ScalarConversionOpts(CGF.
SanOpts);
3481 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3483 SrcType = promotedType;
3487 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3493 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3494 type->isUnsignedIntegerType()) {
3495 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3500 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3501 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3505 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3506 QualType
type = ptr->getPointeeType();
3509 if (
const VariableArrayType *vla
3512 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3515 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3518 elemTy, value, numElts,
false, isSubtraction,
3522 }
else if (
type->isFunctionType()) {
3523 llvm::Value *amt = Builder.getInt32(amount);
3526 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3530 false, isSubtraction,
3535 llvm::Value *amt = Builder.getInt32(amount);
3538 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3541 elemTy, value, amt,
false, isSubtraction,
3546 }
else if (
type->isVectorType()) {
3547 if (
type->hasIntegerRepresentation()) {
3548 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3550 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3552 value = Builder.CreateFAdd(
3554 llvm::ConstantFP::get(value->getType(), amount),
3555 isInc ?
"inc" :
"dec");
3559 }
else if (
type->isRealFloatingType()) {
3562 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3566 value = Builder.CreateFPExt(value, CGF.
CGM.
FloatTy,
"incdec.conv");
3568 if (value->getType()->isFloatTy())
3569 amt = llvm::ConstantFP::get(VMContext,
3570 llvm::APFloat(
static_cast<float>(amount)));
3571 else if (value->getType()->isDoubleTy())
3572 amt = llvm::ConstantFP::get(VMContext,
3573 llvm::APFloat(
static_cast<double>(amount)));
3577 llvm::APFloat F(
static_cast<float>(amount));
3579 const llvm::fltSemantics *FS;
3582 if (value->getType()->isFP128Ty())
3584 else if (value->getType()->isHalfTy())
3586 else if (value->getType()->isBFloatTy())
3588 else if (value->getType()->isPPC_FP128Ty())
3592 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3593 amt = llvm::ConstantFP::get(VMContext, F);
3595 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3598 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3601 }
else if (
type->isFixedPointType()) {
3608 Info.Opcode = isInc ? BO_Add : BO_Sub;
3610 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3613 if (
type->isSignedFixedPointType()) {
3614 Info.Opcode = isInc ? BO_Sub : BO_Add;
3615 Info.RHS = Builder.CreateNeg(Info.RHS);
3620 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3622 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3623 value = EmitFixedPointBinOp(Info);
3627 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3630 if (!isInc) size = -size;
3631 llvm::Value *sizeValue =
3632 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3635 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3638 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3640 value = Builder.CreateBitCast(value, input->getType());
3644 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3649 llvm::Value *
success = Pair.second;
3650 atomicPHI->addIncoming(old, curBlock);
3651 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3652 Builder.SetInsertPoint(contBB);
3653 return isPre ? value : input;
3657 if (LV.isBitField()) {
3667 return isPre ? value : input;
3671Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3672 QualType PromotionType) {
3673 QualType promotionTy = PromotionType.
isNull()
3676 Value *result = VisitPlus(E, promotionTy);
3677 if (result && !promotionTy.
isNull())
3678 result = EmitUnPromotedValue(result, E->
getType());
3682Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3683 QualType PromotionType) {
3685 TestAndClearIgnoreResultAssign();
3686 if (!PromotionType.
isNull())
3691Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3692 QualType PromotionType) {
3693 QualType promotionTy = PromotionType.
isNull()
3696 Value *result = VisitMinus(E, promotionTy);
3697 if (result && !promotionTy.
isNull())
3698 result = EmitUnPromotedValue(result, E->
getType());
3702Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3703 QualType PromotionType) {
3704 TestAndClearIgnoreResultAssign();
3706 if (!PromotionType.
isNull())
3712 if (Op->
getType()->isFPOrFPVectorTy()) {
3713 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3714 return Builder.CreateFNeg(Op,
"fneg");
3720 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3722 BinOp.Opcode = BO_Sub;
3725 return EmitSub(BinOp);
3728Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3729 TestAndClearIgnoreResultAssign();
3731 return Builder.CreateNot(Op,
"not");
3734Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3738 VectorKind::Generic) {
3742 if (Oper->
getType()->isFPOrFPVectorTy()) {
3743 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3745 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3747 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3748 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3757 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3760 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3763Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3765 Expr::EvalResult EVResult;
3768 return Builder.getInt(
Value);
3773 llvm::Type* ResultType = ConvertType(E->
getType());
3774 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3776 for (
unsigned i = 0; i != n; ++i) {
3778 llvm::Value *Offset =
nullptr;
3785 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3792 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3796 Offset = Builder.CreateMul(Idx, ElemSize);
3801 FieldDecl *MemberDecl = ON.
getField();
3811 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3814 CurrentType = MemberDecl->
getType();
3819 llvm_unreachable(
"dependent __builtin_offsetof");
3836 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3848ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3849 const UnaryExprOrTypeTraitExpr *E) {
3852 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3853 if (
const VariableArrayType *VAT =
3858 bool EvaluateExtent =
true;
3859 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3861 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3863 if (EvaluateExtent) {
3874 if (Kind == UETT_CountOf)
3883 if (!eltSize.
isOne())
3886 return VlaSize.NumElts;
3889 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3895 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3896 }
else if (E->
getKind() == UETT_VectorElements) {
3898 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3906Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3907 QualType PromotionType) {
3908 QualType promotionTy = PromotionType.
isNull()
3911 Value *result = VisitReal(E, promotionTy);
3912 if (result && !promotionTy.
isNull())
3913 result = EmitUnPromotedValue(result, E->
getType());
3917Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3918 QualType PromotionType) {
3925 if (!PromotionType.
isNull()) {
3927 Op, IgnoreResultAssign,
true);
3942 if (!PromotionType.
isNull())
3947Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3948 QualType PromotionType) {
3949 QualType promotionTy = PromotionType.
isNull()
3952 Value *result = VisitImag(E, promotionTy);
3953 if (result && !promotionTy.
isNull())
3954 result = EmitUnPromotedValue(result, E->
getType());
3958Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3959 QualType PromotionType) {
3966 if (!PromotionType.
isNull()) {
3968 Op,
true, IgnoreResultAssign);
3972 return result.second
3988 else if (!PromotionType.
isNull())
3992 if (!PromotionType.
isNull())
3993 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3994 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
4001Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
4002 QualType PromotionType) {
4003 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
4006Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
4007 QualType ExprType) {
4008 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
4011Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
4013 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
4015#define HANDLE_BINOP(OP) \
4017 return Emit##OP(EmitBinOps(BO, PromotionType));
4026 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4029 return VisitImag(UO, PromotionType);
4031 return VisitReal(UO, PromotionType);
4033 return VisitMinus(UO, PromotionType);
4035 return VisitPlus(UO, PromotionType);
4040 auto result = Visit(
const_cast<Expr *
>(E));
4042 if (!PromotionType.
isNull())
4043 return EmitPromotedValue(result, PromotionType);
4045 return EmitUnPromotedValue(result, E->
getType());
4050BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4051 QualType PromotionType) {
4052 TestAndClearIgnoreResultAssign();
4056 if (!PromotionType.
isNull())
4057 Result.Ty = PromotionType;
4066LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4067 const CompoundAssignOperator *E,
4068 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4079 QualType PromotionTypeCR;
4081 if (PromotionTypeCR.
isNull())
4084 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4085 if (!PromotionTypeRHS.
isNull())
4088 OpInfo.RHS = Visit(E->
getRHS());
4089 OpInfo.Ty = PromotionTypeCR;
4096 llvm::PHINode *atomicPHI =
nullptr;
4097 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4099 QualType AtomicValueTy = atomicTy->getValueType();
4108 bool CanEmitAtomicRMW;
4110 llvm::Type *IRTy = CGF.
ConvertType(AtomicValueTy);
4114 !OpInfo.FPFeatures.isFPConstrained() &&
4116 llvm::isPowerOf2_64(StoreBits);
4122 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4124 LangOptions::SOB_Trapping;
4126 if (CanEmitAtomicRMW) {
4127 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4128 llvm::Instruction::BinaryOps Op;
4130 switch (OpInfo.Opcode) {
4132 AtomicOp = llvm::AtomicRMWInst::FAdd;
4133 Op = llvm::Instruction::FAdd;
4136 AtomicOp = llvm::AtomicRMWInst::FSub;
4137 Op = llvm::Instruction::FSub;
4143 switch (OpInfo.Opcode) {
4145 case BO_MulAssign:
case BO_DivAssign:
4151 AtomicOp = llvm::AtomicRMWInst::Add;
4152 Op = llvm::Instruction::Add;
4155 AtomicOp = llvm::AtomicRMWInst::Sub;
4156 Op = llvm::Instruction::Sub;
4159 AtomicOp = llvm::AtomicRMWInst::And;
4160 Op = llvm::Instruction::And;
4163 AtomicOp = llvm::AtomicRMWInst::Xor;
4164 Op = llvm::Instruction::Xor;
4167 AtomicOp = llvm::AtomicRMWInst::Or;
4168 Op = llvm::Instruction::Or;
4171 llvm_unreachable(
"Invalid compound assignment type");
4174 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4176 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4180 llvm::AtomicRMWInst *OldVal =
4185 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4191 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4193 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4194 OpInfo.LHS = CGF.
EmitToMemory(OpInfo.LHS, AtomicValueTy);
4195 Builder.CreateBr(opBB);
4196 Builder.SetInsertPoint(opBB);
4197 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4198 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4199 OpInfo.LHS = atomicPHI;
4202 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4204 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4206 if (!PromotionTypeLHS.
isNull())
4207 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4210 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4221 if (LHSLV.isBitField()) {
4223 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4224 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4226 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4227 Loc, ScalarConversionOpts(CGF.
SanOpts));
4229 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4230 ScalarConversionOpts(CGF.
SanOpts));
4234 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4238 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4239 llvm::Value *
success = Pair.second;
4240 atomicPHI->addIncoming(old, curBlock);
4241 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4242 Builder.SetInsertPoint(contBB);
4250 if (LHSLV.isBitField()) {
4266Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4267 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4268 bool Ignore = TestAndClearIgnoreResultAssign();
4269 Value *RHS =
nullptr;
4270 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4281 if (!LHS.isVolatileQualified())
4285 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4288void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4289 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4290 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4293 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4294 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4295 SanitizerKind::SO_IntegerDivideByZero));
4299 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4300 Ops.Ty->hasSignedIntegerRepresentation() &&
4302 Ops.mayHaveIntegerOverflow() &&
4304 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4307 llvm::Value *IntMin =
4308 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4309 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4311 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4312 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4313 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4315 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4318 if (Checks.size() > 0)
4319 EmitBinOpCheck(Checks, Ops);
4322Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4324 SanitizerDebugLocation SanScope(&CGF,
4325 {SanitizerKind::SO_IntegerDivideByZero,
4326 SanitizerKind::SO_SignedIntegerOverflow,
4327 SanitizerKind::SO_FloatDivideByZero},
4328 SanitizerHandler::DivremOverflow);
4329 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4330 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4331 Ops.Ty->isIntegerType() &&
4332 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4333 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4334 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4335 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4336 Ops.Ty->isRealFloatingType() &&
4337 Ops.mayHaveFloatDivisionByZero()) {
4338 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4339 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4341 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4345 if (Ops.Ty->isConstantMatrixType()) {
4346 llvm::MatrixBuilder MB(Builder);
4353 "first operand must be a matrix");
4355 "second operand must be an arithmetic type");
4356 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4357 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4358 Ops.Ty->hasUnsignedIntegerRepresentation());
4361 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4363 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4364 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4368 else if (Ops.isFixedPointOp())
4369 return EmitFixedPointBinOp(Ops);
4370 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4371 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4373 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4376Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4378 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4379 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4380 Ops.Ty->isIntegerType() &&
4381 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4382 SanitizerDebugLocation SanScope(&CGF,
4383 {SanitizerKind::SO_IntegerDivideByZero,
4384 SanitizerKind::SO_SignedIntegerOverflow},
4385 SanitizerHandler::DivremOverflow);
4386 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4387 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4390 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4391 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4393 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4394 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4396 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4399Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4404 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4405 switch (Ops.Opcode) {
4409 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4410 llvm::Intrinsic::uadd_with_overflow;
4411 OverflowKind = SanitizerHandler::AddOverflow;
4416 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4417 llvm::Intrinsic::usub_with_overflow;
4418 OverflowKind = SanitizerHandler::SubOverflow;
4423 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4424 llvm::Intrinsic::umul_with_overflow;
4425 OverflowKind = SanitizerHandler::MulOverflow;
4428 llvm_unreachable(
"Unsupported operation for overflow detection");
4434 SanitizerDebugLocation SanScope(&CGF,
4435 {SanitizerKind::SO_SignedIntegerOverflow,
4436 SanitizerKind::SO_UnsignedIntegerOverflow},
4442 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4443 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4444 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4447 const std::string *handlerName =
4449 if (handlerName->empty()) {
4455 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4456 llvm::Value *NotOf = Builder.CreateNot(overflow);
4458 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4461 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4464 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4465 llvm::Value *NotOf = Builder.CreateNot(overflow);
4467 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4470 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4475 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4476 llvm::BasicBlock *continueBB =
4480 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4484 Builder.SetInsertPoint(overflowBB);
4490 llvm::FunctionCallee handler =
4495 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4496 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4500 llvm::Value *handlerArgs[] = {
4503 Builder.getInt8(OpID),
4506 llvm::Value *handlerResult =
4510 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4511 Builder.CreateBr(continueBB);
4513 Builder.SetInsertPoint(continueBB);
4514 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4515 phi->addIncoming(result, initialBB);
4516 phi->addIncoming(handlerResult, overflowBB);
4525 bool isSubtraction) {
4530 Value *pointer = op.LHS;
4531 Expr *pointerOperand =
expr->getLHS();
4533 Expr *indexOperand =
expr->getRHS();
4536 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4537 std::swap(pointer,
index);
4538 std::swap(pointerOperand, indexOperand);
4542 index, isSubtraction);
4548 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4552 auto &DL =
CGM.getDataLayout();
4575 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4577 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4578 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4579 PtrTy->getPointerAddressSpace()))
4582 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4583 auto CheckHandler = SanitizerHandler::PointerOverflow;
4585 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4587 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4588 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4590 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4591 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4596 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4607 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4617 llvm::Value *objectSize =
4623 return Builder.CreateBitCast(result, pointer->getType());
4628 getContext().getAsVariableArrayType(elementType)) {
4630 llvm::Value *numElements =
getVLASize(vla).NumElts;
4639 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4659 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4672 bool negMul,
bool negAdd) {
4673 Value *MulOp0 = MulOp->getOperand(0);
4674 Value *MulOp1 = MulOp->getOperand(1);
4676 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4678 Addend = Builder.CreateFNeg(Addend,
"neg");
4680 Value *FMulAdd =
nullptr;
4681 if (Builder.getIsFPConstrained()) {
4683 "Only constrained operation should be created when Builder is in FP "
4684 "constrained mode");
4685 FMulAdd = Builder.CreateConstrainedFPCall(
4686 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4688 {MulOp0, MulOp1, Addend});
4690 FMulAdd = Builder.CreateCall(
4692 {MulOp0, MulOp1, Addend});
4694 MulOp->eraseFromParent();
4709 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4710 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4711 "Only fadd/fsub can be the root of an fmuladd.");
4714 if (!op.FPFeatures.allowFPContractWithinStatement())
4717 Value *LHS = op.LHS;
4718 Value *RHS = op.RHS;
4722 bool NegLHS =
false;
4723 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4724 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4725 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4726 LHS = LHSUnOp->getOperand(0);
4731 bool NegRHS =
false;
4732 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4733 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4734 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4735 RHS = RHSUnOp->getOperand(0);
4743 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4744 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4745 (LHSBinOp->use_empty() || NegLHS)) {
4749 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4752 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4753 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4754 (RHSBinOp->use_empty() || NegRHS)) {
4758 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4762 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4763 if (LHSBinOp->getIntrinsicID() ==
4764 llvm::Intrinsic::experimental_constrained_fmul &&
4765 (LHSBinOp->use_empty() || NegLHS)) {
4769 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4772 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4773 if (RHSBinOp->getIntrinsicID() ==
4774 llvm::Intrinsic::experimental_constrained_fmul &&
4775 (RHSBinOp->use_empty() || NegRHS)) {
4779 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4786Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4787 if (op.LHS->getType()->isPointerTy() ||
4788 op.RHS->getType()->isPointerTy())
4791 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4792 op.Ty->isUnsignedIntegerType()) {
4793 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4795 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4796 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4797 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4798 case LangOptions::OB_Wrap:
4799 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4800 case LangOptions::OB_SignedAndDefined:
4802 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4804 case LangOptions::OB_Unset:
4806 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4807 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4809 case LangOptions::OB_Trap:
4810 if (CanElideOverflowCheck(CGF.
getContext(), op))
4811 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4812 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4813 return EmitOverflowCheckedBinOp(op);
4818 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4819 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4825 if (op.Ty->isConstantMatrixType()) {
4826 llvm::MatrixBuilder MB(Builder);
4827 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4828 return MB.CreateAdd(op.LHS, op.RHS);
4831 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4832 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4833 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4836 if (op.isFixedPointOp())
4837 return EmitFixedPointBinOp(op);
4839 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4844Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4846 using llvm::ConstantInt;
4852 QualType ResultTy = op.Ty;
4853 QualType LHSTy, RHSTy;
4854 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4855 RHSTy = BinOp->getRHS()->getType();
4856 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4861 LHSTy = CAO->getComputationLHSType();
4862 ResultTy = CAO->getComputationResultType();
4864 LHSTy = BinOp->getLHS()->getType();
4865 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4866 LHSTy = UnOp->getSubExpr()->getType();
4867 RHSTy = UnOp->getSubExpr()->getType();
4870 Value *LHS = op.LHS;
4871 Value *RHS = op.RHS;
4876 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4880 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4881 switch (op.Opcode) {
4884 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4888 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4892 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4896 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4900 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4904 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4907 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4909 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4911 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4913 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4918 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4920 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4924 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4937 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4943 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4948Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4950 if (!op.LHS->getType()->isPointerTy()) {
4951 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4952 op.Ty->isUnsignedIntegerType()) {
4953 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4955 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4956 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4957 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4958 case LangOptions::OB_Wrap:
4959 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4960 case LangOptions::OB_SignedAndDefined:
4962 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4964 case LangOptions::OB_Unset:
4966 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4967 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4969 case LangOptions::OB_Trap:
4970 if (CanElideOverflowCheck(CGF.
getContext(), op))
4971 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4972 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4973 return EmitOverflowCheckedBinOp(op);
4978 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4979 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4985 if (op.Ty->isConstantMatrixType()) {
4986 llvm::MatrixBuilder MB(Builder);
4987 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4988 return MB.CreateSub(op.LHS, op.RHS);
4991 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4992 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4993 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4996 if (op.isFixedPointOp())
4997 return EmitFixedPointBinOp(op);
4999 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
5004 if (!op.RHS->getType()->isPointerTy())
5014 LHS = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
5015 RHS = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
5017 LHS = Builder.CreatePtrToAddr(op.LHS,
"sub.ptr.lhs.cast");
5018 RHS = Builder.CreatePtrToAddr(op.RHS,
"sub.ptr.rhs.cast");
5020 LHS = Builder.CreateZExtOrTrunc(LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5022 RHS = Builder.CreateZExtOrTrunc(RHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5024 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
5028 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
5030 llvm::Value *divisor =
nullptr;
5033 if (
const VariableArrayType *vla
5036 elementType = VlaSize.Type;
5037 divisor = VlaSize.NumElts;
5041 if (!eltSize.
isOne())
5048 CharUnits elementSize;
5057 if (elementSize.
isOne())
5064 return Builder.CreateSDiv(diffInChars, divisor,
"sub.ptr.div");
5068 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5071Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5073 llvm::IntegerType *Ty;
5074 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5082 llvm::Type *RHSTy = RHS->
getType();
5083 llvm::APInt RHSMax =
5084 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5085 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5086 if (RHSMax.ult(Ty->getBitWidth()))
5087 return llvm::ConstantInt::get(RHSTy, RHSMax);
5088 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5092 const Twine &Name) {
5093 llvm::IntegerType *Ty;
5094 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5099 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5100 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5102 return Builder.CreateURem(
5103 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5106Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5108 if (Ops.isFixedPointOp())
5109 return EmitFixedPointBinOp(Ops);
5113 Value *RHS = Ops.RHS;
5114 if (Ops.LHS->getType() != RHS->
getType())
5115 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5117 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5118 Ops.Ty->hasSignedIntegerRepresentation() &&
5121 bool SanitizeUnsignedBase =
5122 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5123 Ops.Ty->hasUnsignedIntegerRepresentation();
5124 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5125 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5128 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5129 else if ((SanitizeBase || SanitizeExponent) &&
5131 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5132 if (SanitizeSignedBase)
5133 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5134 if (SanitizeUnsignedBase)
5135 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5136 if (SanitizeExponent)
5137 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5139 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5140 SanitizerHandler::ShiftOutOfBounds);
5141 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5142 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5143 llvm::Value *WidthMinusOne =
5144 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5145 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5147 if (SanitizeExponent) {
5149 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5156 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5159 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5160 llvm::Value *PromotedWidthMinusOne =
5161 (RHS == Ops.RHS) ? WidthMinusOne
5162 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5164 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5165 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5174 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5175 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5177 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5178 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5180 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5181 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5182 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5183 Checks.push_back(std::make_pair(
5184 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5185 : SanitizerKind::SO_UnsignedShiftBase));
5188 assert(!Checks.empty());
5189 EmitBinOpCheck(Checks, Ops);
5192 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5195Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5197 if (Ops.isFixedPointOp())
5198 return EmitFixedPointBinOp(Ops);
5202 Value *RHS = Ops.RHS;
5203 if (Ops.LHS->getType() != RHS->
getType())
5204 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5208 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5209 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5211 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5212 SanitizerHandler::ShiftOutOfBounds);
5213 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5214 llvm::Value *
Valid = Builder.CreateICmpULE(
5215 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5216 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5219 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5220 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5221 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5229 default: llvm_unreachable(
"unexpected element type");
5230 case BuiltinType::Char_U:
5231 case BuiltinType::UChar:
5232 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5233 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5234 case BuiltinType::Char_S:
5235 case BuiltinType::SChar:
5236 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5237 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5238 case BuiltinType::UShort:
5239 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5240 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5241 case BuiltinType::Short:
5242 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5243 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5244 case BuiltinType::UInt:
5245 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5246 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5247 case BuiltinType::Int:
5248 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5249 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5250 case BuiltinType::ULong:
5251 case BuiltinType::ULongLong:
5252 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5253 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5254 case BuiltinType::Long:
5255 case BuiltinType::LongLong:
5256 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5257 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5258 case BuiltinType::Float:
5259 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5260 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5261 case BuiltinType::Double:
5262 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5263 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5264 case BuiltinType::UInt128:
5265 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5266 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5267 case BuiltinType::Int128:
5268 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5269 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5273Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5274 llvm::CmpInst::Predicate UICmpOpc,
5275 llvm::CmpInst::Predicate SICmpOpc,
5276 llvm::CmpInst::Predicate FCmpOpc,
5278 TestAndClearIgnoreResultAssign();
5282 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5288 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5290 BinOpInfo BOInfo = EmitBinOps(E);
5291 Value *LHS = BOInfo.LHS;
5292 Value *RHS = BOInfo.RHS;
5298 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5300 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5303 Value *FirstVecArg = LHS,
5304 *SecondVecArg = RHS;
5306 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5310 default: llvm_unreachable(
"is not a comparison operation");
5322 std::swap(FirstVecArg, SecondVecArg);
5329 if (ElementKind == BuiltinType::Float) {
5331 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5332 std::swap(FirstVecArg, SecondVecArg);
5340 if (ElementKind == BuiltinType::Float) {
5342 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5347 std::swap(FirstVecArg, SecondVecArg);
5352 Value *CR6Param = Builder.getInt32(CR6);
5354 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5362 if (ResultTy->getBitWidth() > 1 &&
5364 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5369 if (BOInfo.isFixedPointOp()) {
5370 Result = EmitFixedPointBinOp(BOInfo);
5371 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5372 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5374 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5376 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5378 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5381 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5387 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5396 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5398 CETy = CTy->getElementType();
5400 LHS.first = Visit(E->
getLHS());
5401 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5404 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5407 CTy->getElementType()) &&
5408 "The element types must always match.");
5411 RHS.first = Visit(E->
getRHS());
5412 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5414 "The element types must always match.");
5417 Value *ResultR, *ResultI;
5421 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5422 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5426 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5427 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5431 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5434 "Complex comparison other than == or != ?");
5435 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5447 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5448 CastKind Kind = ICE->getCastKind();
5449 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5450 *SrcType = ICE->getSubExpr()->getType();
5463 bool Ignore = TestAndClearIgnoreResultAssign();
5497 RHS = Visit(E->
getRHS());
5513 RHS = Visit(E->
getRHS());
5553 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5556Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5567 if (LHS->
getType()->isFPOrFPVectorTy()) {
5568 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5570 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5571 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5573 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5574 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5576 Value *
And = Builder.CreateAnd(LHS, RHS);
5577 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5581 llvm::Type *ResTy = ConvertType(E->
getType());
5600 if (InstrumentRegions &&
5604 llvm::BasicBlock *RHSSkip =
5607 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5624 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5635 return llvm::Constant::getNullValue(ResTy);
5646 llvm::BasicBlock *LHSFalseBlock =
5649 CodeGenFunction::ConditionalEvaluation eval(CGF);
5664 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5666 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5668 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5677 RHSBlock = Builder.GetInsertBlock();
5682 llvm::BasicBlock *ContIncoming = RHSBlock;
5683 if (InstrumentRegions &&
5687 llvm::BasicBlock *RHSBlockSkip =
5689 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5693 PN->addIncoming(RHSCond, RHSBlockCnt);
5698 ContIncoming = RHSBlockSkip;
5709 PN->addIncoming(RHSCond, ContIncoming);
5718 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5722 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5725Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5736 if (LHS->
getType()->isFPOrFPVectorTy()) {
5737 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5739 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5740 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5742 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5743 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5745 Value *
Or = Builder.CreateOr(LHS, RHS);
5746 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5750 llvm::Type *ResTy = ConvertType(E->
getType());
5769 if (InstrumentRegions &&
5773 llvm::BasicBlock *RHSSkip =
5776 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5793 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5804 return llvm::ConstantInt::get(ResTy, 1);
5814 llvm::BasicBlock *LHSTrueBlock =
5817 CodeGenFunction::ConditionalEvaluation eval(CGF);
5833 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5835 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5837 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5849 RHSBlock = Builder.GetInsertBlock();
5854 llvm::BasicBlock *ContIncoming = RHSBlock;
5855 if (InstrumentRegions &&
5859 llvm::BasicBlock *RHSTrueBlock =
5861 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5865 PN->addIncoming(RHSCond, RHSBlockCnt);
5870 ContIncoming = RHSTrueBlock;
5877 PN->addIncoming(RHSCond, ContIncoming);
5884 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5887Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5890 return Visit(E->
getRHS());
5897Value *ScalarExprEmitter::
5898VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5899 TestAndClearIgnoreResultAssign();
5902 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5904 Expr *condExpr = E->
getCond();
5912 Expr *live = lhsExpr, *dead = rhsExpr;
5913 if (!CondExprBool) std::swap(live, dead);
5940 llvm::Value *LHS = Visit(lhsExpr);
5941 llvm::Value *RHS = Visit(rhsExpr);
5943 llvm::Type *condType = ConvertType(condExpr->
getType());
5946 unsigned numElem = vecTy->getNumElements();
5947 llvm::Type *elemType = vecTy->getElementType();
5949 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5950 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5951 llvm::Value *tmp = Builder.CreateSExt(
5952 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5953 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5956 llvm::Value *RHSTmp = RHS;
5957 llvm::Value *LHSTmp = LHS;
5958 bool wasCast =
false;
5960 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5961 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5962 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5966 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5967 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5968 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5970 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5980 llvm::Value *LHS = Visit(lhsExpr);
5981 llvm::Value *RHS = Visit(rhsExpr);
5983 llvm::Type *CondType = ConvertType(condExpr->
getType());
5986 if (VecTy->getElementType()->isIntegerTy(1))
5987 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5990 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5992 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5994 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5995 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
6007 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
6011 llvm::Value *LHS = Visit(lhsExpr);
6012 llvm::Value *RHS = Visit(rhsExpr);
6015 assert(!RHS &&
"LHS and RHS types must match");
6018 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6029 CodeGenFunction::ConditionalEvaluation eval(CGF);
6043 Value *LHS = Visit(lhsExpr);
6046 LHSBlock = Builder.GetInsertBlock();
6047 Builder.CreateBr(ContBlock);
6059 Value *RHS = Visit(rhsExpr);
6062 RHSBlock = Builder.GetInsertBlock();
6072 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6073 PN->addIncoming(LHS, LHSBlock);
6074 PN->addIncoming(RHS, RHSBlock);
6079Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6083Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6085 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6090Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6096 Value *Src,
unsigned NumElementsDst) {
6097 static constexpr int Mask[] = {0, 1, 2, -1};
6098 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6118 const llvm::DataLayout &DL,
6119 Value *Src, llvm::Type *DstTy,
6120 StringRef Name =
"") {
6124 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6125 return Builder.CreateBitCast(Src, DstTy, Name);
6128 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6129 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6132 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6134 if (!DstTy->isIntegerTy())
6135 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6137 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6141 if (!SrcTy->isIntegerTy())
6142 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6144 return Builder.CreateIntToPtr(Src, DstTy, Name);
6147Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6149 llvm::Type *DstTy = ConvertType(E->
getType());
6151 llvm::Type *SrcTy = Src->
getType();
6152 unsigned NumElementsSrc =
6156 unsigned NumElementsDst =
6167 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6172 Src->setName(
"astype");
6179 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6180 auto *Vec4Ty = llvm::FixedVectorType::get(
6186 Src->setName(
"astype");
6191 Src, DstTy,
"astype");
6194Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6206 "Invalid scalar expression to emit");
6208 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6209 .Visit(
const_cast<Expr *
>(E));
6218 "Invalid scalar expression to emit");
6219 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6229 "Invalid complex -> scalar conversion");
6230 return ScalarExprEmitter(*
this)
6231 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6238 if (!PromotionType.
isNull())
6239 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6241 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6247 bool isInc,
bool isPre) {
6248 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6258 llvm::Type *BaseTy =
6274 ScalarExprEmitter Scalar(*
this);
6277#define COMPOUND_OP(Op) \
6278 case BO_##Op##Assign: \
6279 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6316 llvm_unreachable(
"Not valid compound assignment operators");
6319 llvm_unreachable(
"Unhandled compound assignment operator");
6340 llvm::Value *TotalOffset =
nullptr;
6342 auto *IntPtrTy = DL.getAddressType(BasePtr->
getType());
6345 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6346 auto *SAddIntrinsic =
6347 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6348 auto *SMulIntrinsic =
6349 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6352 llvm::Value *OffsetOverflows = Builder.getFalse();
6356 llvm::Value *RHS) -> llvm::Value * {
6357 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6360 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6361 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6363 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6366 OffsetOverflows = Builder.getTrue();
6367 return llvm::ConstantInt::get(VMContext, N);
6372 auto *ResultAndOverflow = Builder.CreateCall(
6373 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6374 OffsetOverflows = Builder.CreateOr(
6375 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6376 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6380 for (
auto GTI = llvm::gep_type_begin(ElemTy, IdxList),
6381 GTE = llvm::gep_type_end(ElemTy, IdxList);
6382 GTI != GTE; ++GTI) {
6383 llvm::Value *LocalOffset;
6384 auto *Index = GTI.getOperand();
6386 if (
auto *STy = GTI.getStructTypeOrNull()) {
6390 LocalOffset = llvm::ConstantInt::get(
6391 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6396 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6397 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6398 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6403 if (!TotalOffset || TotalOffset ==
Zero)
6404 TotalOffset = LocalOffset;
6406 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6409 return {TotalOffset, OffsetOverflows};
6414static llvm::GEPNoWrapFlags
6416 llvm::Type *SrcTy,
bool SignedIndices,
bool IsSubtraction) {
6417 llvm::GEPNoWrapFlags NW;
6418 bool SectionGEP = CGF.
getLangOpts().OpenMPIsTargetDevice &&
6419 SrcTy->isArrayTy() &&
6420 SrcTy->getArrayElementType()->isArrayTy() &&
6423 NW = llvm::GEPNoWrapFlags::inBounds();
6424 if (!SignedIndices && !IsSubtraction)
6425 NW |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6431 ArrayRef<Value *> IdxList,
6432 bool SignedIndices,
bool IsSubtraction,
6433 SourceLocation Loc,
const Twine &Name) {
6434 llvm::Type *PtrTy =
Ptr->getType();
6436 llvm::GEPNoWrapFlags NWFlags =
6439 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6442 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6446 bool PerformNullCheck = !NullPointerIsDefined(
6447 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6450 bool PerformOverflowCheck =
6453 if (!(PerformNullCheck || PerformOverflowCheck))
6456 const auto &DL = CGM.getDataLayout();
6458 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6459 auto CheckHandler = SanitizerHandler::PointerOverflow;
6460 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6461 llvm::Type *IntPtrTy = DL.getAddressType(PtrTy);
6464 Ptr, ElemTy, IdxList, getLLVMContext(), CGM, Builder);
6466 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6476 auto *IntPtr = Builder.CreatePtrToAddr(Ptr);
6477 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6479 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6483 if (PerformNullCheck) {
6491 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6492 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6493 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6494 Checks.emplace_back(
Valid, CheckOrdinal);
6497 if (PerformOverflowCheck) {
6502 llvm::Value *ValidGEP;
6503 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6504 if (SignedIndices) {
6510 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6511 auto *PosOrZeroOffset =
6513 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6515 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6516 }
else if (!IsSubtraction) {
6521 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6527 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6529 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6530 Checks.emplace_back(ValidGEP, CheckOrdinal);
6533 assert(!Checks.empty() &&
"Should have produced some checks.");
6535 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6537 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6538 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6544 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6545 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6546 const Twine &Name) {
6547 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6548 llvm::GEPNoWrapFlags NWFlags =
6550 SignedIndices, IsSubtraction);
6551 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6555 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6556 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6557 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, llvm::Type *ElemTy, ArrayRef< Value * > IdxList, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Compute the total offset in bytes that indexing BasePtr with ElemTy and IdxList applies,...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static llvm::GEPNoWrapFlags inBoundsGEPFlags(const CodeGenFunction &CGF, const llvm::Value *Ptr, llvm::Type *SrcTy, bool SignedIndices, bool IsSubtraction)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * EmitHLSLElementwiseCastToVector(CodeGenFunction &CGF, QualType DestTy, unsigned NumSrcElements, GetElementTy GetElement, SourceLocation Loc)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static mlir::Value tryEmitFMulAdd(mlir::Location loc, const BinOpInfo &op, CIRGenBuilderTy &builder, bool isSub=false)
static mlir::Value buildFMulAdd(mlir::Location addLoc, cir::FMulOp mulOp, mlir::Value addend, CIRGenBuilderTy &builder, bool negMul, bool negAdd)
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
Result
Implement __builtin_bit_cast and related operations.
Defines AST-level helper utilities for matrix types.
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedCharTy
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
bool isOne() const
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.
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.
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...
LoadedLValueCapture * CurLoadedLValueCapture
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
const Qualifiers & getQuals() const
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned mapRowMajorToColumnMajorFlattenedIndex(unsigned RowMajorIdx) const
Given a row-major flattened index RowMajorIdx, return the equivalent column-major flattened index.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
bool isSignedOverflowDefined() const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
const clang::Expr * ExprTy
bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, const ASTContext &Ctx)
Check whether E is cheap enough and side-effect-free enough to evaluate unconditionally instead of co...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
PRESERVE_NONE bool Ret(InterpState &S)
@ Address
A pointer to a ValueDecl.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
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, not including padding.
const Expr * E
The expression whose l-value is recorded.
std::optional< LValue > LV
The recorded l-value, set if E was loaded by ScalarExprEmitter.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::Type * HalfTy
half, bfloat, float, double
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool HasSideEffects
Whether the evaluated expression has side effects.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.