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) {
377 EmitLValueAlignmentAssumption(E,
V);
383 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
387 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
388 Value *Src, QualType SrcType, QualType DstType,
389 llvm::Type *DstTy, SourceLocation Loc);
394 enum ImplicitConversionCheckKind :
unsigned char {
395 ICCK_IntegerTruncation = 0,
396 ICCK_UnsignedIntegerTruncation = 1,
397 ICCK_SignedIntegerTruncation = 2,
398 ICCK_IntegerSignChange = 3,
399 ICCK_SignedIntegerTruncationOrSignChange = 4,
404 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
405 QualType DstType, SourceLocation Loc,
406 bool OBTrapInvolved =
false);
411 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
412 QualType DstType, SourceLocation Loc,
413 bool OBTrapInvolved =
false);
417 struct ScalarConversionOpts {
418 bool TreatBooleanAsSigned;
419 bool EmitImplicitIntegerTruncationChecks;
420 bool EmitImplicitIntegerSignChangeChecks;
422 bool PatternExcluded;
424 ScalarConversionOpts()
425 : TreatBooleanAsSigned(
false),
426 EmitImplicitIntegerTruncationChecks(
false),
427 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
429 ScalarConversionOpts(clang::SanitizerSet SanOpts)
430 : TreatBooleanAsSigned(
false),
431 EmitImplicitIntegerTruncationChecks(
432 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
433 EmitImplicitIntegerSignChangeChecks(
434 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
435 PatternExcluded(
false) {}
437 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
438 llvm::Type *SrcTy, llvm::Type *DstTy,
439 ScalarConversionOpts Opts);
441 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
443 ScalarConversionOpts Opts = ScalarConversionOpts());
447 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
453 QualType SrcTy, QualType DstTy,
457 Value *EmitNullValue(QualType Ty);
462 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
463 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
467 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
470 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
477 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
478 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
484 ZI->eraseFromParent();
489 return Builder.CreateIsNotNull(
V,
"tobool");
496 Value *Visit(Expr *E) {
497 ApplyDebugLocation DL(CGF, E);
498 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
501 Value *VisitStmt(Stmt *S) {
503 llvm_unreachable(
"Stmt can't have complex result type!");
505 Value *VisitExpr(Expr *S);
507 Value *VisitConstantExpr(ConstantExpr *E) {
513 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
528 Value *VisitParenExpr(ParenExpr *PE) {
531 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
534 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
535 return Visit(
GE->getResultExpr());
537 Value *VisitCoawaitExpr(CoawaitExpr *S) {
540 Value *VisitCoyieldExpr(CoyieldExpr *S) {
543 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
548 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
549 return Builder.getInt(E->
getValue());
551 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
552 return Builder.getInt(E->
getValue());
554 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
555 return llvm::ConstantFP::get(VMContext, E->
getValue());
557 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
560 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
563 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
564 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
566 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
567 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
569 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
573 return EmitNullValue(E->
getType());
575 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
576 return EmitNullValue(E->
getType());
578 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
579 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
580 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
582 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
585 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
589 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
593 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
594 Value *VisitEmbedExpr(EmbedExpr *E);
596 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
605 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
606 llvm_unreachable(
"Codegen for this isn't defined/implemented");
610 Value *VisitDeclRefExpr(DeclRefExpr *E) {
613 return EmitLoadOfLValue(E);
616 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
619 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
622 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
623 return EmitLoadOfLValue(E);
625 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
628 return EmitLoadOfLValue(E);
632 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
638 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
644 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
649 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
650 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
651 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
652 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
653 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
654 Value *VisitMemberExpr(MemberExpr *E);
655 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
656 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
657 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
663 return EmitLoadOfLValue(E);
666 Value *VisitInitListExpr(InitListExpr *E);
668 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
670 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
674 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
675 return EmitNullValue(E->
getType());
677 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
679 return VisitCastExpr(E);
683 Value *VisitCallExpr(
const CallExpr *E) {
685 return EmitLoadOfLValue(E);
687 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
691 EmitLValueAlignmentAssumption(E,
V);
695 Value *VisitStmtExpr(
const StmtExpr *E);
698 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
700 return EmitScalarPrePostIncDec(E, LV,
false,
false);
702 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
704 return EmitScalarPrePostIncDec(E, LV,
true,
false);
706 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
708 return EmitScalarPrePostIncDec(E, LV,
false,
true);
710 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
712 return EmitScalarPrePostIncDec(E, LV,
true,
true);
715 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
719 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
720 bool isInc,
bool isPre);
723 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
727 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
729 Value *VisitUnaryDeref(
const UnaryOperator *E) {
732 return EmitLoadOfLValue(E);
735 Value *VisitUnaryPlus(
const UnaryOperator *E,
736 QualType PromotionType = QualType());
737 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
738 Value *VisitUnaryMinus(
const UnaryOperator *E,
739 QualType PromotionType = QualType());
740 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
742 Value *VisitUnaryNot (
const UnaryOperator *E);
743 Value *VisitUnaryLNot (
const UnaryOperator *E);
744 Value *VisitUnaryReal(
const UnaryOperator *E,
745 QualType PromotionType = QualType());
746 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
747 Value *VisitUnaryImag(
const UnaryOperator *E,
748 QualType PromotionType = QualType());
749 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
750 Value *VisitUnaryExtension(
const UnaryOperator *E) {
755 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
756 return EmitLoadOfLValue(E);
758 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
766 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
767 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
770 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
771 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
774 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
778 Value *VisitExprWithCleanups(ExprWithCleanups *E);
779 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
782 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
787 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
789 return llvm::ConstantInt::get(ConvertType(E->
getType()),
793 return llvm::ConstantInt::get(ConvertType(E->
getType()),
797 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
805 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
806 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
809 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
810 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
813 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
823 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
824 return EmitNullValue(E->
getType());
827 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
832 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
833 return Builder.getInt1(E->
getValue());
837 Value *EmitMul(
const BinOpInfo &Ops) {
838 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
839 Ops.Ty->isUnsignedIntegerType()) {
840 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
842 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
843 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
844 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
845 case LangOptions::OB_Wrap:
846 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
847 case LangOptions::OB_SignedAndDefined:
849 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
851 case LangOptions::OB_Unset:
853 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
854 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
856 case LangOptions::OB_Trap:
857 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
858 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
859 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
860 return EmitOverflowCheckedBinOp(Ops);
864 if (Ops.Ty->isConstantMatrixType()) {
865 llvm::MatrixBuilder MB(Builder);
869 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
870 BO->getLHS()->getType().getCanonicalType());
871 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
872 BO->getRHS()->getType().getCanonicalType());
873 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
874 if (LHSMatTy && RHSMatTy)
875 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
876 LHSMatTy->getNumColumns(),
877 RHSMatTy->getNumColumns());
878 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
881 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
883 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
884 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
886 if (Ops.isFixedPointOp())
887 return EmitFixedPointBinOp(Ops);
888 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
892 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
895 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
896 llvm::Value *
Zero,
bool isDiv);
898 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
904 Value *EmitDiv(
const BinOpInfo &Ops);
905 Value *EmitRem(
const BinOpInfo &Ops);
906 Value *EmitAdd(
const BinOpInfo &Ops);
907 Value *EmitSub(
const BinOpInfo &Ops);
908 Value *EmitShl(
const BinOpInfo &Ops);
909 Value *EmitShr(
const BinOpInfo &Ops);
910 Value *EmitAnd(
const BinOpInfo &Ops) {
911 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
913 Value *EmitXor(
const BinOpInfo &Ops) {
914 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
916 Value *EmitOr (
const BinOpInfo &Ops) {
917 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
921 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
923 BinOpInfo EmitBinOps(
const BinaryOperator *E,
924 QualType PromotionTy = QualType());
926 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
927 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
928 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
930 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
931 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
934 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
935 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
937 QualType getPromotionType(QualType Ty) {
939 if (
auto *CT = Ty->
getAs<ComplexType>()) {
940 QualType ElementType = CT->getElementType();
941 if (ElementType.UseExcessPrecision(Ctx))
946 if (
auto *VT = Ty->
getAs<VectorType>()) {
947 unsigned NumElements = VT->getNumElements();
957#define HANDLEBINOP(OP) \
958 Value *VisitBin##OP(const BinaryOperator *E) { \
959 QualType promotionTy = getPromotionType(E->getType()); \
960 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
961 if (result && !promotionTy.isNull()) \
962 result = EmitUnPromotedValue(result, E->getType()); \
965 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
966 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
967 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
983 llvm::CmpInst::Predicate SICmpOpc,
984 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
985#define VISITCOMP(CODE, UI, SI, FP, SIG) \
986 Value *VisitBin##CODE(const BinaryOperator *E) { \
987 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
988 llvm::FCmpInst::FP, SIG); }
989 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
1003 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
1004 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1006 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1011 Value *VisitBlockExpr(
const BlockExpr *BE);
1012 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1013 Value *VisitChooseExpr(ChooseExpr *CE);
1014 Value *VisitVAArgExpr(VAArgExpr *VE);
1015 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1018 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1021 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1024 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1027 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1028 Value *VisitAtomicExpr(AtomicExpr *AE);
1029 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1042 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1045 return EmitFloatToBoolConversion(Src);
1047 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1051 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1055 "Unknown scalar type to convert");
1058 return EmitIntToBoolConversion(Src);
1061 return EmitPointerToBoolConversion(Src, SrcType);
1064void ScalarExprEmitter::EmitFloatConversionCheck(
1065 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1066 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1067 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1071 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1072 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1073 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1074 using llvm::APFloat;
1077 llvm::Value *Check =
nullptr;
1078 const llvm::fltSemantics &SrcSema =
1088 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1089 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1090 APFloat::opOverflow)
1093 MinSrc = APFloat::getInf(SrcSema,
true);
1097 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1100 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1101 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1102 APFloat::opOverflow)
1105 MaxSrc = APFloat::getInf(SrcSema,
false);
1109 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1114 const llvm::fltSemantics &Sema =
1117 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1118 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1122 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1124 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1125 Check = Builder.CreateAnd(GE, LE);
1130 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1136static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1137 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1140 llvm::Type *SrcTy = Src->
getType();
1141 llvm::Type *DstTy = Dst->
getType();
1146 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1148 "non-integer llvm type");
1155 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1157 if (!SrcSigned && !DstSigned) {
1158 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1159 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1161 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1162 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1165 llvm::Value *Check =
nullptr;
1167 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1169 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1171 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1179void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1180 Value *Dst, QualType DstType,
1182 bool OBTrapInvolved) {
1183 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1193 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1194 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1196 if (SrcBits <= DstBits)
1199 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1206 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1207 (!SrcSigned && DstSigned))
1210 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1211 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1214 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1219 SanitizerDebugLocation SanScope(
1221 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1222 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1238 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1246 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1247 if (OBT->isWrapKind())
1250 if (ignoredBySanitizer && !OBTrapInvolved)
1253 llvm::Constant *StaticArgs[] = {
1256 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1257 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1259 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1266 llvm::Type *VTy =
V->getType();
1269 return llvm::ConstantInt::getFalse(VTy->getContext());
1271 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1272 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1273 llvm::Twine(Name) +
"." +
V->getName() +
1274 ".negativitycheck");
1279static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1280 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1283 llvm::Type *SrcTy = Src->
getType();
1284 llvm::Type *DstTy = Dst->
getType();
1287 "non-integer llvm type");
1293 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1294 unsigned DstBits = DstTy->getScalarSizeInBits();
1298 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1299 "either the widths should be different, or the signednesses.");
1302 llvm::Value *SrcIsNegative =
1305 llvm::Value *DstIsNegative =
1311 llvm::Value *Check =
nullptr;
1312 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1314 return std::make_pair(
1315 ScalarExprEmitter::ICCK_IntegerSignChange,
1316 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1319void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1320 Value *Dst, QualType DstType,
1322 bool OBTrapInvolved) {
1323 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1327 llvm::Type *SrcTy = Src->
getType();
1328 llvm::Type *DstTy = Dst->
getType();
1338 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1339 unsigned DstBits = DstTy->getScalarSizeInBits();
1346 if (SrcSigned == DstSigned && SrcBits == DstBits)
1350 if (!SrcSigned && !DstSigned)
1355 if ((DstBits > SrcBits) && DstSigned)
1357 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1358 (SrcBits > DstBits) && SrcSigned) {
1367 if (!OBTrapInvolved) {
1370 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1374 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1379 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1380 SanitizerDebugLocation SanScope(
1382 {SanitizerKind::SO_ImplicitIntegerSignChange,
1383 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1384 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1387 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1388 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1392 ImplicitConversionCheckKind CheckKind;
1393 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1400 CheckKind = Check.first;
1401 Checks.emplace_back(Check.second);
1403 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1404 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1410 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1411 Checks.emplace_back(Check.second);
1415 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1416 if (OBTrapInvolved) {
1417 llvm::Value *Combined = Check.second.first;
1418 for (
const auto &
C : Checks)
1419 Combined = Builder.CreateAnd(Combined,
C.first);
1425 llvm::Constant *StaticArgs[] = {
1428 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1429 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1431 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1436static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1437 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1443 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1444 if (!SrcSigned && !DstSigned)
1445 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1447 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1449 llvm::Value *Check =
nullptr;
1451 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1453 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1456 return std::make_pair(
1458 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1463static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1464 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1468 llvm::Value *SrcIsNegative =
1471 llvm::Value *DstIsNegative =
1477 llvm::Value *Check =
nullptr;
1479 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1481 return std::make_pair(
1482 ScalarExprEmitter::ICCK_IntegerSignChange,
1483 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1491 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1509 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1510 unsigned DstBits = Info.
Size;
1515 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1517 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1519 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1520 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1524 bool EmitTruncation = DstBits < SrcBits;
1528 bool EmitTruncationFromUnsignedToSigned =
1529 EmitTruncation && DstSigned && !SrcSigned;
1531 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1532 bool BothUnsigned = !SrcSigned && !DstSigned;
1533 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1540 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1545 else if (EmitSignChange) {
1546 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1547 "either the widths should be different, or the signednesses.");
1553 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1554 if (EmitTruncationFromUnsignedToSigned)
1555 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1557 llvm::Constant *StaticArgs[] = {
1560 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1561 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1563 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1567 QualType DstType, llvm::Type *SrcTy,
1569 ScalarConversionOpts Opts) {
1571 llvm::Type *SrcElementTy;
1572 llvm::Type *DstElementTy;
1582 "cannot cast between matrix and non-matrix types");
1583 SrcElementTy = SrcTy;
1584 DstElementTy = DstTy;
1585 SrcElementType = SrcType;
1586 DstElementType = DstType;
1591 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1596 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1598 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1599 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1603 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1610 llvm::Intrinsic::ID IID =
1611 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1612 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1616 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1617 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1620 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1621 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1622 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1624 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1625 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1626 return Builder.CreateFPExt(Src, DstTy,
"conv");
1631Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1634 ScalarConversionOpts Opts) {
1649 return Builder.CreateIsNotNull(Src,
"tobool");
1652 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1655 "Unhandled scalar conversion from a fixed point type to another type.");
1659 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1662 "Unhandled scalar conversion to a fixed point type from another type.");
1665 QualType NoncanonicalSrcType = SrcType;
1666 QualType NoncanonicalDstType = DstType;
1670 if (SrcType == DstType)
return Src;
1674 llvm::Value *OrigSrc = Src;
1675 QualType OrigSrcType = SrcType;
1676 llvm::Type *SrcTy = Src->
getType();
1680 return EmitConversionToBool(Src, SrcType);
1682 llvm::Type *DstTy = ConvertType(DstType);
1691 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1692 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1693 bool OBTrapInvolved =
1694 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1695 bool OBWrapInvolved =
1696 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1701 if (DstTy->isFloatingPointTy())
1702 return Builder.CreateFPExt(Src, DstTy,
"conv");
1706 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1712 if (SrcTy == DstTy) {
1713 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1714 (OBTrapInvolved && !OBWrapInvolved))
1715 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1716 NoncanonicalDstType, Loc, OBTrapInvolved);
1724 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1729 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1734 llvm::Value* IntResult =
1735 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1737 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1743 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1750 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1752 "Splatted expr doesn't match with vector element type?");
1756 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1760 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1764 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1765 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1766 if (SrcSize == DstSize)
1767 return Builder.CreateBitCast(Src, DstTy,
"conv");
1780 assert(((SrcElementTy->isIntegerTy() &&
1781 DstElementTy->isIntegerTy()) ||
1782 (SrcElementTy->isFloatingPointTy() &&
1783 DstElementTy->isFloatingPointTy())) &&
1784 "unexpected conversion between a floating-point vector and an "
1788 if (SrcElementTy->isIntegerTy())
1789 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1792 if (SrcSize > DstSize)
1793 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1796 return Builder.CreateFPExt(Src, DstTy,
"conv");
1800 Value *Res =
nullptr;
1801 llvm::Type *ResTy = DstTy;
1808 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1810 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1818 if (SrcTy->isFloatingPointTy())
1819 return Builder.CreateFPTrunc(Src, CGF.
CGM.
HalfTy,
"conv");
1824 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1826 if (DstTy != ResTy) {
1827 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1830 assert(ResTy->isIntegerTy(16) &&
1831 "Only half FP requires extra conversion");
1832 Res = Builder.CreateBitCast(Res, ResTy);
1836 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1837 !OBWrapInvolved && !Opts.PatternExcluded)
1838 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1839 NoncanonicalDstType, Loc, OBTrapInvolved);
1841 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1842 (OBTrapInvolved && !OBWrapInvolved))
1843 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1844 NoncanonicalDstType, Loc, OBTrapInvolved);
1849Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1851 SourceLocation Loc) {
1852 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1855 Result = FPBuilder.CreateFloatingToFixed(Src,
1858 Result = FPBuilder.CreateFixedToFloating(Src,
1860 ConvertType(DstTy));
1866 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1867 DstFPSema.getWidth(),
1868 DstFPSema.isSigned());
1870 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1873 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1880Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1882 SourceLocation Loc) {
1884 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1889 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1890 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1891 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1898 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1901Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1909void ScalarExprEmitter::EmitBinOpCheck(
1910 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1911 const BinOpInfo &Info) {
1914 SmallVector<llvm::Constant *, 4> StaticData;
1915 SmallVector<llvm::Value *, 2> DynamicData;
1923 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1924 if (UO && UO->
getOpcode() == UO_Minus) {
1925 Check = SanitizerHandler::NegateOverflow;
1927 DynamicData.push_back(Info.RHS);
1931 Check = SanitizerHandler::ShiftOutOfBounds;
1933 StaticData.push_back(
1935 StaticData.push_back(
1937 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1939 Check = SanitizerHandler::DivremOverflow;
1943 int ArithOverflowKind = 0;
1946 Check = SanitizerHandler::AddOverflow;
1947 ArithOverflowKind = diag::UBSanArithKind::Add;
1951 Check = SanitizerHandler::SubOverflow;
1952 ArithOverflowKind = diag::UBSanArithKind::Sub;
1956 Check = SanitizerHandler::MulOverflow;
1957 ArithOverflowKind = diag::UBSanArithKind::Mul;
1961 llvm_unreachable(
"unexpected opcode for bin op check");
1965 SanitizerKind::UnsignedIntegerOverflow) ||
1967 SanitizerKind::SignedIntegerOverflow)) {
1971 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1975 DynamicData.push_back(Info.LHS);
1976 DynamicData.push_back(Info.RHS);
1979 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1986Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1994ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1996 unsigned AddrSpace =
1998 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2002 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2006Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2008 auto It = E->
begin();
2009 return Builder.getInt((*It)->getValue());
2012Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2020 unsigned LHSElts = LTy->getNumElements();
2028 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2029 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2037 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2038 MTy->getNumElements());
2039 Value* NewV = llvm::PoisonValue::get(RTy);
2040 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2041 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2042 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2044 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2045 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2053 SmallVector<int, 32> Indices;
2057 if (Idx.isSigned() && Idx.isAllOnes())
2058 Indices.push_back(-1);
2060 Indices.push_back(Idx.getZExtValue());
2063 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2066Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2074 if (SrcType == DstType)
return Src;
2077 "ConvertVector source type must be a vector");
2079 "ConvertVector destination type must be a vector");
2081 llvm::Type *SrcTy = Src->
getType();
2082 llvm::Type *DstTy = ConvertType(DstType);
2088 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2089 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2091 assert(SrcTy->isVectorTy() &&
2092 "ConvertVector source IR type must be a vector");
2093 assert(DstTy->isVectorTy() &&
2094 "ConvertVector destination IR type must be a vector");
2099 if (DstEltType->isBooleanType()) {
2100 assert((SrcEltTy->isFloatingPointTy() ||
2103 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2104 if (SrcEltTy->isFloatingPointTy()) {
2105 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2106 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2108 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2113 Value *Res =
nullptr;
2118 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2120 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2122 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2124 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2127 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2128 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2129 if (DstEltType->isSignedIntegerOrEnumerationType())
2130 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2132 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2134 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2135 "Unknown real conversion");
2136 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2137 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2138 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2140 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2146Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2155 return Builder.getInt(
Value);
2159 llvm::Value *
Result = EmitLoadOfLValue(E);
2165 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2166 if (llvm::GetElementPtrInst *GEP =
2167 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2168 if (llvm::Instruction *
Pointer =
2169 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2181Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2182 TestAndClearIgnoreResultAssign();
2190 return EmitLoadOfLValue(E);
2198 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2201 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2205 Ret = Builder.CreateInsertElement(
2206 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2212Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2213 MatrixSingleSubscriptExpr *E) {
2214 TestAndClearIgnoreResultAssign();
2217 unsigned NumRows = MatrixTy->getNumRows();
2218 unsigned NumColumns = MatrixTy->getNumColumns();
2222 llvm::MatrixBuilder MB(Builder);
2226 MB.CreateIndexAssumption(RowIdx, NumRows);
2229 llvm::Type *ElemTy = CGF.
ConvertType(MatrixTy->getElementType());
2230 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2231 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2233 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2234 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2235 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2236 false,
"matrix_row_idx");
2238 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2239 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2240 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2246Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2247 TestAndClearIgnoreResultAssign();
2255 llvm::MatrixBuilder MB(Builder);
2257 unsigned NumCols = MatrixTy->getNumColumns();
2258 unsigned NumRows = MatrixTy->getNumRows();
2259 bool IsMatrixRowMajor =
2263 MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2266 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2271 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2276 int MV = SVI->getMaskValue(Idx);
2283 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2284 "Index operand too large for shufflevector mask!");
2285 return C->getZExtValue();
2288Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2289 bool Ignore = TestAndClearIgnoreResultAssign();
2292 assert((Ignore ==
false ||
2294 "init list ignored");
2311 llvm::VectorType *VType =
2312 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2315 if (NumInitElements == 0) {
2317 return EmitNullValue(E->
getType());
2324 if (NumInitElements == 0) {
2326 return EmitNullValue(E->
getType());
2329 if (NumInitElements == 1) {
2330 Expr *InitVector = E->
getInit(0);
2335 return Visit(InitVector);
2338 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2345 const ConstantMatrixType *ColMajorMT =
2353 unsigned CurIdx = 0;
2354 bool VIsPoisonShuffle =
false;
2355 llvm::Value *
V = llvm::PoisonValue::get(VType);
2356 for (
unsigned i = 0; i != NumInitElements; ++i) {
2359 SmallVector<int, 16> Args;
2361 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2371 ->getNumElements() == ResElts) {
2373 Value *LHS =
nullptr, *RHS =
nullptr;
2378 Args.resize(ResElts, -1);
2380 LHS = EI->getVectorOperand();
2382 VIsPoisonShuffle =
true;
2383 }
else if (VIsPoisonShuffle) {
2386 for (
unsigned j = 0; j != CurIdx; ++j)
2388 Args.push_back(ResElts +
C->getZExtValue());
2389 Args.resize(ResElts, -1);
2392 RHS = EI->getVectorOperand();
2393 VIsPoisonShuffle =
false;
2395 if (!Args.empty()) {
2396 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2402 unsigned InsertIdx =
2406 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2408 VIsPoisonShuffle =
false;
2418 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2421 Value *SVOp = SVI->getOperand(0);
2424 if (OpTy->getNumElements() == ResElts) {
2425 for (
unsigned j = 0; j != CurIdx; ++j) {
2428 if (VIsPoisonShuffle) {
2434 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2436 Args.resize(ResElts, -1);
2438 if (VIsPoisonShuffle)
2448 for (
unsigned j = 0; j != InitElts; ++j)
2450 Args.resize(ResElts, -1);
2451 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2454 for (
unsigned j = 0; j != CurIdx; ++j)
2456 for (
unsigned j = 0; j != InitElts; ++j)
2457 Args.push_back(j + Offset);
2458 Args.resize(ResElts, -1);
2465 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2472 llvm::Type *EltTy = VType->getElementType();
2475 for (; CurIdx < ResElts; ++CurIdx) {
2476 unsigned InsertIdx =
2479 Value *Idx = Builder.getInt32(InsertIdx);
2480 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2481 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2494 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2498 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2501 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2520 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2524 if (
const auto *CE = dyn_cast<CastExpr>(E))
2525 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2526 CE->getCastKind() == CK_ArrayToPointerDecay)
2537 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2547 if (ICE->isGLValue())
2554template <
typename GetElementTy>
2557 unsigned NumSrcElements,
2560 assert(NumSrcElements >= VecTy->getNumElements() &&
2561 "Flattened type on RHS must have the same number or more elements "
2562 "than vector on LHS.");
2564 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; ++I) {
2565 auto [Element, ElementTy] = GetElement(I);
2567 VecTy->getElementType(), Loc);
2568 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2581 CGF, DestTy, LoadList.size(),
2583 RValue RVal = CGF.EmitLoadOfLValue(LoadList[I], Loc);
2584 assert(RVal.isScalar() &&
2585 "All flattened source values should be scalars.");
2586 return std::pair(RVal.getScalarVal(), LoadList[I].getType());
2591 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2592 "Flattened type on RHS must have the same number or more elements "
2593 "than vector on LHS.");
2595 llvm::Value *
V = llvm::PoisonValue::get(CGF.
ConvertType(DestTy));
2597 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2598 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2601 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2604 "All flattened source values should be scalars.");
2607 MatTy->getElementType(), Loc);
2608 unsigned MatrixIdx = MatTy->getColumnMajorFlattenedIndex(Row, Col);
2609 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2616 "Destination type must be a vector, matrix, or builtin type.");
2618 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2627 llvm::scope_exit RestoreCurCast(
2628 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2632 QualType DestTy = CE->
getType();
2634 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2638 bool Ignored = TestAndClearIgnoreResultAssign();
2644 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2645 case CK_BuiltinFnToFnPtr:
2646 llvm_unreachable(
"builtin functions are handled elsewhere");
2648 case CK_LValueBitCast:
2649 case CK_ObjCObjectLValueCast: {
2653 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2656 case CK_LValueToRValueBitCast: {
2662 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2665 case CK_CPointerToObjCPointerCast:
2666 case CK_BlockPointerToObjCPointerCast:
2667 case CK_AnyPointerToBlockPointerCast:
2669 Value *Src = Visit(E);
2670 llvm::Type *SrcTy = Src->
getType();
2671 llvm::Type *DstTy = ConvertType(DestTy);
2682 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2696 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2697 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2702 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2703 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2704 "Address-space cast must be used to convert address spaces");
2706 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2707 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2709 PT->getPointeeType(),
2720 const QualType SrcType = E->
getType();
2725 Src = Builder.CreateLaunderInvariantGroup(Src);
2730 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2734 if (!PointeeType.
isNull())
2743 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2744 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2747 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2748 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2749 ScalableDstTy = llvm::ScalableVectorType::get(
2750 FixedSrcTy->getElementType(),
2752 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2754 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2755 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2756 llvm::Value *
Result = Builder.CreateInsertVector(
2757 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2759 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2760 if (
Result->getType() != ScalableDstTy)
2762 if (
Result->getType() != DstTy)
2772 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2773 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2776 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2777 FixedDstTy->getElementType()->isIntegerTy(8)) {
2778 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2779 ScalableSrcTy = llvm::ScalableVectorType::get(
2780 ScalableSrcTy->getElementType(),
2782 ScalableSrcTy->getElementCount().getKnownMinValue()));
2783 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2784 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2788 ScalableSrcTy = llvm::ScalableVectorType::get(
2789 FixedDstTy->getElementType(),
2790 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2791 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2793 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2794 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2815 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2818 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2821 case CK_AddressSpaceConversion: {
2822 llvm::Type *DestLTy = ConvertType(DestTy);
2825 auto IsWasmFuncref = [](llvm::Type *
T) {
2826 auto *TET = dyn_cast<llvm::TargetExtType>(
T);
2827 return TET && TET->getName() ==
"wasm.funcref";
2829 bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->
getType()));
2830 bool DestIsFuncref = IsWasmFuncref(DestLTy);
2831 if (SrcIsFuncref && DestIsFuncref) {
2836 if (SrcIsFuncref && !DestIsFuncref) {
2840 llvm::Function *ToPtr =
2842 return CGF.
Builder.CreateCall(ToPtr, {Visit(E)});
2844 if (!SrcIsFuncref && DestIsFuncref) {
2847 Expr::EvalResult NullResult;
2852 return llvm::Constant::getNullValue(DestLTy);
2855 llvm::Function *ToFuncref =
2857 return CGF.
Builder.CreateCall(ToFuncref, {Visit(E)});
2861 Result.Val.isNullPointer()) {
2865 if (
Result.HasSideEffects)
2873 case CK_AtomicToNonAtomic:
2874 case CK_NonAtomicToAtomic:
2875 case CK_UserDefinedConversion:
2882 case CK_BaseToDerived: {
2884 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2898 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2906 case CK_UncheckedDerivedToBase:
2907 case CK_DerivedToBase: {
2920 case CK_ArrayToPointerDecay:
2923 case CK_FunctionToPointerDecay:
2924 return EmitLValue(E).getPointer(CGF);
2926 case CK_NullToPointer:
2927 if (MustVisitNullValue(E))
2933 case CK_NullToMemberPointer: {
2934 if (MustVisitNullValue(E))
2937 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2941 case CK_ReinterpretMemberPointer:
2942 case CK_BaseToDerivedMemberPointer:
2943 case CK_DerivedToBaseMemberPointer: {
2944 Value *Src = Visit(E);
2955 case CK_ARCProduceObject:
2957 case CK_ARCConsumeObject:
2959 case CK_ARCReclaimReturnedObject:
2961 case CK_ARCExtendBlockObject:
2964 case CK_CopyAndAutoreleaseBlockObject:
2967 case CK_FloatingRealToComplex:
2968 case CK_FloatingComplexCast:
2969 case CK_IntegralRealToComplex:
2970 case CK_IntegralComplexCast:
2971 case CK_IntegralComplexToFloatingComplex:
2972 case CK_FloatingComplexToIntegralComplex:
2973 case CK_ConstructorConversion:
2975 case CK_HLSLArrayRValue:
2976 llvm_unreachable(
"scalar cast to non-scalar value");
2978 case CK_LValueToRValue:
2980 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2983 case CK_IntegralToPointer: {
2984 Value *Src = Visit(E);
2988 auto DestLLVMTy = ConvertType(DestTy);
2991 llvm::Value* IntResult =
2992 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2994 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
3000 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
3006 case CK_PointerToIntegral: {
3007 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
3010 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3016 case CK_MatrixCast: {
3017 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3024 case CK_HLSLAggregateSplatCast:
3025 case CK_VectorSplat: {
3026 llvm::Type *DstTy = ConvertType(DestTy);
3027 Value *Elt = Visit(E);
3029 llvm::ElementCount NumElements =
3031 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3034 case CK_FixedPointCast:
3035 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3038 case CK_FixedPointToBoolean:
3040 "Expected src type to be fixed point type");
3041 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3042 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3045 case CK_FixedPointToIntegral:
3047 "Expected src type to be fixed point type");
3048 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3049 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3052 case CK_IntegralToFixedPoint:
3054 "Expected src type to be an integer");
3056 "Expected dest type to be fixed point type");
3057 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3060 case CK_IntegralCast: {
3062 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3063 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3067 ScalarConversionOpts Opts;
3068 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3069 if (!ICE->isPartOfExplicitCast())
3070 Opts = ScalarConversionOpts(CGF.
SanOpts);
3072 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3075 case CK_IntegralToFloating: {
3078 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3080 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3081 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3083 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3084 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3087 case CK_FloatingToIntegral: {
3090 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3092 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3093 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3095 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3096 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3099 case CK_FloatingCast: {
3102 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3103 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3104 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3105 SrcElTy->
castAs<BuiltinType>()->getKind())
3106 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3107 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3109 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3110 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3113 case CK_FixedPointToFloating:
3114 case CK_FloatingToFixedPoint: {
3115 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3116 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3119 case CK_BooleanToSignedIntegral: {
3120 ScalarConversionOpts Opts;
3121 Opts.TreatBooleanAsSigned =
true;
3122 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3125 case CK_IntegralToBoolean:
3126 return EmitIntToBoolConversion(Visit(E));
3127 case CK_PointerToBoolean:
3128 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3129 case CK_FloatingToBoolean: {
3130 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3131 return EmitFloatToBoolConversion(Visit(E));
3133 case CK_MemberPointerToBoolean: {
3134 llvm::Value *MemPtr = Visit(E);
3135 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3139 case CK_FloatingComplexToReal:
3140 case CK_IntegralComplexToReal:
3143 case CK_FloatingComplexToBoolean:
3144 case CK_IntegralComplexToBoolean: {
3148 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3152 case CK_ZeroToOCLOpaqueType: {
3155 "CK_ZeroToOCLEvent cast on non-event type");
3156 return llvm::Constant::getNullValue(ConvertType(DestTy));
3159 case CK_IntToOCLSampler:
3162 case CK_HLSLVectorTruncation: {
3164 "Destination type must be a vector or builtin type.");
3165 Value *Vec = Visit(E);
3166 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3167 SmallVector<int> Mask;
3168 unsigned NumElts = VecTy->getNumElements();
3169 for (
unsigned I = 0; I != NumElts; ++I)
3172 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3174 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3175 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3177 case CK_HLSLMatrixTruncation: {
3179 "Destination type must be a matrix or builtin type.");
3180 Value *Mat = Visit(E);
3181 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3182 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3183 unsigned NumCols = MatTy->getNumColumns();
3184 unsigned NumRows = MatTy->getNumRows();
3185 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3186 assert(SrcMatTy &&
"Source type must be a matrix type.");
3187 assert(NumRows <= SrcMatTy->getNumRows());
3188 assert(NumCols <= SrcMatTy->getNumColumns());
3190 for (
unsigned R = 0;
R < NumRows;
R++)
3191 for (
unsigned C = 0;
C < NumCols;
C++)
3192 Mask[MatTy->getColumnMajorFlattenedIndex(R,
C)] =
3193 SrcMatTy->getColumnMajorFlattenedIndex(R,
C);
3195 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3197 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3198 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3200 case CK_HLSLElementwiseCast: {
3204 if (
const auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>()) {
3206 "Matrix elementwise cast destination must be a vector");
3207 assert(RV.
isScalar() &&
"Matrix rvalue must have scalar representation");
3210 CGF, DestTy, SrcMatTy->getNumElementsFlattened(),
3212 unsigned Row = I / SrcMatTy->getNumColumns();
3213 unsigned Col = I % SrcMatTy->getNumColumns();
3214 unsigned Idx = SrcMatTy->getColumnMajorFlattenedIndex(Row, Col);
3216 Builder.CreateExtractElement(SrcVal, Idx,
"matrixext");
3217 return std::pair(Element, SrcMatTy->getElementType());
3238 llvm_unreachable(
"unknown scalar cast");
3241Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3242 CodeGenFunction::StmtExprEvaluation eval(CGF);
3251Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3252 CodeGenFunction::RunCleanupsScope Scope(CGF);
3256 Scope.ForceCleanup({&
V});
3265 llvm::Value *InVal,
bool IsInc,
3269 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3271 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3272 BinOp.FPFeatures = FPFeatures;
3277llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3278 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3281 llvm::Value *Amount =
3282 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3283 StringRef Name = IsInc ?
"inc" :
"dec";
3287 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3288 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3290 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3291 case LangOptions::OB_Wrap:
3292 return Builder.CreateAdd(InVal, Amount, Name);
3293 case LangOptions::OB_SignedAndDefined:
3295 return Builder.CreateAdd(InVal, Amount, Name);
3297 case LangOptions::OB_Unset:
3299 return Builder.CreateAdd(InVal, Amount, Name);
3301 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3302 : Builder.CreateAdd(InVal, Amount, Name);
3304 case LangOptions::OB_Trap:
3306 return Builder.CreateAdd(InVal, Amount, Name);
3309 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3310 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3311 : Builder.CreateAdd(InVal, Amount, Name);
3312 return EmitOverflowCheckedBinOp(Info);
3314 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3319class OMPLastprivateConditionalUpdateRAII {
3321 CodeGenFunction &CGF;
3322 const UnaryOperator *E;
3325 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3326 const UnaryOperator *E)
3328 ~OMPLastprivateConditionalUpdateRAII() {
3337ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3338 bool isInc,
bool isPre) {
3340 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3342 llvm::PHINode *atomicPHI =
nullptr;
3346 QualType SrcType = E->
getType();
3348 int amount = (isInc ? 1 : -1);
3349 bool isSubtraction = !isInc;
3351 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3352 type = atomicTy->getValueType();
3353 if (isInc &&
type->isBooleanType()) {
3356 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3357 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3358 return Builder.getTrue();
3362 return Builder.CreateAtomicRMW(
3363 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3364 llvm::AtomicOrdering::SequentiallyConsistent);
3369 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3370 !(
type->isUnsignedIntegerType() &&
3371 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3373 LangOptions::SOB_Trapping) {
3374 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3375 llvm::AtomicRMWInst::Sub;
3376 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3377 llvm::Instruction::Sub;
3379 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3381 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3382 llvm::AtomicOrdering::SequentiallyConsistent);
3383 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3387 if (
type->isFloatingType()) {
3388 llvm::Type *Ty = ConvertType(
type);
3389 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3390 llvm::AtomicRMWInst::BinOp aop =
3391 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3392 llvm::Instruction::BinaryOps op =
3393 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3394 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3395 llvm::AtomicRMWInst *old =
3397 llvm::AtomicOrdering::SequentiallyConsistent);
3399 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3402 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3405 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3408 Builder.CreateBr(opBB);
3409 Builder.SetInsertPoint(opBB);
3410 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3411 atomicPHI->addIncoming(value, startBB);
3414 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3425 if (isInc &&
type->isBooleanType()) {
3426 value = Builder.getTrue();
3429 }
else if (
type->isIntegerType()) {
3430 QualType promotedType;
3431 bool canPerformLossyDemotionCheck =
false;
3435 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3436 canPerformLossyDemotionCheck =
true;
3437 canPerformLossyDemotionCheck &=
3440 canPerformLossyDemotionCheck &=
3442 type, promotedType);
3443 assert((!canPerformLossyDemotionCheck ||
3444 type->isSignedIntegerOrEnumerationType() ||
3446 ConvertType(
type)->getScalarSizeInBits() ==
3447 ConvertType(promotedType)->getScalarSizeInBits()) &&
3448 "The following check expects that if we do promotion to different "
3449 "underlying canonical type, at least one of the types (either "
3450 "base or promoted) will be signed, or the bitwidths will match.");
3453 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3454 SanitizerKind::ImplicitBitfieldConversion) &&
3455 canPerformLossyDemotionCheck) {
3469 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3470 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3471 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3475 ScalarConversionOpts Opts;
3476 if (!LV.isBitField())
3477 Opts = ScalarConversionOpts(CGF.
SanOpts);
3478 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3480 SrcType = promotedType;
3484 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3490 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3491 type->isUnsignedIntegerType()) {
3492 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3497 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3498 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3502 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3503 QualType
type = ptr->getPointeeType();
3506 if (
const VariableArrayType *vla
3509 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3512 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3515 elemTy, value, numElts,
false, isSubtraction,
3519 }
else if (
type->isFunctionType()) {
3520 llvm::Value *amt = Builder.getInt32(amount);
3523 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3527 false, isSubtraction,
3532 llvm::Value *amt = Builder.getInt32(amount);
3535 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3538 elemTy, value, amt,
false, isSubtraction,
3543 }
else if (
type->isVectorType()) {
3544 if (
type->hasIntegerRepresentation()) {
3545 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3547 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3549 value = Builder.CreateFAdd(
3551 llvm::ConstantFP::get(value->getType(), amount),
3552 isInc ?
"inc" :
"dec");
3556 }
else if (
type->isRealFloatingType()) {
3559 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3563 value = Builder.CreateFPExt(value, CGF.
CGM.
FloatTy,
"incdec.conv");
3565 if (value->getType()->isFloatTy())
3566 amt = llvm::ConstantFP::get(VMContext,
3567 llvm::APFloat(
static_cast<float>(amount)));
3568 else if (value->getType()->isDoubleTy())
3569 amt = llvm::ConstantFP::get(VMContext,
3570 llvm::APFloat(
static_cast<double>(amount)));
3574 llvm::APFloat F(
static_cast<float>(amount));
3576 const llvm::fltSemantics *FS;
3579 if (value->getType()->isFP128Ty())
3581 else if (value->getType()->isHalfTy())
3583 else if (value->getType()->isBFloatTy())
3585 else if (value->getType()->isPPC_FP128Ty())
3589 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3590 amt = llvm::ConstantFP::get(VMContext, F);
3592 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3595 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3598 }
else if (
type->isFixedPointType()) {
3605 Info.Opcode = isInc ? BO_Add : BO_Sub;
3607 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3610 if (
type->isSignedFixedPointType()) {
3611 Info.Opcode = isInc ? BO_Sub : BO_Add;
3612 Info.RHS = Builder.CreateNeg(Info.RHS);
3617 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3619 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3620 value = EmitFixedPointBinOp(Info);
3624 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3627 if (!isInc) size = -size;
3628 llvm::Value *sizeValue =
3629 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3632 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3635 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3637 value = Builder.CreateBitCast(value, input->getType());
3641 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3646 llvm::Value *
success = Pair.second;
3647 atomicPHI->addIncoming(old, curBlock);
3648 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3649 Builder.SetInsertPoint(contBB);
3650 return isPre ? value : input;
3654 if (LV.isBitField()) {
3664 return isPre ? value : input;
3668Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3669 QualType PromotionType) {
3670 QualType promotionTy = PromotionType.
isNull()
3673 Value *result = VisitPlus(E, promotionTy);
3674 if (result && !promotionTy.
isNull())
3675 result = EmitUnPromotedValue(result, E->
getType());
3679Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3680 QualType PromotionType) {
3682 TestAndClearIgnoreResultAssign();
3683 if (!PromotionType.
isNull())
3688Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3689 QualType PromotionType) {
3690 QualType promotionTy = PromotionType.
isNull()
3693 Value *result = VisitMinus(E, promotionTy);
3694 if (result && !promotionTy.
isNull())
3695 result = EmitUnPromotedValue(result, E->
getType());
3699Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3700 QualType PromotionType) {
3701 TestAndClearIgnoreResultAssign();
3703 if (!PromotionType.
isNull())
3709 if (Op->
getType()->isFPOrFPVectorTy()) {
3710 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3711 return Builder.CreateFNeg(Op,
"fneg");
3717 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3719 BinOp.Opcode = BO_Sub;
3722 return EmitSub(BinOp);
3725Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3726 TestAndClearIgnoreResultAssign();
3728 return Builder.CreateNot(Op,
"not");
3731Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3735 VectorKind::Generic) {
3739 if (Oper->
getType()->isFPOrFPVectorTy()) {
3740 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3742 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3744 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3745 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3754 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3757 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3760Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3762 Expr::EvalResult EVResult;
3765 return Builder.getInt(
Value);
3770 llvm::Type* ResultType = ConvertType(E->
getType());
3771 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3773 for (
unsigned i = 0; i != n; ++i) {
3775 llvm::Value *Offset =
nullptr;
3782 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3789 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3793 Offset = Builder.CreateMul(Idx, ElemSize);
3798 FieldDecl *MemberDecl = ON.
getField();
3808 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3811 CurrentType = MemberDecl->
getType();
3816 llvm_unreachable(
"dependent __builtin_offsetof");
3833 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3845ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3846 const UnaryExprOrTypeTraitExpr *E) {
3849 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3850 if (
const VariableArrayType *VAT =
3855 bool EvaluateExtent =
true;
3856 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3858 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3860 if (EvaluateExtent) {
3871 if (Kind == UETT_CountOf)
3880 if (!eltSize.
isOne())
3883 return VlaSize.NumElts;
3886 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3892 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3893 }
else if (E->
getKind() == UETT_VectorElements) {
3895 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3903Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3904 QualType PromotionType) {
3905 QualType promotionTy = PromotionType.
isNull()
3908 Value *result = VisitReal(E, promotionTy);
3909 if (result && !promotionTy.
isNull())
3910 result = EmitUnPromotedValue(result, E->
getType());
3914Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3915 QualType PromotionType) {
3922 if (!PromotionType.
isNull()) {
3924 Op, IgnoreResultAssign,
true);
3939 if (!PromotionType.
isNull())
3944Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3945 QualType PromotionType) {
3946 QualType promotionTy = PromotionType.
isNull()
3949 Value *result = VisitImag(E, promotionTy);
3950 if (result && !promotionTy.
isNull())
3951 result = EmitUnPromotedValue(result, E->
getType());
3955Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3956 QualType PromotionType) {
3963 if (!PromotionType.
isNull()) {
3965 Op,
true, IgnoreResultAssign);
3969 return result.second
3985 else if (!PromotionType.
isNull())
3989 if (!PromotionType.
isNull())
3990 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3991 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3998Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3999 QualType PromotionType) {
4000 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
4003Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
4004 QualType ExprType) {
4005 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
4008Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
4010 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
4012#define HANDLE_BINOP(OP) \
4014 return Emit##OP(EmitBinOps(BO, PromotionType));
4023 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4026 return VisitImag(UO, PromotionType);
4028 return VisitReal(UO, PromotionType);
4030 return VisitMinus(UO, PromotionType);
4032 return VisitPlus(UO, PromotionType);
4037 auto result = Visit(
const_cast<Expr *
>(E));
4039 if (!PromotionType.
isNull())
4040 return EmitPromotedValue(result, PromotionType);
4042 return EmitUnPromotedValue(result, E->
getType());
4047BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4048 QualType PromotionType) {
4049 TestAndClearIgnoreResultAssign();
4053 if (!PromotionType.
isNull())
4054 Result.Ty = PromotionType;
4063LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4064 const CompoundAssignOperator *E,
4065 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4076 QualType PromotionTypeCR;
4078 if (PromotionTypeCR.
isNull())
4081 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4082 if (!PromotionTypeRHS.
isNull())
4085 OpInfo.RHS = Visit(E->
getRHS());
4086 OpInfo.Ty = PromotionTypeCR;
4093 llvm::PHINode *atomicPHI =
nullptr;
4094 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4096 QualType AtomicValueTy = atomicTy->getValueType();
4105 bool CanEmitAtomicRMW;
4107 llvm::Type *IRTy = CGF.
ConvertType(AtomicValueTy);
4111 !OpInfo.FPFeatures.isFPConstrained() &&
4113 llvm::isPowerOf2_64(StoreBits);
4119 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4121 LangOptions::SOB_Trapping;
4123 if (CanEmitAtomicRMW) {
4124 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4125 llvm::Instruction::BinaryOps Op;
4127 switch (OpInfo.Opcode) {
4129 AtomicOp = llvm::AtomicRMWInst::FAdd;
4130 Op = llvm::Instruction::FAdd;
4133 AtomicOp = llvm::AtomicRMWInst::FSub;
4134 Op = llvm::Instruction::FSub;
4140 switch (OpInfo.Opcode) {
4142 case BO_MulAssign:
case BO_DivAssign:
4148 AtomicOp = llvm::AtomicRMWInst::Add;
4149 Op = llvm::Instruction::Add;
4152 AtomicOp = llvm::AtomicRMWInst::Sub;
4153 Op = llvm::Instruction::Sub;
4156 AtomicOp = llvm::AtomicRMWInst::And;
4157 Op = llvm::Instruction::And;
4160 AtomicOp = llvm::AtomicRMWInst::Xor;
4161 Op = llvm::Instruction::Xor;
4164 AtomicOp = llvm::AtomicRMWInst::Or;
4165 Op = llvm::Instruction::Or;
4168 llvm_unreachable(
"Invalid compound assignment type");
4171 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4173 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4177 llvm::AtomicRMWInst *OldVal =
4182 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4188 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4190 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4191 OpInfo.LHS = CGF.
EmitToMemory(OpInfo.LHS, AtomicValueTy);
4192 Builder.CreateBr(opBB);
4193 Builder.SetInsertPoint(opBB);
4194 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4195 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4196 OpInfo.LHS = atomicPHI;
4199 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4201 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4203 if (!PromotionTypeLHS.
isNull())
4204 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4207 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4218 if (LHSLV.isBitField()) {
4220 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4221 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4223 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4224 Loc, ScalarConversionOpts(CGF.
SanOpts));
4226 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4227 ScalarConversionOpts(CGF.
SanOpts));
4231 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4235 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4236 llvm::Value *
success = Pair.second;
4237 atomicPHI->addIncoming(old, curBlock);
4238 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4239 Builder.SetInsertPoint(contBB);
4247 if (LHSLV.isBitField()) {
4263Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4264 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4265 bool Ignore = TestAndClearIgnoreResultAssign();
4266 Value *RHS =
nullptr;
4267 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4278 if (!LHS.isVolatileQualified())
4282 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4285void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4286 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4287 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4290 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4291 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4292 SanitizerKind::SO_IntegerDivideByZero));
4296 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4297 Ops.Ty->hasSignedIntegerRepresentation() &&
4299 Ops.mayHaveIntegerOverflow() &&
4301 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4304 llvm::Value *IntMin =
4305 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4306 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4308 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4309 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4310 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4312 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4315 if (Checks.size() > 0)
4316 EmitBinOpCheck(Checks, Ops);
4319Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4321 SanitizerDebugLocation SanScope(&CGF,
4322 {SanitizerKind::SO_IntegerDivideByZero,
4323 SanitizerKind::SO_SignedIntegerOverflow,
4324 SanitizerKind::SO_FloatDivideByZero},
4325 SanitizerHandler::DivremOverflow);
4326 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4327 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4328 Ops.Ty->isIntegerType() &&
4329 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4330 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4331 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4332 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4333 Ops.Ty->isRealFloatingType() &&
4334 Ops.mayHaveFloatDivisionByZero()) {
4335 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4336 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4338 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4342 if (Ops.Ty->isConstantMatrixType()) {
4343 llvm::MatrixBuilder MB(Builder);
4350 "first operand must be a matrix");
4352 "second operand must be an arithmetic type");
4353 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4354 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4355 Ops.Ty->hasUnsignedIntegerRepresentation());
4358 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4360 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4361 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4365 else if (Ops.isFixedPointOp())
4366 return EmitFixedPointBinOp(Ops);
4367 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4368 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4370 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4373Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4375 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4376 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4377 Ops.Ty->isIntegerType() &&
4378 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4379 SanitizerDebugLocation SanScope(&CGF,
4380 {SanitizerKind::SO_IntegerDivideByZero,
4381 SanitizerKind::SO_SignedIntegerOverflow},
4382 SanitizerHandler::DivremOverflow);
4383 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4384 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4387 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4388 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4390 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4391 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4393 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4396Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4401 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4402 switch (Ops.Opcode) {
4406 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4407 llvm::Intrinsic::uadd_with_overflow;
4408 OverflowKind = SanitizerHandler::AddOverflow;
4413 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4414 llvm::Intrinsic::usub_with_overflow;
4415 OverflowKind = SanitizerHandler::SubOverflow;
4420 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4421 llvm::Intrinsic::umul_with_overflow;
4422 OverflowKind = SanitizerHandler::MulOverflow;
4425 llvm_unreachable(
"Unsupported operation for overflow detection");
4431 SanitizerDebugLocation SanScope(&CGF,
4432 {SanitizerKind::SO_SignedIntegerOverflow,
4433 SanitizerKind::SO_UnsignedIntegerOverflow},
4439 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4440 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4441 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4444 const std::string *handlerName =
4446 if (handlerName->empty()) {
4452 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4453 llvm::Value *NotOf = Builder.CreateNot(overflow);
4455 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4458 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4461 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4462 llvm::Value *NotOf = Builder.CreateNot(overflow);
4464 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4467 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4472 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4473 llvm::BasicBlock *continueBB =
4477 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4481 Builder.SetInsertPoint(overflowBB);
4487 llvm::FunctionCallee handler =
4492 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4493 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4497 llvm::Value *handlerArgs[] = {
4500 Builder.getInt8(OpID),
4503 llvm::Value *handlerResult =
4507 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4508 Builder.CreateBr(continueBB);
4510 Builder.SetInsertPoint(continueBB);
4511 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4512 phi->addIncoming(result, initialBB);
4513 phi->addIncoming(handlerResult, overflowBB);
4522 bool isSubtraction) {
4527 Value *pointer = op.LHS;
4528 Expr *pointerOperand =
expr->getLHS();
4530 Expr *indexOperand =
expr->getRHS();
4533 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4534 std::swap(pointer,
index);
4535 std::swap(pointerOperand, indexOperand);
4539 index, isSubtraction);
4545 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4549 auto &DL =
CGM.getDataLayout();
4572 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4574 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4575 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4576 PtrTy->getPointerAddressSpace()))
4579 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4580 auto CheckHandler = SanitizerHandler::PointerOverflow;
4582 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4584 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4585 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4587 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4588 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4593 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4604 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4614 llvm::Value *objectSize =
4620 return Builder.CreateBitCast(result, pointer->getType());
4625 getContext().getAsVariableArrayType(elementType)) {
4627 llvm::Value *numElements =
getVLASize(vla).NumElts;
4636 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4656 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4669 bool negMul,
bool negAdd) {
4670 Value *MulOp0 = MulOp->getOperand(0);
4671 Value *MulOp1 = MulOp->getOperand(1);
4673 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4675 Addend = Builder.CreateFNeg(Addend,
"neg");
4677 Value *FMulAdd =
nullptr;
4678 if (Builder.getIsFPConstrained()) {
4680 "Only constrained operation should be created when Builder is in FP "
4681 "constrained mode");
4682 FMulAdd = Builder.CreateConstrainedFPCall(
4683 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4685 {MulOp0, MulOp1, Addend});
4687 FMulAdd = Builder.CreateCall(
4689 {MulOp0, MulOp1, Addend});
4691 MulOp->eraseFromParent();
4706 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4707 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4708 "Only fadd/fsub can be the root of an fmuladd.");
4711 if (!op.FPFeatures.allowFPContractWithinStatement())
4714 Value *LHS = op.LHS;
4715 Value *RHS = op.RHS;
4719 bool NegLHS =
false;
4720 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4721 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4722 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4723 LHS = LHSUnOp->getOperand(0);
4728 bool NegRHS =
false;
4729 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4730 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4731 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4732 RHS = RHSUnOp->getOperand(0);
4740 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4741 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4742 (LHSBinOp->use_empty() || NegLHS)) {
4746 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4749 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4750 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4751 (RHSBinOp->use_empty() || NegRHS)) {
4755 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4759 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4760 if (LHSBinOp->getIntrinsicID() ==
4761 llvm::Intrinsic::experimental_constrained_fmul &&
4762 (LHSBinOp->use_empty() || NegLHS)) {
4766 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4769 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4770 if (RHSBinOp->getIntrinsicID() ==
4771 llvm::Intrinsic::experimental_constrained_fmul &&
4772 (RHSBinOp->use_empty() || NegRHS)) {
4776 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4783Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4784 if (op.LHS->getType()->isPointerTy() ||
4785 op.RHS->getType()->isPointerTy())
4788 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4789 op.Ty->isUnsignedIntegerType()) {
4790 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4792 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4793 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4794 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4795 case LangOptions::OB_Wrap:
4796 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4797 case LangOptions::OB_SignedAndDefined:
4799 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4801 case LangOptions::OB_Unset:
4803 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4804 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4806 case LangOptions::OB_Trap:
4807 if (CanElideOverflowCheck(CGF.
getContext(), op))
4808 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4809 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4810 return EmitOverflowCheckedBinOp(op);
4815 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4816 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4822 if (op.Ty->isConstantMatrixType()) {
4823 llvm::MatrixBuilder MB(Builder);
4824 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4825 return MB.CreateAdd(op.LHS, op.RHS);
4828 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4829 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4830 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4833 if (op.isFixedPointOp())
4834 return EmitFixedPointBinOp(op);
4836 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4841Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4843 using llvm::ConstantInt;
4849 QualType ResultTy = op.Ty;
4850 QualType LHSTy, RHSTy;
4851 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4852 RHSTy = BinOp->getRHS()->getType();
4853 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4858 LHSTy = CAO->getComputationLHSType();
4859 ResultTy = CAO->getComputationResultType();
4861 LHSTy = BinOp->getLHS()->getType();
4862 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4863 LHSTy = UnOp->getSubExpr()->getType();
4864 RHSTy = UnOp->getSubExpr()->getType();
4867 Value *LHS = op.LHS;
4868 Value *RHS = op.RHS;
4873 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4877 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4878 switch (op.Opcode) {
4881 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4885 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4889 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4893 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4897 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4901 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4904 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4906 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4908 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4910 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4915 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4917 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4921 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4934 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4940 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4945Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4947 if (!op.LHS->getType()->isPointerTy()) {
4948 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4949 op.Ty->isUnsignedIntegerType()) {
4950 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4952 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4953 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4954 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4955 case LangOptions::OB_Wrap:
4956 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4957 case LangOptions::OB_SignedAndDefined:
4959 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4961 case LangOptions::OB_Unset:
4963 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4964 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4966 case LangOptions::OB_Trap:
4967 if (CanElideOverflowCheck(CGF.
getContext(), op))
4968 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4969 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4970 return EmitOverflowCheckedBinOp(op);
4975 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4976 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4982 if (op.Ty->isConstantMatrixType()) {
4983 llvm::MatrixBuilder MB(Builder);
4984 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4985 return MB.CreateSub(op.LHS, op.RHS);
4988 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4989 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4990 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4993 if (op.isFixedPointOp())
4994 return EmitFixedPointBinOp(op);
4996 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
5001 if (!op.RHS->getType()->isPointerTy())
5011 LHS = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
5012 RHS = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
5014 LHS = Builder.CreatePtrToAddr(op.LHS,
"sub.ptr.lhs.cast");
5015 RHS = Builder.CreatePtrToAddr(op.RHS,
"sub.ptr.rhs.cast");
5017 LHS = Builder.CreateZExtOrTrunc(LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5019 RHS = Builder.CreateZExtOrTrunc(RHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5021 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
5025 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
5027 llvm::Value *divisor =
nullptr;
5030 if (
const VariableArrayType *vla
5033 elementType = VlaSize.Type;
5034 divisor = VlaSize.NumElts;
5038 if (!eltSize.
isOne())
5045 CharUnits elementSize;
5054 if (elementSize.
isOne())
5061 return Builder.CreateSDiv(diffInChars, divisor,
"sub.ptr.div");
5065 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5068Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5070 llvm::IntegerType *Ty;
5071 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5079 llvm::Type *RHSTy = RHS->
getType();
5080 llvm::APInt RHSMax =
5081 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5082 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5083 if (RHSMax.ult(Ty->getBitWidth()))
5084 return llvm::ConstantInt::get(RHSTy, RHSMax);
5085 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5089 const Twine &Name) {
5090 llvm::IntegerType *Ty;
5091 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5096 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5097 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5099 return Builder.CreateURem(
5100 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5103Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5105 if (Ops.isFixedPointOp())
5106 return EmitFixedPointBinOp(Ops);
5110 Value *RHS = Ops.RHS;
5111 if (Ops.LHS->getType() != RHS->
getType())
5112 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5114 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5115 Ops.Ty->hasSignedIntegerRepresentation() &&
5118 bool SanitizeUnsignedBase =
5119 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5120 Ops.Ty->hasUnsignedIntegerRepresentation();
5121 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5122 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5125 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5126 else if ((SanitizeBase || SanitizeExponent) &&
5128 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5129 if (SanitizeSignedBase)
5130 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5131 if (SanitizeUnsignedBase)
5132 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5133 if (SanitizeExponent)
5134 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5136 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5137 SanitizerHandler::ShiftOutOfBounds);
5138 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5139 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5140 llvm::Value *WidthMinusOne =
5141 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5142 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5144 if (SanitizeExponent) {
5146 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5153 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5156 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5157 llvm::Value *PromotedWidthMinusOne =
5158 (RHS == Ops.RHS) ? WidthMinusOne
5159 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5161 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5162 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5171 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5172 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5174 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5175 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5177 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5178 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5179 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5180 Checks.push_back(std::make_pair(
5181 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5182 : SanitizerKind::SO_UnsignedShiftBase));
5185 assert(!Checks.empty());
5186 EmitBinOpCheck(Checks, Ops);
5189 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5192Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5194 if (Ops.isFixedPointOp())
5195 return EmitFixedPointBinOp(Ops);
5199 Value *RHS = Ops.RHS;
5200 if (Ops.LHS->getType() != RHS->
getType())
5201 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5205 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5206 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5208 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5209 SanitizerHandler::ShiftOutOfBounds);
5210 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5211 llvm::Value *
Valid = Builder.CreateICmpULE(
5212 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5213 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5216 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5217 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5218 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5226 default: llvm_unreachable(
"unexpected element type");
5227 case BuiltinType::Char_U:
5228 case BuiltinType::UChar:
5229 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5230 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5231 case BuiltinType::Char_S:
5232 case BuiltinType::SChar:
5233 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5234 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5235 case BuiltinType::UShort:
5236 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5237 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5238 case BuiltinType::Short:
5239 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5240 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5241 case BuiltinType::UInt:
5242 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5243 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5244 case BuiltinType::Int:
5245 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5246 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5247 case BuiltinType::ULong:
5248 case BuiltinType::ULongLong:
5249 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5250 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5251 case BuiltinType::Long:
5252 case BuiltinType::LongLong:
5253 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5254 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5255 case BuiltinType::Float:
5256 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5257 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5258 case BuiltinType::Double:
5259 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5260 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5261 case BuiltinType::UInt128:
5262 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5263 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5264 case BuiltinType::Int128:
5265 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5266 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5270Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5271 llvm::CmpInst::Predicate UICmpOpc,
5272 llvm::CmpInst::Predicate SICmpOpc,
5273 llvm::CmpInst::Predicate FCmpOpc,
5275 TestAndClearIgnoreResultAssign();
5279 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5285 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5287 BinOpInfo BOInfo = EmitBinOps(E);
5288 Value *LHS = BOInfo.LHS;
5289 Value *RHS = BOInfo.RHS;
5295 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5297 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5300 Value *FirstVecArg = LHS,
5301 *SecondVecArg = RHS;
5303 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5307 default: llvm_unreachable(
"is not a comparison operation");
5319 std::swap(FirstVecArg, SecondVecArg);
5326 if (ElementKind == BuiltinType::Float) {
5328 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5329 std::swap(FirstVecArg, SecondVecArg);
5337 if (ElementKind == BuiltinType::Float) {
5339 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5344 std::swap(FirstVecArg, SecondVecArg);
5349 Value *CR6Param = Builder.getInt32(CR6);
5351 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5359 if (ResultTy->getBitWidth() > 1 &&
5361 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5366 if (BOInfo.isFixedPointOp()) {
5367 Result = EmitFixedPointBinOp(BOInfo);
5368 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5369 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5371 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5373 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5375 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5378 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5384 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5393 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5395 CETy = CTy->getElementType();
5397 LHS.first = Visit(E->
getLHS());
5398 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5401 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5404 CTy->getElementType()) &&
5405 "The element types must always match.");
5408 RHS.first = Visit(E->
getRHS());
5409 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5411 "The element types must always match.");
5414 Value *ResultR, *ResultI;
5418 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5419 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5423 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5424 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5428 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5431 "Complex comparison other than == or != ?");
5432 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5444 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5445 CastKind Kind = ICE->getCastKind();
5446 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5447 *SrcType = ICE->getSubExpr()->getType();
5460 bool Ignore = TestAndClearIgnoreResultAssign();
5494 RHS = Visit(E->
getRHS());
5510 RHS = Visit(E->
getRHS());
5550 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5553Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5564 if (LHS->
getType()->isFPOrFPVectorTy()) {
5565 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5567 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5568 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5570 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5571 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5573 Value *
And = Builder.CreateAnd(LHS, RHS);
5574 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5578 llvm::Type *ResTy = ConvertType(E->
getType());
5597 if (InstrumentRegions &&
5601 llvm::BasicBlock *RHSSkip =
5604 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5621 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5632 return llvm::Constant::getNullValue(ResTy);
5643 llvm::BasicBlock *LHSFalseBlock =
5646 CodeGenFunction::ConditionalEvaluation eval(CGF);
5661 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5663 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5665 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5674 RHSBlock = Builder.GetInsertBlock();
5679 llvm::BasicBlock *ContIncoming = RHSBlock;
5680 if (InstrumentRegions &&
5684 llvm::BasicBlock *RHSBlockSkip =
5686 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5690 PN->addIncoming(RHSCond, RHSBlockCnt);
5695 ContIncoming = RHSBlockSkip;
5706 PN->addIncoming(RHSCond, ContIncoming);
5715 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5719 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5722Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5733 if (LHS->
getType()->isFPOrFPVectorTy()) {
5734 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5736 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5737 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5739 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5740 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5742 Value *
Or = Builder.CreateOr(LHS, RHS);
5743 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5747 llvm::Type *ResTy = ConvertType(E->
getType());
5766 if (InstrumentRegions &&
5770 llvm::BasicBlock *RHSSkip =
5773 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5790 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5801 return llvm::ConstantInt::get(ResTy, 1);
5811 llvm::BasicBlock *LHSTrueBlock =
5814 CodeGenFunction::ConditionalEvaluation eval(CGF);
5830 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5832 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5834 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5846 RHSBlock = Builder.GetInsertBlock();
5851 llvm::BasicBlock *ContIncoming = RHSBlock;
5852 if (InstrumentRegions &&
5856 llvm::BasicBlock *RHSTrueBlock =
5858 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5862 PN->addIncoming(RHSCond, RHSBlockCnt);
5867 ContIncoming = RHSTrueBlock;
5874 PN->addIncoming(RHSCond, ContIncoming);
5881 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5884Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5887 return Visit(E->
getRHS());
5894Value *ScalarExprEmitter::
5895VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5896 TestAndClearIgnoreResultAssign();
5899 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5901 Expr *condExpr = E->
getCond();
5909 Expr *live = lhsExpr, *dead = rhsExpr;
5910 if (!CondExprBool) std::swap(live, dead);
5937 llvm::Value *LHS = Visit(lhsExpr);
5938 llvm::Value *RHS = Visit(rhsExpr);
5940 llvm::Type *condType = ConvertType(condExpr->
getType());
5943 unsigned numElem = vecTy->getNumElements();
5944 llvm::Type *elemType = vecTy->getElementType();
5946 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5947 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5948 llvm::Value *tmp = Builder.CreateSExt(
5949 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5950 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5953 llvm::Value *RHSTmp = RHS;
5954 llvm::Value *LHSTmp = LHS;
5955 bool wasCast =
false;
5957 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5958 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5959 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5963 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5964 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5965 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5967 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5977 llvm::Value *LHS = Visit(lhsExpr);
5978 llvm::Value *RHS = Visit(rhsExpr);
5980 llvm::Type *CondType = ConvertType(condExpr->
getType());
5983 if (VecTy->getElementType()->isIntegerTy(1))
5984 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5987 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5989 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5991 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5992 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
6004 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
6008 llvm::Value *LHS = Visit(lhsExpr);
6009 llvm::Value *RHS = Visit(rhsExpr);
6012 assert(!RHS &&
"LHS and RHS types must match");
6015 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6026 CodeGenFunction::ConditionalEvaluation eval(CGF);
6040 Value *LHS = Visit(lhsExpr);
6043 LHSBlock = Builder.GetInsertBlock();
6044 Builder.CreateBr(ContBlock);
6056 Value *RHS = Visit(rhsExpr);
6059 RHSBlock = Builder.GetInsertBlock();
6069 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6070 PN->addIncoming(LHS, LHSBlock);
6071 PN->addIncoming(RHS, RHSBlock);
6076Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6080Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6082 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6087Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6093 Value *Src,
unsigned NumElementsDst) {
6094 static constexpr int Mask[] = {0, 1, 2, -1};
6095 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6115 const llvm::DataLayout &DL,
6116 Value *Src, llvm::Type *DstTy,
6117 StringRef Name =
"") {
6121 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6122 return Builder.CreateBitCast(Src, DstTy, Name);
6125 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6126 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6129 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6131 if (!DstTy->isIntegerTy())
6132 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6134 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6138 if (!SrcTy->isIntegerTy())
6139 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6141 return Builder.CreateIntToPtr(Src, DstTy, Name);
6144Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6146 llvm::Type *DstTy = ConvertType(E->
getType());
6148 llvm::Type *SrcTy = Src->
getType();
6149 unsigned NumElementsSrc =
6153 unsigned NumElementsDst =
6164 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6169 Src->setName(
"astype");
6176 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6177 auto *Vec4Ty = llvm::FixedVectorType::get(
6183 Src->setName(
"astype");
6188 Src, DstTy,
"astype");
6191Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6203 "Invalid scalar expression to emit");
6205 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6206 .Visit(
const_cast<Expr *
>(E));
6215 "Invalid scalar expression to emit");
6216 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6226 "Invalid complex -> scalar conversion");
6227 return ScalarExprEmitter(*
this)
6228 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6235 if (!PromotionType.
isNull())
6236 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6238 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6244 bool isInc,
bool isPre) {
6245 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6255 llvm::Type *BaseTy =
6271 ScalarExprEmitter Scalar(*
this);
6274#define COMPOUND_OP(Op) \
6275 case BO_##Op##Assign: \
6276 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6313 llvm_unreachable(
"Not valid compound assignment operators");
6316 llvm_unreachable(
"Unhandled compound assignment operator");
6337 llvm::Value *TotalOffset =
nullptr;
6339 auto *IntPtrTy = DL.getAddressType(BasePtr->
getType());
6342 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6343 auto *SAddIntrinsic =
6344 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6345 auto *SMulIntrinsic =
6346 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6349 llvm::Value *OffsetOverflows = Builder.getFalse();
6353 llvm::Value *RHS) -> llvm::Value * {
6354 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6357 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6358 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6360 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6363 OffsetOverflows = Builder.getTrue();
6364 return llvm::ConstantInt::get(VMContext, N);
6369 auto *ResultAndOverflow = Builder.CreateCall(
6370 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6371 OffsetOverflows = Builder.CreateOr(
6372 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6373 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6377 for (
auto GTI = llvm::gep_type_begin(ElemTy, IdxList),
6378 GTE = llvm::gep_type_end(ElemTy, IdxList);
6379 GTI != GTE; ++GTI) {
6380 llvm::Value *LocalOffset;
6381 auto *Index = GTI.getOperand();
6383 if (
auto *STy = GTI.getStructTypeOrNull()) {
6387 LocalOffset = llvm::ConstantInt::get(
6388 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6393 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6394 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6395 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6400 if (!TotalOffset || TotalOffset ==
Zero)
6401 TotalOffset = LocalOffset;
6403 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6406 return {TotalOffset, OffsetOverflows};
6411static llvm::GEPNoWrapFlags
6413 llvm::Type *SrcTy,
bool SignedIndices,
bool IsSubtraction) {
6414 llvm::GEPNoWrapFlags NW;
6415 bool SectionGEP = CGF.
getLangOpts().OpenMPIsTargetDevice &&
6416 SrcTy->isArrayTy() &&
6417 SrcTy->getArrayElementType()->isArrayTy() &&
6420 NW = llvm::GEPNoWrapFlags::inBounds();
6421 if (!SignedIndices && !IsSubtraction)
6422 NW |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6428 ArrayRef<Value *> IdxList,
6429 bool SignedIndices,
bool IsSubtraction,
6430 SourceLocation Loc,
const Twine &Name) {
6431 llvm::Type *PtrTy =
Ptr->getType();
6433 llvm::GEPNoWrapFlags NWFlags =
6436 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6439 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6443 bool PerformNullCheck = !NullPointerIsDefined(
6444 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6447 bool PerformOverflowCheck =
6450 if (!(PerformNullCheck || PerformOverflowCheck))
6453 const auto &DL = CGM.getDataLayout();
6455 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6456 auto CheckHandler = SanitizerHandler::PointerOverflow;
6457 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6458 llvm::Type *IntPtrTy = DL.getAddressType(PtrTy);
6461 Ptr, ElemTy, IdxList, getLLVMContext(), CGM, Builder);
6463 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6473 auto *IntPtr = Builder.CreatePtrToAddr(Ptr);
6474 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6476 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6480 if (PerformNullCheck) {
6488 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6489 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6490 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6491 Checks.emplace_back(
Valid, CheckOrdinal);
6494 if (PerformOverflowCheck) {
6499 llvm::Value *ValidGEP;
6500 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6501 if (SignedIndices) {
6507 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6508 auto *PosOrZeroOffset =
6510 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6512 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6513 }
else if (!IsSubtraction) {
6518 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6524 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6526 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6527 Checks.emplace_back(ValidGEP, CheckOrdinal);
6530 assert(!Checks.empty() &&
"Should have produced some checks.");
6532 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6534 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6535 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6541 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6542 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6543 const Twine &Name) {
6544 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6545 llvm::GEPNoWrapFlags NWFlags =
6547 SignedIndices, IsSubtraction);
6548 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6552 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6553 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6554 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...
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
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::Type * HalfTy
half, bfloat, float, double
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool HasSideEffects
Whether the evaluated expression has side effects.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.