36#include "llvm/ADT/APFixedPoint.h"
37#include "llvm/ADT/ScopeExit.h"
38#include "llvm/IR/Argument.h"
39#include "llvm/IR/CFG.h"
40#include "llvm/IR/Constants.h"
41#include "llvm/IR/DataLayout.h"
42#include "llvm/IR/DerivedTypes.h"
43#include "llvm/IR/FixedPointBuilder.h"
44#include "llvm/IR/Function.h"
45#include "llvm/IR/GEPNoWrapFlags.h"
46#include "llvm/IR/GetElementPtrTypeIterator.h"
47#include "llvm/IR/GlobalVariable.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/IntrinsicsPowerPC.h"
50#include "llvm/IR/IntrinsicsWebAssembly.h"
51#include "llvm/IR/MatrixBuilder.h"
52#include "llvm/IR/Module.h"
53#include "llvm/Support/TypeSize.h"
76bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
81 const auto &LHSAP = LHS->getValue();
82 const auto &RHSAP = RHS->getValue();
83 if (Opcode == BO_Add) {
85 : LHSAP.uadd_ov(RHSAP, Overflow);
86 }
else if (Opcode == BO_Sub) {
88 : LHSAP.usub_ov(RHSAP, Overflow);
89 }
else if (Opcode == BO_Mul) {
91 : LHSAP.umul_ov(RHSAP, Overflow);
92 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
93 if (
Signed && !RHS->isZero())
94 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
106 FPOptions FPFeatures;
110 bool mayHaveIntegerOverflow()
const {
112 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
113 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
114 if (!LHSCI || !RHSCI)
118 return ::mayHaveIntegerOverflow(
123 bool isDivremOp()
const {
129 bool mayHaveIntegerDivisionByZero()
const {
131 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
137 bool mayHaveFloatDivisionByZero()
const {
139 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
140 return CFP->isZero();
147 bool isFixedPointOp()
const {
150 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
151 QualType LHSType = BinOp->getLHS()->getType();
152 QualType RHSType = BinOp->getRHS()->getType();
155 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
156 return UnOp->getSubExpr()->getType()->isFixedPointType();
161 bool rhsHasSignedIntegerRepresentation()
const {
162 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
163 QualType RHSType = BinOp->getRHS()->getType();
170static bool MustVisitNullValue(
const Expr *E) {
193static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
203 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
208 switch (OBT->getBehaviorKind()) {
209 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
211 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
214 llvm_unreachable(
"Unknown OverflowBehaviorKind");
221 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
229 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
233static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
235 "Expected a unary or binary operator");
239 if (!Op.mayHaveIntegerOverflow())
246 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
247 if (BO && BO->hasExcludedOverflowPattern())
250 if (Op.Ty.isWrapType())
252 if (Op.Ty.isTrapType())
255 if (Op.Ty->isSignedIntegerType() &&
261 if (Op.Ty->isUnsignedIntegerType() &&
286 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
292 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
293 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
297class ScalarExprEmitter
299 CodeGenFunction &CGF;
300 CGBuilderTy &Builder;
301 bool IgnoreResultAssign;
302 llvm::LLVMContext &VMContext;
305 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
306 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
307 VMContext(cgf.getLLVMContext()) {
314 bool TestAndClearIgnoreResultAssign() {
315 bool I = IgnoreResultAssign;
316 IgnoreResultAssign =
false;
320 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
321 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
327 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
328 const BinOpInfo &Info);
330 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
334 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
335 const AlignValueAttr *AVAttr =
nullptr;
336 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
337 const ValueDecl *VD = DRE->getDecl();
340 if (
const auto *TTy =
342 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
352 AVAttr = VD->
getAttr<AlignValueAttr>();
357 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
358 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
371 Value *EmitLoadOfLValue(
const Expr *E) {
375 EmitLValueAlignmentAssumption(E,
V);
381 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
385 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
386 Value *Src, QualType SrcType, QualType DstType,
387 llvm::Type *DstTy, SourceLocation Loc);
392 enum ImplicitConversionCheckKind :
unsigned char {
393 ICCK_IntegerTruncation = 0,
394 ICCK_UnsignedIntegerTruncation = 1,
395 ICCK_SignedIntegerTruncation = 2,
396 ICCK_IntegerSignChange = 3,
397 ICCK_SignedIntegerTruncationOrSignChange = 4,
402 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
403 QualType DstType, SourceLocation Loc,
404 bool OBTrapInvolved =
false);
409 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
410 QualType DstType, SourceLocation Loc,
411 bool OBTrapInvolved =
false);
415 struct ScalarConversionOpts {
416 bool TreatBooleanAsSigned;
417 bool EmitImplicitIntegerTruncationChecks;
418 bool EmitImplicitIntegerSignChangeChecks;
420 bool PatternExcluded;
422 ScalarConversionOpts()
423 : TreatBooleanAsSigned(
false),
424 EmitImplicitIntegerTruncationChecks(
false),
425 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
427 ScalarConversionOpts(clang::SanitizerSet SanOpts)
428 : TreatBooleanAsSigned(
false),
429 EmitImplicitIntegerTruncationChecks(
430 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
431 EmitImplicitIntegerSignChangeChecks(
432 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
433 PatternExcluded(
false) {}
435 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
436 llvm::Type *SrcTy, llvm::Type *DstTy,
437 ScalarConversionOpts Opts);
439 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
441 ScalarConversionOpts Opts = ScalarConversionOpts());
445 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
451 QualType SrcTy, QualType DstTy,
455 Value *EmitNullValue(QualType Ty);
460 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
461 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
465 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
468 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
475 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
476 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
482 ZI->eraseFromParent();
487 return Builder.CreateIsNotNull(
V,
"tobool");
494 Value *Visit(Expr *E) {
495 ApplyDebugLocation DL(CGF, E);
496 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
499 Value *VisitStmt(Stmt *S) {
501 llvm_unreachable(
"Stmt can't have complex result type!");
503 Value *VisitExpr(Expr *S);
505 Value *VisitConstantExpr(ConstantExpr *E) {
511 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
526 Value *VisitParenExpr(ParenExpr *PE) {
529 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
532 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
533 return Visit(
GE->getResultExpr());
535 Value *VisitCoawaitExpr(CoawaitExpr *S) {
538 Value *VisitCoyieldExpr(CoyieldExpr *S) {
541 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
546 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
547 return Builder.getInt(E->
getValue());
549 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
550 return Builder.getInt(E->
getValue());
552 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
553 return llvm::ConstantFP::get(VMContext, E->
getValue());
555 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
558 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
561 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
562 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
564 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
565 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
567 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
571 return EmitNullValue(E->
getType());
573 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
574 return EmitNullValue(E->
getType());
576 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
577 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
578 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
580 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
583 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
587 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
591 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
592 Value *VisitEmbedExpr(EmbedExpr *E);
594 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
603 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
604 llvm_unreachable(
"Codegen for this isn't defined/implemented");
608 Value *VisitDeclRefExpr(DeclRefExpr *E) {
611 return EmitLoadOfLValue(E);
614 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
617 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
620 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
621 return EmitLoadOfLValue(E);
623 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
626 return EmitLoadOfLValue(E);
630 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
636 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
642 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
647 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
648 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
649 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
650 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
651 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
652 Value *VisitMemberExpr(MemberExpr *E);
653 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
654 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
655 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
661 return EmitLoadOfLValue(E);
664 Value *VisitInitListExpr(InitListExpr *E);
666 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
668 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
672 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
673 return EmitNullValue(E->
getType());
675 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
677 return VisitCastExpr(E);
681 Value *VisitCallExpr(
const CallExpr *E) {
683 return EmitLoadOfLValue(E);
685 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
689 EmitLValueAlignmentAssumption(E,
V);
693 Value *VisitStmtExpr(
const StmtExpr *E);
696 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
698 return EmitScalarPrePostIncDec(E, LV,
false,
false);
700 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
702 return EmitScalarPrePostIncDec(E, LV,
true,
false);
704 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
706 return EmitScalarPrePostIncDec(E, LV,
false,
true);
708 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
710 return EmitScalarPrePostIncDec(E, LV,
true,
true);
713 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
717 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
718 bool isInc,
bool isPre);
721 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
725 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
727 Value *VisitUnaryDeref(
const UnaryOperator *E) {
730 return EmitLoadOfLValue(E);
733 Value *VisitUnaryPlus(
const UnaryOperator *E,
734 QualType PromotionType = QualType());
735 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
736 Value *VisitUnaryMinus(
const UnaryOperator *E,
737 QualType PromotionType = QualType());
738 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
740 Value *VisitUnaryNot (
const UnaryOperator *E);
741 Value *VisitUnaryLNot (
const UnaryOperator *E);
742 Value *VisitUnaryReal(
const UnaryOperator *E,
743 QualType PromotionType = QualType());
744 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
745 Value *VisitUnaryImag(
const UnaryOperator *E,
746 QualType PromotionType = QualType());
747 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
748 Value *VisitUnaryExtension(
const UnaryOperator *E) {
753 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
754 return EmitLoadOfLValue(E);
756 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
764 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
765 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
768 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
769 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
772 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
776 Value *VisitExprWithCleanups(ExprWithCleanups *E);
777 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
780 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
785 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
787 return llvm::ConstantInt::get(ConvertType(E->
getType()),
790 return llvm::ConstantInt::get(ConvertType(E->
getType()),
794 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
802 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
803 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
806 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
807 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
810 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
820 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
821 return EmitNullValue(E->
getType());
824 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
829 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
830 return Builder.getInt1(E->
getValue());
834 Value *EmitMul(
const BinOpInfo &Ops) {
835 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
836 Ops.Ty->isUnsignedIntegerType()) {
837 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
839 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
840 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
841 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
842 case LangOptions::OB_Wrap:
843 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
844 case LangOptions::OB_SignedAndDefined:
846 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
848 case LangOptions::OB_Unset:
850 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
851 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
853 case LangOptions::OB_Trap:
854 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
855 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
856 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
857 return EmitOverflowCheckedBinOp(Ops);
861 if (Ops.Ty->isConstantMatrixType()) {
862 llvm::MatrixBuilder MB(Builder);
866 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
867 BO->getLHS()->getType().getCanonicalType());
868 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
869 BO->getRHS()->getType().getCanonicalType());
870 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
871 if (LHSMatTy && RHSMatTy)
872 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
873 LHSMatTy->getNumColumns(),
874 RHSMatTy->getNumColumns());
875 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
878 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
880 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
881 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
883 if (Ops.isFixedPointOp())
884 return EmitFixedPointBinOp(Ops);
885 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
889 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
892 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
893 llvm::Value *
Zero,
bool isDiv);
895 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
901 Value *EmitDiv(
const BinOpInfo &Ops);
902 Value *EmitRem(
const BinOpInfo &Ops);
903 Value *EmitAdd(
const BinOpInfo &Ops);
904 Value *EmitSub(
const BinOpInfo &Ops);
905 Value *EmitShl(
const BinOpInfo &Ops);
906 Value *EmitShr(
const BinOpInfo &Ops);
907 Value *EmitAnd(
const BinOpInfo &Ops) {
908 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
910 Value *EmitXor(
const BinOpInfo &Ops) {
911 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
913 Value *EmitOr (
const BinOpInfo &Ops) {
914 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
918 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
920 BinOpInfo EmitBinOps(
const BinaryOperator *E,
921 QualType PromotionTy = QualType());
923 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
924 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
925 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
927 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
928 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
931 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
932 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
934 QualType getPromotionType(QualType Ty) {
936 if (
auto *CT = Ty->
getAs<ComplexType>()) {
937 QualType ElementType = CT->getElementType();
943 if (
auto *VT = Ty->
getAs<VectorType>()) {
944 unsigned NumElements = VT->getNumElements();
954#define HANDLEBINOP(OP) \
955 Value *VisitBin##OP(const BinaryOperator *E) { \
956 QualType promotionTy = getPromotionType(E->getType()); \
957 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
958 if (result && !promotionTy.isNull()) \
959 result = EmitUnPromotedValue(result, E->getType()); \
962 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
963 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
964 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
980 llvm::CmpInst::Predicate SICmpOpc,
981 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
982#define VISITCOMP(CODE, UI, SI, FP, SIG) \
983 Value *VisitBin##CODE(const BinaryOperator *E) { \
984 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
985 llvm::FCmpInst::FP, SIG); }
986 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
1000 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
1001 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1003 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1008 Value *VisitBlockExpr(
const BlockExpr *BE);
1009 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1010 Value *VisitChooseExpr(ChooseExpr *CE);
1011 Value *VisitVAArgExpr(VAArgExpr *VE);
1012 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1015 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1018 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1021 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1024 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1025 Value *VisitAtomicExpr(AtomicExpr *AE);
1026 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1039 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1042 return EmitFloatToBoolConversion(Src);
1044 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1048 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1052 "Unknown scalar type to convert");
1055 return EmitIntToBoolConversion(Src);
1058 return EmitPointerToBoolConversion(Src, SrcType);
1061void ScalarExprEmitter::EmitFloatConversionCheck(
1062 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1063 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1064 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1068 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1069 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1070 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1071 using llvm::APFloat;
1074 llvm::Value *Check =
nullptr;
1075 const llvm::fltSemantics &SrcSema =
1085 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1086 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1087 APFloat::opOverflow)
1090 MinSrc = APFloat::getInf(SrcSema,
true);
1094 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1097 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1098 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1099 APFloat::opOverflow)
1102 MaxSrc = APFloat::getInf(SrcSema,
false);
1106 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1111 const llvm::fltSemantics &Sema =
1114 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1115 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1119 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1121 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1122 Check = Builder.CreateAnd(GE, LE);
1127 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1133static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1134 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1137 llvm::Type *SrcTy = Src->
getType();
1138 llvm::Type *DstTy = Dst->
getType();
1143 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1145 "non-integer llvm type");
1152 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1154 if (!SrcSigned && !DstSigned) {
1155 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1156 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1158 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1159 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1162 llvm::Value *Check =
nullptr;
1164 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1166 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1168 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1176void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1177 Value *Dst, QualType DstType,
1179 bool OBTrapInvolved) {
1180 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1190 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1191 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1193 if (SrcBits <= DstBits)
1196 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1203 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1204 (!SrcSigned && DstSigned))
1207 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1208 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1211 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1216 SanitizerDebugLocation SanScope(
1218 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1219 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1235 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1243 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1244 if (OBT->isWrapKind())
1247 if (ignoredBySanitizer && !OBTrapInvolved)
1250 llvm::Constant *StaticArgs[] = {
1253 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1254 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1256 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1263 llvm::Type *VTy =
V->getType();
1266 return llvm::ConstantInt::getFalse(VTy->getContext());
1268 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1269 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1270 llvm::Twine(Name) +
"." +
V->getName() +
1271 ".negativitycheck");
1276static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1277 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1280 llvm::Type *SrcTy = Src->
getType();
1281 llvm::Type *DstTy = Dst->
getType();
1284 "non-integer llvm type");
1290 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1291 unsigned DstBits = DstTy->getScalarSizeInBits();
1295 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1296 "either the widths should be different, or the signednesses.");
1299 llvm::Value *SrcIsNegative =
1302 llvm::Value *DstIsNegative =
1308 llvm::Value *Check =
nullptr;
1309 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1311 return std::make_pair(
1312 ScalarExprEmitter::ICCK_IntegerSignChange,
1313 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1316void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1317 Value *Dst, QualType DstType,
1319 bool OBTrapInvolved) {
1320 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1324 llvm::Type *SrcTy = Src->
getType();
1325 llvm::Type *DstTy = Dst->
getType();
1335 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1336 unsigned DstBits = DstTy->getScalarSizeInBits();
1343 if (SrcSigned == DstSigned && SrcBits == DstBits)
1347 if (!SrcSigned && !DstSigned)
1352 if ((DstBits > SrcBits) && DstSigned)
1354 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1355 (SrcBits > DstBits) && SrcSigned) {
1364 if (!OBTrapInvolved) {
1367 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1371 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1376 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1377 SanitizerDebugLocation SanScope(
1379 {SanitizerKind::SO_ImplicitIntegerSignChange,
1380 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1381 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1384 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1385 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1389 ImplicitConversionCheckKind CheckKind;
1390 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1397 CheckKind = Check.first;
1398 Checks.emplace_back(Check.second);
1400 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1401 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1407 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1408 Checks.emplace_back(Check.second);
1412 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1413 if (OBTrapInvolved) {
1414 llvm::Value *Combined = Check.second.first;
1415 for (
const auto &
C : Checks)
1416 Combined = Builder.CreateAnd(Combined,
C.first);
1422 llvm::Constant *StaticArgs[] = {
1425 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1426 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1428 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1433static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1434 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1440 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1441 if (!SrcSigned && !DstSigned)
1442 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1444 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1446 llvm::Value *Check =
nullptr;
1448 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1450 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1453 return std::make_pair(
1455 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1460static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1461 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1465 llvm::Value *SrcIsNegative =
1468 llvm::Value *DstIsNegative =
1474 llvm::Value *Check =
nullptr;
1476 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1478 return std::make_pair(
1479 ScalarExprEmitter::ICCK_IntegerSignChange,
1480 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1488 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1506 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1507 unsigned DstBits = Info.
Size;
1512 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1514 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1516 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1517 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1521 bool EmitTruncation = DstBits < SrcBits;
1525 bool EmitTruncationFromUnsignedToSigned =
1526 EmitTruncation && DstSigned && !SrcSigned;
1528 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1529 bool BothUnsigned = !SrcSigned && !DstSigned;
1530 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1537 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1542 else if (EmitSignChange) {
1543 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1544 "either the widths should be different, or the signednesses.");
1550 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1551 if (EmitTruncationFromUnsignedToSigned)
1552 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1554 llvm::Constant *StaticArgs[] = {
1557 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1558 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1560 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1564 QualType DstType, llvm::Type *SrcTy,
1566 ScalarConversionOpts Opts) {
1568 llvm::Type *SrcElementTy;
1569 llvm::Type *DstElementTy;
1579 "cannot cast between matrix and non-matrix types");
1580 SrcElementTy = SrcTy;
1581 DstElementTy = DstTy;
1582 SrcElementType = SrcType;
1583 DstElementType = DstType;
1588 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1593 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1595 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1596 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1600 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1607 llvm::Intrinsic::ID IID =
1608 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1609 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1613 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1614 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1617 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1618 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1619 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1621 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1622 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1623 return Builder.CreateFPExt(Src, DstTy,
"conv");
1628Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1631 ScalarConversionOpts Opts) {
1646 return Builder.CreateIsNotNull(Src,
"tobool");
1649 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1652 "Unhandled scalar conversion from a fixed point type to another type.");
1656 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1659 "Unhandled scalar conversion to a fixed point type from another type.");
1662 QualType NoncanonicalSrcType = SrcType;
1663 QualType NoncanonicalDstType = DstType;
1667 if (SrcType == DstType)
return Src;
1671 llvm::Value *OrigSrc = Src;
1672 QualType OrigSrcType = SrcType;
1673 llvm::Type *SrcTy = Src->
getType();
1677 return EmitConversionToBool(Src, SrcType);
1679 llvm::Type *DstTy = ConvertType(DstType);
1688 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1689 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1690 bool OBTrapInvolved =
1691 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1692 bool OBWrapInvolved =
1693 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1698 if (DstTy->isFloatingPointTy())
1699 return Builder.CreateFPExt(Src, DstTy,
"conv");
1703 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1709 if (SrcTy == DstTy) {
1710 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1711 (OBTrapInvolved && !OBWrapInvolved))
1712 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1713 NoncanonicalDstType, Loc, OBTrapInvolved);
1721 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1726 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1731 llvm::Value* IntResult =
1732 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1734 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1740 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1747 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1749 "Splatted expr doesn't match with vector element type?");
1753 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1757 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1761 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1762 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1763 if (SrcSize == DstSize)
1764 return Builder.CreateBitCast(Src, DstTy,
"conv");
1777 assert(((SrcElementTy->isIntegerTy() &&
1778 DstElementTy->isIntegerTy()) ||
1779 (SrcElementTy->isFloatingPointTy() &&
1780 DstElementTy->isFloatingPointTy())) &&
1781 "unexpected conversion between a floating-point vector and an "
1785 if (SrcElementTy->isIntegerTy())
1786 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1789 if (SrcSize > DstSize)
1790 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1793 return Builder.CreateFPExt(Src, DstTy,
"conv");
1797 Value *Res =
nullptr;
1798 llvm::Type *ResTy = DstTy;
1805 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1807 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1815 if (SrcTy->isFloatingPointTy())
1816 return Builder.CreateFPTrunc(Src, CGF.
CGM.
HalfTy,
"conv");
1821 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1823 if (DstTy != ResTy) {
1824 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1827 assert(ResTy->isIntegerTy(16) &&
1828 "Only half FP requires extra conversion");
1829 Res = Builder.CreateBitCast(Res, ResTy);
1833 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1834 !OBWrapInvolved && !Opts.PatternExcluded)
1835 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1836 NoncanonicalDstType, Loc, OBTrapInvolved);
1838 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1839 (OBTrapInvolved && !OBWrapInvolved))
1840 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1841 NoncanonicalDstType, Loc, OBTrapInvolved);
1846Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1848 SourceLocation Loc) {
1849 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1852 Result = FPBuilder.CreateFloatingToFixed(Src,
1855 Result = FPBuilder.CreateFixedToFloating(Src,
1857 ConvertType(DstTy));
1863 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1864 DstFPSema.getWidth(),
1865 DstFPSema.isSigned());
1867 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1870 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1877Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1879 SourceLocation Loc) {
1881 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1886 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1887 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1888 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1895 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1898Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1906void ScalarExprEmitter::EmitBinOpCheck(
1907 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1908 const BinOpInfo &Info) {
1911 SmallVector<llvm::Constant *, 4> StaticData;
1912 SmallVector<llvm::Value *, 2> DynamicData;
1920 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1921 if (UO && UO->
getOpcode() == UO_Minus) {
1922 Check = SanitizerHandler::NegateOverflow;
1924 DynamicData.push_back(Info.RHS);
1928 Check = SanitizerHandler::ShiftOutOfBounds;
1930 StaticData.push_back(
1932 StaticData.push_back(
1934 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1936 Check = SanitizerHandler::DivremOverflow;
1940 int ArithOverflowKind = 0;
1943 Check = SanitizerHandler::AddOverflow;
1944 ArithOverflowKind = diag::UBSanArithKind::Add;
1948 Check = SanitizerHandler::SubOverflow;
1949 ArithOverflowKind = diag::UBSanArithKind::Sub;
1953 Check = SanitizerHandler::MulOverflow;
1954 ArithOverflowKind = diag::UBSanArithKind::Mul;
1958 llvm_unreachable(
"unexpected opcode for bin op check");
1962 SanitizerKind::UnsignedIntegerOverflow) ||
1964 SanitizerKind::SignedIntegerOverflow)) {
1968 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1972 DynamicData.push_back(Info.LHS);
1973 DynamicData.push_back(Info.RHS);
1976 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1983Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1991ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1993 unsigned AddrSpace =
1995 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1998 llvm::Type *ExprTy = ConvertType(E->
getType());
1999 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2003Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2005 auto It = E->
begin();
2006 return Builder.getInt((*It)->getValue());
2009Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2017 unsigned LHSElts = LTy->getNumElements();
2025 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2026 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2034 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2035 MTy->getNumElements());
2036 Value* NewV = llvm::PoisonValue::get(RTy);
2037 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2038 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2039 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2041 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2042 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2050 SmallVector<int, 32> Indices;
2054 if (Idx.isSigned() && Idx.isAllOnes())
2055 Indices.push_back(-1);
2057 Indices.push_back(Idx.getZExtValue());
2060 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2063Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2071 if (SrcType == DstType)
return Src;
2074 "ConvertVector source type must be a vector");
2076 "ConvertVector destination type must be a vector");
2078 llvm::Type *SrcTy = Src->
getType();
2079 llvm::Type *DstTy = ConvertType(DstType);
2085 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2086 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2088 assert(SrcTy->isVectorTy() &&
2089 "ConvertVector source IR type must be a vector");
2090 assert(DstTy->isVectorTy() &&
2091 "ConvertVector destination IR type must be a vector");
2096 if (DstEltType->isBooleanType()) {
2097 assert((SrcEltTy->isFloatingPointTy() ||
2100 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2101 if (SrcEltTy->isFloatingPointTy()) {
2102 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2103 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2105 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2110 Value *Res =
nullptr;
2115 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2117 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2119 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2121 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2124 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2125 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2126 if (DstEltType->isSignedIntegerOrEnumerationType())
2127 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2129 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2131 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2132 "Unknown real conversion");
2133 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2134 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2135 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2137 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2143Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2152 return Builder.getInt(
Value);
2156 llvm::Value *
Result = EmitLoadOfLValue(E);
2162 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2163 if (llvm::GetElementPtrInst *GEP =
2164 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2165 if (llvm::Instruction *
Pointer =
2166 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2178Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2179 TestAndClearIgnoreResultAssign();
2187 return EmitLoadOfLValue(E);
2195 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2198 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2202 Ret = Builder.CreateInsertElement(
2203 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
2209Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2210 MatrixSingleSubscriptExpr *E) {
2211 TestAndClearIgnoreResultAssign();
2214 unsigned NumRows = MatrixTy->getNumRows();
2215 unsigned NumColumns = MatrixTy->getNumColumns();
2219 llvm::MatrixBuilder MB(Builder);
2223 MB.CreateIndexAssumption(RowIdx, NumRows);
2227 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2228 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2230 bool IsMatrixRowMajor =
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 IsMatrixRowMajor,
"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);
2258 unsigned NumCols = MatrixTy->getNumColumns();
2259 unsigned NumRows = MatrixTy->getNumRows();
2260 bool IsMatrixRowMajor =
2262 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2265 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2270 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2275 int MV = SVI->getMaskValue(Idx);
2282 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2283 "Index operand too large for shufflevector mask!");
2284 return C->getZExtValue();
2287Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2288 bool Ignore = TestAndClearIgnoreResultAssign();
2291 assert((Ignore ==
false ||
2293 "init list ignored");
2310 llvm::VectorType *VType =
2311 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2314 if (NumInitElements == 0) {
2316 return EmitNullValue(E->
getType());
2323 if (NumInitElements == 0) {
2325 return EmitNullValue(E->
getType());
2328 if (NumInitElements == 1) {
2329 Expr *InitVector = E->
getInit(0);
2334 return Visit(InitVector);
2337 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2344 const ConstantMatrixType *ColMajorMT =
nullptr;
2345 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2354 unsigned CurIdx = 0;
2355 bool VIsPoisonShuffle =
false;
2356 llvm::Value *
V = llvm::PoisonValue::get(VType);
2357 for (
unsigned i = 0; i != NumInitElements; ++i) {
2360 SmallVector<int, 16> Args;
2362 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2372 ->getNumElements() == ResElts) {
2374 Value *LHS =
nullptr, *RHS =
nullptr;
2379 Args.resize(ResElts, -1);
2381 LHS = EI->getVectorOperand();
2383 VIsPoisonShuffle =
true;
2384 }
else if (VIsPoisonShuffle) {
2387 for (
unsigned j = 0; j != CurIdx; ++j)
2389 Args.push_back(ResElts +
C->getZExtValue());
2390 Args.resize(ResElts, -1);
2393 RHS = EI->getVectorOperand();
2394 VIsPoisonShuffle =
false;
2396 if (!Args.empty()) {
2397 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2403 unsigned InsertIdx =
2407 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2409 VIsPoisonShuffle =
false;
2419 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2422 Value *SVOp = SVI->getOperand(0);
2425 if (OpTy->getNumElements() == ResElts) {
2426 for (
unsigned j = 0; j != CurIdx; ++j) {
2429 if (VIsPoisonShuffle) {
2435 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2437 Args.resize(ResElts, -1);
2439 if (VIsPoisonShuffle)
2449 for (
unsigned j = 0; j != InitElts; ++j)
2451 Args.resize(ResElts, -1);
2452 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2455 for (
unsigned j = 0; j != CurIdx; ++j)
2457 for (
unsigned j = 0; j != InitElts; ++j)
2458 Args.push_back(j + Offset);
2459 Args.resize(ResElts, -1);
2466 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2473 llvm::Type *EltTy = VType->getElementType();
2476 for (; CurIdx < ResElts; ++CurIdx) {
2477 unsigned InsertIdx =
2480 Value *Idx = Builder.getInt32(InsertIdx);
2481 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2482 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2495 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2499 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2502 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2521 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2525 if (
const auto *CE = dyn_cast<CastExpr>(E))
2526 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2527 CE->getCastKind() == CK_ArrayToPointerDecay)
2538 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2548 if (ICE->isGLValue())
2563 assert(LoadList.size() >= VecTy->getNumElements() &&
2564 "Flattened type on RHS must have the same number or more elements "
2565 "than vector on LHS.");
2569 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2572 "All flattened source values should be scalars.");
2575 VecTy->getElementType(), Loc);
2576 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2581 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2582 "Flattened type on RHS must have the same number or more elements "
2583 "than vector on LHS.");
2590 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2591 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2594 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2597 "All flattened source values should be scalars.");
2600 MatTy->getElementType(), Loc);
2601 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2602 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2609 "Destination type must be a vector, matrix, or builtin type.");
2611 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2620 llvm::scope_exit RestoreCurCast(
2621 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2625 QualType DestTy = CE->
getType();
2627 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2631 bool Ignored = TestAndClearIgnoreResultAssign();
2637 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2638 case CK_BuiltinFnToFnPtr:
2639 llvm_unreachable(
"builtin functions are handled elsewhere");
2641 case CK_LValueBitCast:
2642 case CK_ObjCObjectLValueCast: {
2646 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2649 case CK_LValueToRValueBitCast: {
2655 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2658 case CK_CPointerToObjCPointerCast:
2659 case CK_BlockPointerToObjCPointerCast:
2660 case CK_AnyPointerToBlockPointerCast:
2662 Value *Src = Visit(E);
2663 llvm::Type *SrcTy = Src->
getType();
2664 llvm::Type *DstTy = ConvertType(DestTy);
2675 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2689 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2690 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2695 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2696 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2697 "Address-space cast must be used to convert address spaces");
2699 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2700 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2702 PT->getPointeeType(),
2713 const QualType SrcType = E->
getType();
2718 Src = Builder.CreateLaunderInvariantGroup(Src);
2726 Src = Builder.CreateStripInvariantGroup(Src);
2731 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2735 if (!PointeeType.
isNull())
2744 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2745 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2748 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2749 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2750 ScalableDstTy = llvm::ScalableVectorType::get(
2751 FixedSrcTy->getElementType(),
2753 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2755 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2756 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2757 llvm::Value *
Result = Builder.CreateInsertVector(
2758 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2760 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2761 if (
Result->getType() != ScalableDstTy)
2763 if (
Result->getType() != DstTy)
2773 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2774 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2777 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2778 FixedDstTy->getElementType()->isIntegerTy(8)) {
2779 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2780 ScalableSrcTy = llvm::ScalableVectorType::get(
2781 ScalableSrcTy->getElementType(),
2783 ScalableSrcTy->getElementCount().getKnownMinValue()));
2784 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2785 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2789 ScalableSrcTy = llvm::ScalableVectorType::get(
2790 FixedDstTy->getElementType(),
2791 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2792 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2794 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2795 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2816 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2819 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2822 case CK_AddressSpaceConversion: {
2823 llvm::Type *DestLTy = ConvertType(DestTy);
2826 auto IsWasmFuncref = [](llvm::Type *
T) {
2827 auto *TET = dyn_cast<llvm::TargetExtType>(
T);
2828 return TET && TET->getName() ==
"wasm.funcref";
2830 bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->
getType()));
2831 bool DestIsFuncref = IsWasmFuncref(DestLTy);
2832 if (SrcIsFuncref && DestIsFuncref) {
2837 if (SrcIsFuncref && !DestIsFuncref) {
2841 llvm::Function *ToPtr =
2843 return CGF.
Builder.CreateCall(ToPtr, {Visit(E)});
2845 if (!SrcIsFuncref && DestIsFuncref) {
2848 Expr::EvalResult NullResult;
2853 return llvm::Constant::getNullValue(DestLTy);
2856 llvm::Function *ToFuncref =
2858 return CGF.
Builder.CreateCall(ToFuncref, {Visit(E)});
2862 Result.Val.isNullPointer()) {
2866 if (
Result.HasSideEffects)
2874 case CK_AtomicToNonAtomic:
2875 case CK_NonAtomicToAtomic:
2876 case CK_UserDefinedConversion:
2883 case CK_BaseToDerived: {
2885 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2899 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2907 case CK_UncheckedDerivedToBase:
2908 case CK_DerivedToBase: {
2921 case CK_ArrayToPointerDecay:
2924 case CK_FunctionToPointerDecay:
2925 return EmitLValue(E).getPointer(CGF);
2927 case CK_NullToPointer:
2928 if (MustVisitNullValue(E))
2934 case CK_NullToMemberPointer: {
2935 if (MustVisitNullValue(E))
2938 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2942 case CK_ReinterpretMemberPointer:
2943 case CK_BaseToDerivedMemberPointer:
2944 case CK_DerivedToBaseMemberPointer: {
2945 Value *Src = Visit(E);
2956 case CK_ARCProduceObject:
2958 case CK_ARCConsumeObject:
2960 case CK_ARCReclaimReturnedObject:
2962 case CK_ARCExtendBlockObject:
2965 case CK_CopyAndAutoreleaseBlockObject:
2968 case CK_FloatingRealToComplex:
2969 case CK_FloatingComplexCast:
2970 case CK_IntegralRealToComplex:
2971 case CK_IntegralComplexCast:
2972 case CK_IntegralComplexToFloatingComplex:
2973 case CK_FloatingComplexToIntegralComplex:
2974 case CK_ConstructorConversion:
2976 case CK_HLSLArrayRValue:
2977 llvm_unreachable(
"scalar cast to non-scalar value");
2979 case CK_LValueToRValue:
2981 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2984 case CK_IntegralToPointer: {
2985 Value *Src = Visit(E);
2989 auto DestLLVMTy = ConvertType(DestTy);
2992 llvm::Value* IntResult =
2993 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2995 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
3001 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
3007 case CK_PointerToIntegral: {
3008 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
3009 auto *PtrExpr = Visit(E);
3012 const QualType SrcType = E->
getType();
3017 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
3021 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3027 case CK_MatrixCast: {
3028 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3035 case CK_HLSLAggregateSplatCast:
3036 case CK_VectorSplat: {
3037 llvm::Type *DstTy = ConvertType(DestTy);
3038 Value *Elt = Visit(E);
3040 llvm::ElementCount NumElements =
3042 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3045 case CK_FixedPointCast:
3046 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3049 case CK_FixedPointToBoolean:
3051 "Expected src type to be fixed point type");
3052 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3053 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3056 case CK_FixedPointToIntegral:
3058 "Expected src type to be fixed point type");
3059 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3060 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3063 case CK_IntegralToFixedPoint:
3065 "Expected src type to be an integer");
3067 "Expected dest type to be fixed point type");
3068 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3071 case CK_IntegralCast: {
3073 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3074 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3078 ScalarConversionOpts Opts;
3079 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3080 if (!ICE->isPartOfExplicitCast())
3081 Opts = ScalarConversionOpts(CGF.
SanOpts);
3083 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3086 case CK_IntegralToFloating: {
3089 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3091 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3092 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3094 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3095 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3098 case CK_FloatingToIntegral: {
3101 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3103 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3104 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3106 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3107 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3110 case CK_FloatingCast: {
3113 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3114 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3115 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3116 SrcElTy->
castAs<BuiltinType>()->getKind())
3117 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3118 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3120 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3121 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3124 case CK_FixedPointToFloating:
3125 case CK_FloatingToFixedPoint: {
3126 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3127 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3130 case CK_BooleanToSignedIntegral: {
3131 ScalarConversionOpts Opts;
3132 Opts.TreatBooleanAsSigned =
true;
3133 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3136 case CK_IntegralToBoolean:
3137 return EmitIntToBoolConversion(Visit(E));
3138 case CK_PointerToBoolean:
3139 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3140 case CK_FloatingToBoolean: {
3141 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3142 return EmitFloatToBoolConversion(Visit(E));
3144 case CK_MemberPointerToBoolean: {
3145 llvm::Value *MemPtr = Visit(E);
3146 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3150 case CK_FloatingComplexToReal:
3151 case CK_IntegralComplexToReal:
3154 case CK_FloatingComplexToBoolean:
3155 case CK_IntegralComplexToBoolean: {
3159 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3163 case CK_ZeroToOCLOpaqueType: {
3166 "CK_ZeroToOCLEvent cast on non-event type");
3167 return llvm::Constant::getNullValue(ConvertType(DestTy));
3170 case CK_IntToOCLSampler:
3173 case CK_HLSLVectorTruncation: {
3175 "Destination type must be a vector or builtin type.");
3176 Value *Vec = Visit(E);
3177 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3178 SmallVector<int> Mask;
3179 unsigned NumElts = VecTy->getNumElements();
3180 for (
unsigned I = 0; I != NumElts; ++I)
3183 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3185 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3186 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3188 case CK_HLSLMatrixTruncation: {
3190 "Destination type must be a matrix or builtin type.");
3191 Value *Mat = Visit(E);
3192 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3193 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3194 unsigned NumCols = MatTy->getNumColumns();
3195 unsigned NumRows = MatTy->getNumRows();
3196 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3197 assert(SrcMatTy &&
"Source type must be a matrix type.");
3198 assert(NumRows <= SrcMatTy->getNumRows());
3199 assert(NumCols <= SrcMatTy->getNumColumns());
3206 for (
unsigned R = 0;
R < NumRows;
R++)
3207 for (
unsigned C = 0;
C < NumCols;
C++)
3208 Mask[MatTy->getFlattenedIndex(R,
C, IsDstRowMajor)] =
3209 SrcMatTy->getFlattenedIndex(R,
C, IsSrcRowMajor);
3211 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3213 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3214 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3216 case CK_HLSLElementwiseCast: {
3236 llvm_unreachable(
"unknown scalar cast");
3239Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3240 CodeGenFunction::StmtExprEvaluation eval(CGF);
3249Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3250 CodeGenFunction::RunCleanupsScope Scope(CGF);
3254 Scope.ForceCleanup({&
V});
3263 llvm::Value *InVal,
bool IsInc,
3267 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3269 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3270 BinOp.FPFeatures = FPFeatures;
3275llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3276 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3279 llvm::Value *Amount =
3280 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3281 StringRef Name = IsInc ?
"inc" :
"dec";
3285 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3286 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3288 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3289 case LangOptions::OB_Wrap:
3290 return Builder.CreateAdd(InVal, Amount, Name);
3291 case LangOptions::OB_SignedAndDefined:
3293 return Builder.CreateAdd(InVal, Amount, Name);
3295 case LangOptions::OB_Unset:
3297 return Builder.CreateAdd(InVal, Amount, Name);
3299 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3300 : Builder.CreateAdd(InVal, Amount, Name);
3302 case LangOptions::OB_Trap:
3304 return Builder.CreateAdd(InVal, Amount, Name);
3307 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3308 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3309 : Builder.CreateAdd(InVal, Amount, Name);
3310 return EmitOverflowCheckedBinOp(Info);
3312 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3317class OMPLastprivateConditionalUpdateRAII {
3319 CodeGenFunction &CGF;
3320 const UnaryOperator *E;
3323 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3324 const UnaryOperator *E)
3326 ~OMPLastprivateConditionalUpdateRAII() {
3335ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3336 bool isInc,
bool isPre) {
3338 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3340 llvm::PHINode *atomicPHI =
nullptr;
3344 QualType SrcType = E->
getType();
3346 int amount = (isInc ? 1 : -1);
3347 bool isSubtraction = !isInc;
3349 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3350 type = atomicTy->getValueType();
3351 if (isInc &&
type->isBooleanType()) {
3354 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3355 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3356 return Builder.getTrue();
3360 return Builder.CreateAtomicRMW(
3361 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3362 llvm::AtomicOrdering::SequentiallyConsistent);
3367 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3368 !(
type->isUnsignedIntegerType() &&
3369 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3371 LangOptions::SOB_Trapping) {
3372 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3373 llvm::AtomicRMWInst::Sub;
3374 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3375 llvm::Instruction::Sub;
3377 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3379 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3380 llvm::AtomicOrdering::SequentiallyConsistent);
3381 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3385 if (
type->isFloatingType()) {
3386 llvm::Type *Ty = ConvertType(
type);
3387 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3388 llvm::AtomicRMWInst::BinOp aop =
3389 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3390 llvm::Instruction::BinaryOps op =
3391 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3392 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3393 llvm::AtomicRMWInst *old =
3395 llvm::AtomicOrdering::SequentiallyConsistent);
3397 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3400 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3403 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3406 Builder.CreateBr(opBB);
3407 Builder.SetInsertPoint(opBB);
3408 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3409 atomicPHI->addIncoming(value, startBB);
3412 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3423 if (isInc &&
type->isBooleanType()) {
3424 value = Builder.getTrue();
3427 }
else if (
type->isIntegerType()) {
3428 QualType promotedType;
3429 bool canPerformLossyDemotionCheck =
false;
3433 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3434 canPerformLossyDemotionCheck =
true;
3435 canPerformLossyDemotionCheck &=
3438 canPerformLossyDemotionCheck &=
3440 type, promotedType);
3441 assert((!canPerformLossyDemotionCheck ||
3442 type->isSignedIntegerOrEnumerationType() ||
3444 ConvertType(
type)->getScalarSizeInBits() ==
3445 ConvertType(promotedType)->getScalarSizeInBits()) &&
3446 "The following check expects that if we do promotion to different "
3447 "underlying canonical type, at least one of the types (either "
3448 "base or promoted) will be signed, or the bitwidths will match.");
3451 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3452 SanitizerKind::ImplicitBitfieldConversion) &&
3453 canPerformLossyDemotionCheck) {
3467 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3468 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3469 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3473 ScalarConversionOpts Opts;
3474 if (!LV.isBitField())
3475 Opts = ScalarConversionOpts(CGF.
SanOpts);
3476 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3478 SrcType = promotedType;
3482 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3488 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3489 type->isUnsignedIntegerType()) {
3490 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3495 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3496 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3500 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3501 QualType
type = ptr->getPointeeType();
3504 if (
const VariableArrayType *vla
3507 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3510 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3513 elemTy, value, numElts,
false, isSubtraction,
3517 }
else if (
type->isFunctionType()) {
3518 llvm::Value *amt = Builder.getInt32(amount);
3521 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3525 false, isSubtraction,
3530 llvm::Value *amt = Builder.getInt32(amount);
3533 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3536 elemTy, value, amt,
false, isSubtraction,
3541 }
else if (
type->isVectorType()) {
3542 if (
type->hasIntegerRepresentation()) {
3543 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3545 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3547 value = Builder.CreateFAdd(
3549 llvm::ConstantFP::get(value->getType(), amount),
3550 isInc ?
"inc" :
"dec");
3554 }
else if (
type->isRealFloatingType()) {
3557 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3563 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3566 if (value->getType()->isFloatTy())
3567 amt = llvm::ConstantFP::get(VMContext,
3568 llvm::APFloat(
static_cast<float>(amount)));
3569 else if (value->getType()->isDoubleTy())
3570 amt = llvm::ConstantFP::get(VMContext,
3571 llvm::APFloat(
static_cast<double>(amount)));
3575 llvm::APFloat F(
static_cast<float>(amount));
3577 const llvm::fltSemantics *FS;
3580 if (value->getType()->isFP128Ty())
3582 else if (value->getType()->isHalfTy())
3584 else if (value->getType()->isBFloatTy())
3586 else if (value->getType()->isPPC_FP128Ty())
3590 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3591 amt = llvm::ConstantFP::get(VMContext, F);
3593 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3596 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3597 value = Builder.CreateBitCast(value, input->getType());
3601 }
else if (
type->isFixedPointType()) {
3608 Info.Opcode = isInc ? BO_Add : BO_Sub;
3610 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3613 if (
type->isSignedFixedPointType()) {
3614 Info.Opcode = isInc ? BO_Sub : BO_Add;
3615 Info.RHS = Builder.CreateNeg(Info.RHS);
3620 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3622 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3623 value = EmitFixedPointBinOp(Info);
3627 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3630 if (!isInc) size = -size;
3631 llvm::Value *sizeValue =
3632 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3635 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3638 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3640 value = Builder.CreateBitCast(value, input->getType());
3644 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3649 llvm::Value *
success = Pair.second;
3650 atomicPHI->addIncoming(old, curBlock);
3651 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3652 Builder.SetInsertPoint(contBB);
3653 return isPre ? value : input;
3657 if (LV.isBitField()) {
3667 return isPre ? value : input;
3671Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3672 QualType PromotionType) {
3673 QualType promotionTy = PromotionType.
isNull()
3676 Value *result = VisitPlus(E, promotionTy);
3677 if (result && !promotionTy.
isNull())
3678 result = EmitUnPromotedValue(result, E->
getType());
3682Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3683 QualType PromotionType) {
3685 TestAndClearIgnoreResultAssign();
3686 if (!PromotionType.
isNull())
3691Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3692 QualType PromotionType) {
3693 QualType promotionTy = PromotionType.
isNull()
3696 Value *result = VisitMinus(E, promotionTy);
3697 if (result && !promotionTy.
isNull())
3698 result = EmitUnPromotedValue(result, E->
getType());
3702Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3703 QualType PromotionType) {
3704 TestAndClearIgnoreResultAssign();
3706 if (!PromotionType.
isNull())
3712 if (Op->
getType()->isFPOrFPVectorTy()) {
3713 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3714 return Builder.CreateFNeg(Op,
"fneg");
3720 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3722 BinOp.Opcode = BO_Sub;
3725 return EmitSub(BinOp);
3728Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3729 TestAndClearIgnoreResultAssign();
3731 return Builder.CreateNot(Op,
"not");
3734Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3738 VectorKind::Generic) {
3742 if (Oper->
getType()->isFPOrFPVectorTy()) {
3743 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3745 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3747 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3748 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3757 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3760 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3763Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3765 Expr::EvalResult EVResult;
3768 return Builder.getInt(
Value);
3773 llvm::Type* ResultType = ConvertType(E->
getType());
3774 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3776 for (
unsigned i = 0; i != n; ++i) {
3778 llvm::Value *Offset =
nullptr;
3785 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3792 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3796 Offset = Builder.CreateMul(Idx, ElemSize);
3801 FieldDecl *MemberDecl = ON.
getField();
3811 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3814 CurrentType = MemberDecl->
getType();
3819 llvm_unreachable(
"dependent __builtin_offsetof");
3836 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3848ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3849 const UnaryExprOrTypeTraitExpr *E) {
3852 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3853 if (
const VariableArrayType *VAT =
3858 bool EvaluateExtent =
true;
3859 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3861 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3863 if (EvaluateExtent) {
3874 if (Kind == UETT_CountOf)
3883 if (!eltSize.
isOne())
3886 return VlaSize.NumElts;
3889 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3895 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3896 }
else if (E->
getKind() == UETT_VectorElements) {
3898 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3906Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3907 QualType PromotionType) {
3908 QualType promotionTy = PromotionType.
isNull()
3911 Value *result = VisitReal(E, promotionTy);
3912 if (result && !promotionTy.
isNull())
3913 result = EmitUnPromotedValue(result, E->
getType());
3917Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3918 QualType PromotionType) {
3925 if (!PromotionType.
isNull()) {
3927 Op, IgnoreResultAssign,
true);
3942 if (!PromotionType.
isNull())
3947Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3948 QualType PromotionType) {
3949 QualType promotionTy = PromotionType.
isNull()
3952 Value *result = VisitImag(E, promotionTy);
3953 if (result && !promotionTy.
isNull())
3954 result = EmitUnPromotedValue(result, E->
getType());
3958Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3959 QualType PromotionType) {
3966 if (!PromotionType.
isNull()) {
3968 Op,
true, IgnoreResultAssign);
3972 return result.second
3988 else if (!PromotionType.
isNull())
3992 if (!PromotionType.
isNull())
3993 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3994 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
4001Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
4002 QualType PromotionType) {
4003 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
4006Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
4007 QualType ExprType) {
4008 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
4011Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
4013 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
4015#define HANDLE_BINOP(OP) \
4017 return Emit##OP(EmitBinOps(BO, PromotionType));
4026 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4029 return VisitImag(UO, PromotionType);
4031 return VisitReal(UO, PromotionType);
4033 return VisitMinus(UO, PromotionType);
4035 return VisitPlus(UO, PromotionType);
4040 auto result = Visit(
const_cast<Expr *
>(E));
4042 if (!PromotionType.
isNull())
4043 return EmitPromotedValue(result, PromotionType);
4045 return EmitUnPromotedValue(result, E->
getType());
4050BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4051 QualType PromotionType) {
4052 TestAndClearIgnoreResultAssign();
4056 if (!PromotionType.
isNull())
4057 Result.Ty = PromotionType;
4066LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4067 const CompoundAssignOperator *E,
4068 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4079 QualType PromotionTypeCR;
4081 if (PromotionTypeCR.
isNull())
4084 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4085 if (!PromotionTypeRHS.
isNull())
4088 OpInfo.RHS = Visit(E->
getRHS());
4089 OpInfo.Ty = PromotionTypeCR;
4096 llvm::PHINode *atomicPHI =
nullptr;
4097 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4099 QualType AtomicValueTy = atomicTy->getValueType();
4108 bool CanEmitAtomicRMW =
4112 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4114 LangOptions::SOB_Trapping;
4115 if (CanEmitAtomicRMW) {
4116 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4117 llvm::Instruction::BinaryOps Op;
4118 switch (OpInfo.Opcode) {
4120 case BO_MulAssign:
case BO_DivAssign:
4126 AtomicOp = llvm::AtomicRMWInst::Add;
4127 Op = llvm::Instruction::Add;
4130 AtomicOp = llvm::AtomicRMWInst::Sub;
4131 Op = llvm::Instruction::Sub;
4134 AtomicOp = llvm::AtomicRMWInst::And;
4135 Op = llvm::Instruction::And;
4138 AtomicOp = llvm::AtomicRMWInst::Xor;
4139 Op = llvm::Instruction::Xor;
4142 AtomicOp = llvm::AtomicRMWInst::Or;
4143 Op = llvm::Instruction::Or;
4146 llvm_unreachable(
"Invalid compound assignment type");
4148 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4150 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4154 llvm::AtomicRMWInst *OldVal =
4159 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4165 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4167 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4168 OpInfo.LHS = CGF.
EmitToMemory(OpInfo.LHS, AtomicValueTy);
4169 Builder.CreateBr(opBB);
4170 Builder.SetInsertPoint(opBB);
4171 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4172 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4173 OpInfo.LHS = atomicPHI;
4176 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4178 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4180 if (!PromotionTypeLHS.
isNull())
4181 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4184 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4195 if (LHSLV.isBitField()) {
4197 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4198 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4200 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4201 Loc, ScalarConversionOpts(CGF.
SanOpts));
4203 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4204 ScalarConversionOpts(CGF.
SanOpts));
4208 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4212 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4213 llvm::Value *
success = Pair.second;
4214 atomicPHI->addIncoming(old, curBlock);
4215 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4216 Builder.SetInsertPoint(contBB);
4224 if (LHSLV.isBitField()) {
4240Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4241 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4242 bool Ignore = TestAndClearIgnoreResultAssign();
4243 Value *RHS =
nullptr;
4244 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4255 if (!LHS.isVolatileQualified())
4259 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4262void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4263 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4264 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4267 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4268 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4269 SanitizerKind::SO_IntegerDivideByZero));
4273 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4274 Ops.Ty->hasSignedIntegerRepresentation() &&
4276 Ops.mayHaveIntegerOverflow() &&
4278 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4281 llvm::Value *IntMin =
4282 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4283 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4285 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4286 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4287 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4289 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4292 if (Checks.size() > 0)
4293 EmitBinOpCheck(Checks, Ops);
4296Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4298 SanitizerDebugLocation SanScope(&CGF,
4299 {SanitizerKind::SO_IntegerDivideByZero,
4300 SanitizerKind::SO_SignedIntegerOverflow,
4301 SanitizerKind::SO_FloatDivideByZero},
4302 SanitizerHandler::DivremOverflow);
4303 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4304 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4305 Ops.Ty->isIntegerType() &&
4306 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4307 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4308 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4309 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4310 Ops.Ty->isRealFloatingType() &&
4311 Ops.mayHaveFloatDivisionByZero()) {
4312 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4313 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4315 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4319 if (Ops.Ty->isConstantMatrixType()) {
4320 llvm::MatrixBuilder MB(Builder);
4327 "first operand must be a matrix");
4329 "second operand must be an arithmetic type");
4330 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4331 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4332 Ops.Ty->hasUnsignedIntegerRepresentation());
4335 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4337 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4338 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4342 else if (Ops.isFixedPointOp())
4343 return EmitFixedPointBinOp(Ops);
4344 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4345 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4347 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4350Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4352 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4353 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4354 Ops.Ty->isIntegerType() &&
4355 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4356 SanitizerDebugLocation SanScope(&CGF,
4357 {SanitizerKind::SO_IntegerDivideByZero,
4358 SanitizerKind::SO_SignedIntegerOverflow},
4359 SanitizerHandler::DivremOverflow);
4360 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4361 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4364 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4365 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4367 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4368 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4370 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4373Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4378 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4379 switch (Ops.Opcode) {
4383 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4384 llvm::Intrinsic::uadd_with_overflow;
4385 OverflowKind = SanitizerHandler::AddOverflow;
4390 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4391 llvm::Intrinsic::usub_with_overflow;
4392 OverflowKind = SanitizerHandler::SubOverflow;
4397 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4398 llvm::Intrinsic::umul_with_overflow;
4399 OverflowKind = SanitizerHandler::MulOverflow;
4402 llvm_unreachable(
"Unsupported operation for overflow detection");
4408 SanitizerDebugLocation SanScope(&CGF,
4409 {SanitizerKind::SO_SignedIntegerOverflow,
4410 SanitizerKind::SO_UnsignedIntegerOverflow},
4416 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4417 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4418 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4421 const std::string *handlerName =
4423 if (handlerName->empty()) {
4429 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4430 llvm::Value *NotOf = Builder.CreateNot(overflow);
4432 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4435 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4438 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4439 llvm::Value *NotOf = Builder.CreateNot(overflow);
4441 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4444 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4449 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4450 llvm::BasicBlock *continueBB =
4454 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4458 Builder.SetInsertPoint(overflowBB);
4461 llvm::Type *Int8Ty = CGF.
Int8Ty;
4462 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4463 llvm::FunctionType *handlerTy =
4464 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4465 llvm::FunctionCallee handler =
4470 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4471 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4475 llvm::Value *handlerArgs[] = {
4478 Builder.getInt8(OpID),
4481 llvm::Value *handlerResult =
4485 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4486 Builder.CreateBr(continueBB);
4488 Builder.SetInsertPoint(continueBB);
4489 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4490 phi->addIncoming(result, initialBB);
4491 phi->addIncoming(handlerResult, overflowBB);
4500 bool isSubtraction) {
4505 Value *pointer = op.LHS;
4506 Expr *pointerOperand =
expr->getLHS();
4508 Expr *indexOperand =
expr->getRHS();
4511 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4512 std::swap(pointer,
index);
4513 std::swap(pointerOperand, indexOperand);
4517 index, isSubtraction);
4523 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4527 auto &DL =
CGM.getDataLayout();
4550 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4552 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4553 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4554 PtrTy->getPointerAddressSpace()))
4557 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4558 auto CheckHandler = SanitizerHandler::PointerOverflow;
4560 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4562 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4563 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4565 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4566 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4571 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4582 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4592 llvm::Value *objectSize =
4598 return Builder.CreateBitCast(result, pointer->getType());
4603 getContext().getAsVariableArrayType(elementType)) {
4605 llvm::Value *numElements =
getVLASize(vla).NumElts;
4614 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4634 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4647 bool negMul,
bool negAdd) {
4648 Value *MulOp0 = MulOp->getOperand(0);
4649 Value *MulOp1 = MulOp->getOperand(1);
4651 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4653 Addend = Builder.CreateFNeg(Addend,
"neg");
4655 Value *FMulAdd =
nullptr;
4656 if (Builder.getIsFPConstrained()) {
4658 "Only constrained operation should be created when Builder is in FP "
4659 "constrained mode");
4660 FMulAdd = Builder.CreateConstrainedFPCall(
4661 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4663 {MulOp0, MulOp1, Addend});
4665 FMulAdd = Builder.CreateCall(
4667 {MulOp0, MulOp1, Addend});
4669 MulOp->eraseFromParent();
4684 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4685 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4686 "Only fadd/fsub can be the root of an fmuladd.");
4689 if (!op.FPFeatures.allowFPContractWithinStatement())
4692 Value *LHS = op.LHS;
4693 Value *RHS = op.RHS;
4697 bool NegLHS =
false;
4698 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4699 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4700 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4701 LHS = LHSUnOp->getOperand(0);
4706 bool NegRHS =
false;
4707 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4708 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4709 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4710 RHS = RHSUnOp->getOperand(0);
4718 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4719 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4720 (LHSBinOp->use_empty() || NegLHS)) {
4724 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4727 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4728 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4729 (RHSBinOp->use_empty() || NegRHS)) {
4733 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4737 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4738 if (LHSBinOp->getIntrinsicID() ==
4739 llvm::Intrinsic::experimental_constrained_fmul &&
4740 (LHSBinOp->use_empty() || NegLHS)) {
4744 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4747 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4748 if (RHSBinOp->getIntrinsicID() ==
4749 llvm::Intrinsic::experimental_constrained_fmul &&
4750 (RHSBinOp->use_empty() || NegRHS)) {
4754 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4761Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4762 if (op.LHS->getType()->isPointerTy() ||
4763 op.RHS->getType()->isPointerTy())
4766 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4767 op.Ty->isUnsignedIntegerType()) {
4768 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4770 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4771 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4772 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4773 case LangOptions::OB_Wrap:
4774 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4775 case LangOptions::OB_SignedAndDefined:
4777 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4779 case LangOptions::OB_Unset:
4781 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4782 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4784 case LangOptions::OB_Trap:
4785 if (CanElideOverflowCheck(CGF.
getContext(), op))
4786 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4787 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4788 return EmitOverflowCheckedBinOp(op);
4793 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4794 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4800 if (op.Ty->isConstantMatrixType()) {
4801 llvm::MatrixBuilder MB(Builder);
4802 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4803 return MB.CreateAdd(op.LHS, op.RHS);
4806 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4807 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4808 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4811 if (op.isFixedPointOp())
4812 return EmitFixedPointBinOp(op);
4814 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4819Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4821 using llvm::ConstantInt;
4827 QualType ResultTy = op.Ty;
4828 QualType LHSTy, RHSTy;
4829 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4830 RHSTy = BinOp->getRHS()->getType();
4831 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4836 LHSTy = CAO->getComputationLHSType();
4837 ResultTy = CAO->getComputationResultType();
4839 LHSTy = BinOp->getLHS()->getType();
4840 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4841 LHSTy = UnOp->getSubExpr()->getType();
4842 RHSTy = UnOp->getSubExpr()->getType();
4845 Value *LHS = op.LHS;
4846 Value *RHS = op.RHS;
4851 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4855 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4856 switch (op.Opcode) {
4859 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4863 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4867 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4871 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4875 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4879 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4882 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4884 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4886 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4888 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4893 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4895 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4899 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4912 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4918 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4923Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4925 if (!op.LHS->getType()->isPointerTy()) {
4926 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4927 op.Ty->isUnsignedIntegerType()) {
4928 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4930 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4931 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4932 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4933 case LangOptions::OB_Wrap:
4934 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4935 case LangOptions::OB_SignedAndDefined:
4937 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4939 case LangOptions::OB_Unset:
4941 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4942 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4944 case LangOptions::OB_Trap:
4945 if (CanElideOverflowCheck(CGF.
getContext(), op))
4946 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4947 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4948 return EmitOverflowCheckedBinOp(op);
4953 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4954 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4960 if (op.Ty->isConstantMatrixType()) {
4961 llvm::MatrixBuilder MB(Builder);
4962 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4963 return MB.CreateSub(op.LHS, op.RHS);
4966 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4967 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4968 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4971 if (op.isFixedPointOp())
4972 return EmitFixedPointBinOp(op);
4974 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4979 if (!op.RHS->getType()->isPointerTy())
4989 LHS = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4990 RHS = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4992 LHS = Builder.CreatePtrToAddr(op.LHS,
"sub.ptr.lhs.cast");
4993 RHS = Builder.CreatePtrToAddr(op.RHS,
"sub.ptr.rhs.cast");
4995 LHS = Builder.CreateZExtOrTrunc(LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
4997 RHS = Builder.CreateZExtOrTrunc(RHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
4999 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
5003 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
5005 llvm::Value *divisor =
nullptr;
5008 if (
const VariableArrayType *vla
5011 elementType = VlaSize.Type;
5012 divisor = VlaSize.NumElts;
5016 if (!eltSize.
isOne())
5023 CharUnits elementSize;
5032 if (elementSize.
isOne())
5039 return Builder.CreateSDiv(diffInChars, divisor,
"sub.ptr.div");
5043 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5046Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5048 llvm::IntegerType *Ty;
5049 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5057 llvm::Type *RHSTy = RHS->
getType();
5058 llvm::APInt RHSMax =
5059 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5060 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5061 if (RHSMax.ult(Ty->getBitWidth()))
5062 return llvm::ConstantInt::get(RHSTy, RHSMax);
5063 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5067 const Twine &Name) {
5068 llvm::IntegerType *Ty;
5069 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5074 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5075 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5077 return Builder.CreateURem(
5078 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5081Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5083 if (Ops.isFixedPointOp())
5084 return EmitFixedPointBinOp(Ops);
5088 Value *RHS = Ops.RHS;
5089 if (Ops.LHS->getType() != RHS->
getType())
5090 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5092 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5093 Ops.Ty->hasSignedIntegerRepresentation() &&
5096 bool SanitizeUnsignedBase =
5097 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5098 Ops.Ty->hasUnsignedIntegerRepresentation();
5099 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5100 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5103 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5104 else if ((SanitizeBase || SanitizeExponent) &&
5106 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5107 if (SanitizeSignedBase)
5108 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5109 if (SanitizeUnsignedBase)
5110 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5111 if (SanitizeExponent)
5112 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5114 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5115 SanitizerHandler::ShiftOutOfBounds);
5116 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5117 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5118 llvm::Value *WidthMinusOne =
5119 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5120 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5122 if (SanitizeExponent) {
5124 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5131 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5134 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5135 llvm::Value *PromotedWidthMinusOne =
5136 (RHS == Ops.RHS) ? WidthMinusOne
5137 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5139 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5140 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5149 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5150 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5152 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5153 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5155 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5156 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5157 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5158 Checks.push_back(std::make_pair(
5159 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5160 : SanitizerKind::SO_UnsignedShiftBase));
5163 assert(!Checks.empty());
5164 EmitBinOpCheck(Checks, Ops);
5167 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5170Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5172 if (Ops.isFixedPointOp())
5173 return EmitFixedPointBinOp(Ops);
5177 Value *RHS = Ops.RHS;
5178 if (Ops.LHS->getType() != RHS->
getType())
5179 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5183 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5184 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5186 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5187 SanitizerHandler::ShiftOutOfBounds);
5188 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5189 llvm::Value *
Valid = Builder.CreateICmpULE(
5190 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5191 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5194 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5195 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5196 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5204 default: llvm_unreachable(
"unexpected element type");
5205 case BuiltinType::Char_U:
5206 case BuiltinType::UChar:
5207 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5208 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5209 case BuiltinType::Char_S:
5210 case BuiltinType::SChar:
5211 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5212 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5213 case BuiltinType::UShort:
5214 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5215 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5216 case BuiltinType::Short:
5217 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5218 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5219 case BuiltinType::UInt:
5220 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5221 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5222 case BuiltinType::Int:
5223 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5224 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5225 case BuiltinType::ULong:
5226 case BuiltinType::ULongLong:
5227 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5228 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5229 case BuiltinType::Long:
5230 case BuiltinType::LongLong:
5231 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5232 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5233 case BuiltinType::Float:
5234 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5235 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5236 case BuiltinType::Double:
5237 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5238 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5239 case BuiltinType::UInt128:
5240 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5241 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5242 case BuiltinType::Int128:
5243 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5244 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5248Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5249 llvm::CmpInst::Predicate UICmpOpc,
5250 llvm::CmpInst::Predicate SICmpOpc,
5251 llvm::CmpInst::Predicate FCmpOpc,
5253 TestAndClearIgnoreResultAssign();
5257 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5263 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5265 BinOpInfo BOInfo = EmitBinOps(E);
5266 Value *LHS = BOInfo.LHS;
5267 Value *RHS = BOInfo.RHS;
5273 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5275 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5278 Value *FirstVecArg = LHS,
5279 *SecondVecArg = RHS;
5281 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5285 default: llvm_unreachable(
"is not a comparison operation");
5297 std::swap(FirstVecArg, SecondVecArg);
5304 if (ElementKind == BuiltinType::Float) {
5306 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5307 std::swap(FirstVecArg, SecondVecArg);
5315 if (ElementKind == BuiltinType::Float) {
5317 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5322 std::swap(FirstVecArg, SecondVecArg);
5327 Value *CR6Param = Builder.getInt32(CR6);
5329 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5337 if (ResultTy->getBitWidth() > 1 &&
5339 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5344 if (BOInfo.isFixedPointOp()) {
5345 Result = EmitFixedPointBinOp(BOInfo);
5346 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5347 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5349 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5351 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5353 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5368 LHS = Builder.CreateStripInvariantGroup(LHS);
5370 RHS = Builder.CreateStripInvariantGroup(RHS);
5373 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5379 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5385 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5387 CETy = CTy->getElementType();
5389 LHS.first = Visit(E->
getLHS());
5390 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5393 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5396 CTy->getElementType()) &&
5397 "The element types must always match.");
5400 RHS.first = Visit(E->
getRHS());
5401 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5403 "The element types must always match.");
5406 Value *ResultR, *ResultI;
5410 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5411 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5415 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5416 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5420 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5423 "Complex comparison other than == or != ?");
5424 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5436 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5437 CastKind Kind = ICE->getCastKind();
5438 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5439 *SrcType = ICE->getSubExpr()->getType();
5452 bool Ignore = TestAndClearIgnoreResultAssign();
5486 RHS = Visit(E->
getRHS());
5502 RHS = Visit(E->
getRHS());
5542 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5545Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5556 if (LHS->
getType()->isFPOrFPVectorTy()) {
5557 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5559 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5560 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5562 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5563 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5565 Value *
And = Builder.CreateAnd(LHS, RHS);
5566 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5570 llvm::Type *ResTy = ConvertType(E->
getType());
5589 if (InstrumentRegions &&
5593 llvm::BasicBlock *RHSSkip =
5596 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5613 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5624 return llvm::Constant::getNullValue(ResTy);
5635 llvm::BasicBlock *LHSFalseBlock =
5638 CodeGenFunction::ConditionalEvaluation eval(CGF);
5653 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5655 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5657 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5666 RHSBlock = Builder.GetInsertBlock();
5671 llvm::BasicBlock *ContIncoming = RHSBlock;
5672 if (InstrumentRegions &&
5676 llvm::BasicBlock *RHSBlockSkip =
5678 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5682 PN->addIncoming(RHSCond, RHSBlockCnt);
5687 ContIncoming = RHSBlockSkip;
5698 PN->addIncoming(RHSCond, ContIncoming);
5707 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5711 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5714Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5725 if (LHS->
getType()->isFPOrFPVectorTy()) {
5726 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5728 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5729 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5731 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5732 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5734 Value *
Or = Builder.CreateOr(LHS, RHS);
5735 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5739 llvm::Type *ResTy = ConvertType(E->
getType());
5758 if (InstrumentRegions &&
5762 llvm::BasicBlock *RHSSkip =
5765 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5782 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5793 return llvm::ConstantInt::get(ResTy, 1);
5803 llvm::BasicBlock *LHSTrueBlock =
5806 CodeGenFunction::ConditionalEvaluation eval(CGF);
5822 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5824 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5826 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5838 RHSBlock = Builder.GetInsertBlock();
5843 llvm::BasicBlock *ContIncoming = RHSBlock;
5844 if (InstrumentRegions &&
5848 llvm::BasicBlock *RHSTrueBlock =
5850 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5854 PN->addIncoming(RHSCond, RHSBlockCnt);
5859 ContIncoming = RHSTrueBlock;
5866 PN->addIncoming(RHSCond, ContIncoming);
5873 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5876Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5879 return Visit(E->
getRHS());
5904Value *ScalarExprEmitter::
5905VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5906 TestAndClearIgnoreResultAssign();
5909 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5911 Expr *condExpr = E->
getCond();
5919 Expr *live = lhsExpr, *dead = rhsExpr;
5920 if (!CondExprBool) std::swap(live, dead);
5947 llvm::Value *LHS = Visit(lhsExpr);
5948 llvm::Value *RHS = Visit(rhsExpr);
5950 llvm::Type *condType = ConvertType(condExpr->
getType());
5953 unsigned numElem = vecTy->getNumElements();
5954 llvm::Type *elemType = vecTy->getElementType();
5956 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5957 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5958 llvm::Value *tmp = Builder.CreateSExt(
5959 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5960 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5963 llvm::Value *RHSTmp = RHS;
5964 llvm::Value *LHSTmp = LHS;
5965 bool wasCast =
false;
5967 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5968 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5969 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5973 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5974 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5975 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5977 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5987 llvm::Value *LHS = Visit(lhsExpr);
5988 llvm::Value *RHS = Visit(rhsExpr);
5990 llvm::Type *CondType = ConvertType(condExpr->
getType());
5993 if (VecTy->getElementType()->isIntegerTy(1))
5994 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5997 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5999 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
6001 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
6002 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
6012 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
6016 llvm::Value *LHS = Visit(lhsExpr);
6017 llvm::Value *RHS = Visit(rhsExpr);
6020 assert(!RHS &&
"LHS and RHS types must match");
6023 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6034 CodeGenFunction::ConditionalEvaluation eval(CGF);
6048 Value *LHS = Visit(lhsExpr);
6051 LHSBlock = Builder.GetInsertBlock();
6052 Builder.CreateBr(ContBlock);
6064 Value *RHS = Visit(rhsExpr);
6067 RHSBlock = Builder.GetInsertBlock();
6077 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6078 PN->addIncoming(LHS, LHSBlock);
6079 PN->addIncoming(RHS, RHSBlock);
6084Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6088Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6090 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6095Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6101 Value *Src,
unsigned NumElementsDst) {
6102 static constexpr int Mask[] = {0, 1, 2, -1};
6103 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6123 const llvm::DataLayout &DL,
6124 Value *Src, llvm::Type *DstTy,
6125 StringRef Name =
"") {
6129 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6130 return Builder.CreateBitCast(Src, DstTy, Name);
6133 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6134 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6137 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6139 if (!DstTy->isIntegerTy())
6140 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6142 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6146 if (!SrcTy->isIntegerTy())
6147 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6149 return Builder.CreateIntToPtr(Src, DstTy, Name);
6152Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6154 llvm::Type *DstTy = ConvertType(E->
getType());
6156 llvm::Type *SrcTy = Src->
getType();
6157 unsigned NumElementsSrc =
6161 unsigned NumElementsDst =
6172 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6177 Src->setName(
"astype");
6184 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6185 auto *Vec4Ty = llvm::FixedVectorType::get(
6191 Src->setName(
"astype");
6196 Src, DstTy,
"astype");
6199Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6211 "Invalid scalar expression to emit");
6213 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6214 .Visit(
const_cast<Expr *
>(E));
6223 "Invalid scalar expression to emit");
6224 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6234 "Invalid complex -> scalar conversion");
6235 return ScalarExprEmitter(*
this)
6236 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6243 if (!PromotionType.
isNull())
6244 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6246 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6252 bool isInc,
bool isPre) {
6253 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6263 llvm::Type *BaseTy =
6279 ScalarExprEmitter Scalar(*
this);
6282#define COMPOUND_OP(Op) \
6283 case BO_##Op##Assign: \
6284 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6321 llvm_unreachable(
"Not valid compound assignment operators");
6324 llvm_unreachable(
"Unhandled compound assignment operator");
6339 llvm::LLVMContext &VMContext,
6345 llvm::Value *TotalOffset =
nullptr;
6351 Value *BasePtr_int =
6352 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6354 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6355 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6356 return {TotalOffset, Builder.getFalse()};
6360 assert(GEP->getPointerOperand() == BasePtr &&
6361 "BasePtr must be the base of the GEP.");
6362 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6364 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6367 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6368 auto *SAddIntrinsic =
6369 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6370 auto *SMulIntrinsic =
6371 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6374 llvm::Value *OffsetOverflows = Builder.getFalse();
6378 llvm::Value *RHS) -> llvm::Value * {
6379 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6382 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6383 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6385 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6388 OffsetOverflows = Builder.getTrue();
6389 return llvm::ConstantInt::get(VMContext, N);
6394 auto *ResultAndOverflow = Builder.CreateCall(
6395 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6396 OffsetOverflows = Builder.CreateOr(
6397 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6398 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6402 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6403 GTI != GTE; ++GTI) {
6404 llvm::Value *LocalOffset;
6405 auto *Index = GTI.getOperand();
6407 if (
auto *STy = GTI.getStructTypeOrNull()) {
6411 LocalOffset = llvm::ConstantInt::get(
6412 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6417 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6418 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6419 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6424 if (!TotalOffset || TotalOffset ==
Zero)
6425 TotalOffset = LocalOffset;
6427 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6430 return {TotalOffset, OffsetOverflows};
6435 ArrayRef<Value *> IdxList,
6436 bool SignedIndices,
bool IsSubtraction,
6437 SourceLocation Loc,
const Twine &Name) {
6438 llvm::Type *PtrTy = Ptr->
getType();
6440 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6441 if (!SignedIndices && !IsSubtraction)
6442 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6444 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6447 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6451 bool PerformNullCheck = !NullPointerIsDefined(
6452 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6455 bool PerformOverflowCheck =
6458 if (!(PerformNullCheck || PerformOverflowCheck))
6461 const auto &DL = CGM.getDataLayout();
6463 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6464 auto CheckHandler = SanitizerHandler::PointerOverflow;
6465 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6466 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6468 GEPOffsetAndOverflow EvaluatedGEP =
6471 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6481 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6482 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6484 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6488 if (PerformNullCheck) {
6496 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6497 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6498 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6499 Checks.emplace_back(
Valid, CheckOrdinal);
6502 if (PerformOverflowCheck) {
6507 llvm::Value *ValidGEP;
6508 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6509 if (SignedIndices) {
6515 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6516 auto *PosOrZeroOffset =
6518 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6520 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6521 }
else if (!IsSubtraction) {
6526 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6532 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6534 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6535 Checks.emplace_back(ValidGEP, CheckOrdinal);
6538 assert(!Checks.empty() &&
"Should have produced some checks.");
6540 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6542 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6543 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6549 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6550 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6551 const Twine &Name) {
6552 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6553 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6554 if (!SignedIndices && !IsSubtraction)
6555 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6557 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6561 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6562 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6563 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static mlir::Value tryEmitFMulAdd(mlir::Location loc, const BinOpInfo &op, CIRGenBuilderTy &builder, bool isSub=false)
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static mlir::Value buildFMulAdd(mlir::Location addLoc, cir::FMulOp mulOp, mlir::Value addend, CIRGenBuilderTy &builder, bool negMul, bool negAdd)
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
Result
Implement __builtin_bit_cast and related operations.
Defines AST-level helper utilities for matrix types.
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
@ UseSkipPath
Skip (false)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
bool hasSkipCounter(const Stmt *S) const
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
void markStmtAsUsed(bool Skipped, const Stmt *S)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isMCDCDecisionExpr(const Expr *E) const
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
const Qualifiers & getQuals() const
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned mapRowMajorToColumnMajorFlattenedIndex(unsigned RowMajorIdx) const
Given a row-major flattened index RowMajorIdx, return the equivalent column-major flattened index.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
bool isSignedOverflowDefined() const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
PRESERVE_NONE bool Ret(InterpState &S)
@ Address
A pointer to a ValueDecl.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
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.