35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
201 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
206 switch (OBT->getBehaviorKind()) {
207 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
209 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
212 llvm_unreachable(
"Unknown OverflowBehaviorKind");
219 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
227 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
231static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
233 "Expected a unary or binary operator");
237 if (!Op.mayHaveIntegerOverflow())
244 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
245 if (BO && BO->hasExcludedOverflowPattern())
248 if (Op.Ty.isWrapType())
250 if (Op.Ty.isTrapType())
253 if (Op.Ty->isSignedIntegerType() &&
259 if (Op.Ty->isUnsignedIntegerType() &&
284 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
290 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
291 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
295class ScalarExprEmitter
297 CodeGenFunction &CGF;
298 CGBuilderTy &Builder;
299 bool IgnoreResultAssign;
300 llvm::LLVMContext &VMContext;
303 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
304 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
305 VMContext(cgf.getLLVMContext()) {
312 bool TestAndClearIgnoreResultAssign() {
313 bool I = IgnoreResultAssign;
314 IgnoreResultAssign =
false;
318 llvm::Type *ConvertType(QualType T) {
return CGF.
ConvertType(T); }
319 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
325 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
326 const BinOpInfo &Info);
328 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
332 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
333 const AlignValueAttr *AVAttr =
nullptr;
334 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
335 const ValueDecl *VD = DRE->getDecl();
338 if (
const auto *TTy =
340 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
350 AVAttr = VD->
getAttr<AlignValueAttr>();
355 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
356 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
369 Value *EmitLoadOfLValue(
const Expr *E) {
373 EmitLValueAlignmentAssumption(E,
V);
379 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
383 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
384 Value *Src, QualType SrcType, QualType DstType,
385 llvm::Type *DstTy, SourceLocation Loc);
390 enum ImplicitConversionCheckKind :
unsigned char {
391 ICCK_IntegerTruncation = 0,
392 ICCK_UnsignedIntegerTruncation = 1,
393 ICCK_SignedIntegerTruncation = 2,
394 ICCK_IntegerSignChange = 3,
395 ICCK_SignedIntegerTruncationOrSignChange = 4,
400 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
401 QualType DstType, SourceLocation Loc,
402 bool OBTrapInvolved =
false);
407 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
408 QualType DstType, SourceLocation Loc,
409 bool OBTrapInvolved =
false);
413 struct ScalarConversionOpts {
414 bool TreatBooleanAsSigned;
415 bool EmitImplicitIntegerTruncationChecks;
416 bool EmitImplicitIntegerSignChangeChecks;
418 bool PatternExcluded;
420 ScalarConversionOpts()
421 : TreatBooleanAsSigned(
false),
422 EmitImplicitIntegerTruncationChecks(
false),
423 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
425 ScalarConversionOpts(clang::SanitizerSet SanOpts)
426 : TreatBooleanAsSigned(
false),
427 EmitImplicitIntegerTruncationChecks(
428 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
429 EmitImplicitIntegerSignChangeChecks(
430 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
431 PatternExcluded(
false) {}
433 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
434 llvm::Type *SrcTy, llvm::Type *DstTy,
435 ScalarConversionOpts Opts);
437 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
439 ScalarConversionOpts Opts = ScalarConversionOpts());
443 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
449 QualType SrcTy, QualType DstTy,
453 Value *EmitNullValue(QualType Ty);
458 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
459 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
463 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
466 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
473 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
474 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
480 ZI->eraseFromParent();
485 return Builder.CreateIsNotNull(
V,
"tobool");
492 Value *Visit(Expr *E) {
493 ApplyDebugLocation DL(CGF, E);
494 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
497 Value *VisitStmt(Stmt *S) {
499 llvm_unreachable(
"Stmt can't have complex result type!");
501 Value *VisitExpr(Expr *S);
503 Value *VisitConstantExpr(ConstantExpr *E) {
509 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
524 Value *VisitParenExpr(ParenExpr *PE) {
527 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
530 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
531 return Visit(
GE->getResultExpr());
533 Value *VisitCoawaitExpr(CoawaitExpr *S) {
536 Value *VisitCoyieldExpr(CoyieldExpr *S) {
539 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
544 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
545 return Builder.getInt(E->
getValue());
547 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
548 return Builder.getInt(E->
getValue());
550 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
551 return llvm::ConstantFP::get(VMContext, E->
getValue());
553 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
556 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
559 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
560 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
562 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
563 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
565 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
569 return EmitNullValue(E->
getType());
571 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
572 return EmitNullValue(E->
getType());
574 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
575 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
576 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
578 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
581 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
585 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
589 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
590 Value *VisitEmbedExpr(EmbedExpr *E);
592 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
601 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
602 llvm_unreachable(
"Codegen for this isn't defined/implemented");
606 Value *VisitDeclRefExpr(DeclRefExpr *E) {
609 return EmitLoadOfLValue(E);
612 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
615 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
618 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
619 return EmitLoadOfLValue(E);
621 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
624 return EmitLoadOfLValue(E);
628 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
634 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
640 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
645 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
646 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
647 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
648 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
649 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
650 Value *VisitMemberExpr(MemberExpr *E);
651 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
652 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
653 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
659 return EmitLoadOfLValue(E);
662 Value *VisitInitListExpr(InitListExpr *E);
664 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
666 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
670 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
671 return EmitNullValue(E->
getType());
673 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
675 return VisitCastExpr(E);
679 Value *VisitCallExpr(
const CallExpr *E) {
681 return EmitLoadOfLValue(E);
685 EmitLValueAlignmentAssumption(E,
V);
689 Value *VisitStmtExpr(
const StmtExpr *E);
692 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
694 return EmitScalarPrePostIncDec(E, LV,
false,
false);
696 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
698 return EmitScalarPrePostIncDec(E, LV,
true,
false);
700 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
702 return EmitScalarPrePostIncDec(E, LV,
false,
true);
704 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
706 return EmitScalarPrePostIncDec(E, LV,
true,
true);
709 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
713 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
714 bool isInc,
bool isPre);
717 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
721 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
723 Value *VisitUnaryDeref(
const UnaryOperator *E) {
726 return EmitLoadOfLValue(E);
729 Value *VisitUnaryPlus(
const UnaryOperator *E,
730 QualType PromotionType = QualType());
731 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
732 Value *VisitUnaryMinus(
const UnaryOperator *E,
733 QualType PromotionType = QualType());
734 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
736 Value *VisitUnaryNot (
const UnaryOperator *E);
737 Value *VisitUnaryLNot (
const UnaryOperator *E);
738 Value *VisitUnaryReal(
const UnaryOperator *E,
739 QualType PromotionType = QualType());
740 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
741 Value *VisitUnaryImag(
const UnaryOperator *E,
742 QualType PromotionType = QualType());
743 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
744 Value *VisitUnaryExtension(
const UnaryOperator *E) {
749 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
750 return EmitLoadOfLValue(E);
752 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
760 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
761 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
764 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
765 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
768 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
772 Value *VisitExprWithCleanups(ExprWithCleanups *E);
773 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
776 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
781 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
783 return llvm::ConstantInt::get(ConvertType(E->
getType()),
786 return llvm::ConstantInt::get(ConvertType(E->
getType()),
790 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
798 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
799 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
802 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
803 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
806 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
816 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
817 return EmitNullValue(E->
getType());
820 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
825 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
826 return Builder.getInt1(E->
getValue());
830 Value *EmitMul(
const BinOpInfo &Ops) {
831 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
832 Ops.Ty->isUnsignedIntegerType()) {
833 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
835 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
836 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
837 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
838 case LangOptions::OB_Wrap:
839 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
840 case LangOptions::OB_SignedAndDefined:
842 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
844 case LangOptions::OB_Unset:
846 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
847 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
849 case LangOptions::OB_Trap:
850 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
851 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
852 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
853 return EmitOverflowCheckedBinOp(Ops);
857 if (Ops.Ty->isConstantMatrixType()) {
858 llvm::MatrixBuilder MB(Builder);
862 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
863 BO->getLHS()->getType().getCanonicalType());
864 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
865 BO->getRHS()->getType().getCanonicalType());
866 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
867 if (LHSMatTy && RHSMatTy)
868 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
869 LHSMatTy->getNumColumns(),
870 RHSMatTy->getNumColumns());
871 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
874 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
876 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
877 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
879 if (Ops.isFixedPointOp())
880 return EmitFixedPointBinOp(Ops);
881 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
885 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
888 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
889 llvm::Value *
Zero,
bool isDiv);
891 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
897 Value *EmitDiv(
const BinOpInfo &Ops);
898 Value *EmitRem(
const BinOpInfo &Ops);
899 Value *EmitAdd(
const BinOpInfo &Ops);
900 Value *EmitSub(
const BinOpInfo &Ops);
901 Value *EmitShl(
const BinOpInfo &Ops);
902 Value *EmitShr(
const BinOpInfo &Ops);
903 Value *EmitAnd(
const BinOpInfo &Ops) {
904 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
906 Value *EmitXor(
const BinOpInfo &Ops) {
907 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
909 Value *EmitOr (
const BinOpInfo &Ops) {
910 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
914 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
916 BinOpInfo EmitBinOps(
const BinaryOperator *E,
917 QualType PromotionTy = QualType());
919 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
920 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
921 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
923 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
924 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
927 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
928 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
930 QualType getPromotionType(QualType Ty) {
932 if (
auto *CT = Ty->
getAs<ComplexType>()) {
933 QualType ElementType = CT->getElementType();
939 if (
auto *VT = Ty->
getAs<VectorType>()) {
940 unsigned NumElements = VT->getNumElements();
950#define HANDLEBINOP(OP) \
951 Value *VisitBin##OP(const BinaryOperator *E) { \
952 QualType promotionTy = getPromotionType(E->getType()); \
953 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
954 if (result && !promotionTy.isNull()) \
955 result = EmitUnPromotedValue(result, E->getType()); \
958 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
959 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
960 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
976 llvm::CmpInst::Predicate SICmpOpc,
977 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
978#define VISITCOMP(CODE, UI, SI, FP, SIG) \
979 Value *VisitBin##CODE(const BinaryOperator *E) { \
980 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
981 llvm::FCmpInst::FP, SIG); }
982 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
996 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
997 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
999 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1004 Value *VisitBlockExpr(
const BlockExpr *BE);
1005 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1006 Value *VisitChooseExpr(ChooseExpr *CE);
1007 Value *VisitVAArgExpr(VAArgExpr *VE);
1008 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1011 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1014 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1017 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1020 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1021 Value *VisitAtomicExpr(AtomicExpr *AE);
1022 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1035 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1038 return EmitFloatToBoolConversion(Src);
1040 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1044 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1048 "Unknown scalar type to convert");
1051 return EmitIntToBoolConversion(Src);
1054 return EmitPointerToBoolConversion(Src, SrcType);
1057void ScalarExprEmitter::EmitFloatConversionCheck(
1058 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1059 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1060 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1064 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1065 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1066 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1067 using llvm::APFloat;
1070 llvm::Value *Check =
nullptr;
1071 const llvm::fltSemantics &SrcSema =
1081 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1082 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1083 APFloat::opOverflow)
1086 MinSrc = APFloat::getInf(SrcSema,
true);
1090 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1093 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1094 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1095 APFloat::opOverflow)
1098 MaxSrc = APFloat::getInf(SrcSema,
false);
1102 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1107 const llvm::fltSemantics &Sema =
1110 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1111 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1115 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1117 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1118 Check = Builder.CreateAnd(GE, LE);
1123 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1129static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1130 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1133 llvm::Type *SrcTy = Src->
getType();
1134 llvm::Type *DstTy = Dst->
getType();
1139 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1141 "non-integer llvm type");
1148 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1150 if (!SrcSigned && !DstSigned) {
1151 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1152 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1154 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1155 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1158 llvm::Value *Check =
nullptr;
1160 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1162 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1164 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1172void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1173 Value *Dst, QualType DstType,
1175 bool OBTrapInvolved) {
1176 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1186 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1187 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1189 if (SrcBits <= DstBits)
1192 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1199 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1200 (!SrcSigned && DstSigned))
1203 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1204 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1207 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1212 SanitizerDebugLocation SanScope(
1214 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1215 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1231 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1239 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1240 if (OBT->isWrapKind())
1243 if (ignoredBySanitizer && !OBTrapInvolved)
1246 llvm::Constant *StaticArgs[] = {
1249 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1250 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1252 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1259 llvm::Type *VTy =
V->getType();
1262 return llvm::ConstantInt::getFalse(VTy->getContext());
1264 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1265 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1266 llvm::Twine(Name) +
"." +
V->getName() +
1267 ".negativitycheck");
1272static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1273 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1276 llvm::Type *SrcTy = Src->
getType();
1277 llvm::Type *DstTy = Dst->
getType();
1280 "non-integer llvm type");
1286 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1287 unsigned DstBits = DstTy->getScalarSizeInBits();
1291 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1292 "either the widths should be different, or the signednesses.");
1295 llvm::Value *SrcIsNegative =
1298 llvm::Value *DstIsNegative =
1304 llvm::Value *Check =
nullptr;
1305 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1307 return std::make_pair(
1308 ScalarExprEmitter::ICCK_IntegerSignChange,
1309 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1312void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1313 Value *Dst, QualType DstType,
1315 bool OBTrapInvolved) {
1316 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1320 llvm::Type *SrcTy = Src->
getType();
1321 llvm::Type *DstTy = Dst->
getType();
1331 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1332 unsigned DstBits = DstTy->getScalarSizeInBits();
1339 if (SrcSigned == DstSigned && SrcBits == DstBits)
1343 if (!SrcSigned && !DstSigned)
1348 if ((DstBits > SrcBits) && DstSigned)
1350 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1351 (SrcBits > DstBits) && SrcSigned) {
1360 if (!OBTrapInvolved) {
1363 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1367 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1372 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1373 SanitizerDebugLocation SanScope(
1375 {SanitizerKind::SO_ImplicitIntegerSignChange,
1376 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1377 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1380 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1381 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1385 ImplicitConversionCheckKind CheckKind;
1386 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1393 CheckKind = Check.first;
1394 Checks.emplace_back(Check.second);
1396 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1397 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1403 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1404 Checks.emplace_back(Check.second);
1408 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1409 if (OBTrapInvolved) {
1410 llvm::Value *Combined = Check.second.first;
1411 for (
const auto &
C : Checks)
1412 Combined = Builder.CreateAnd(Combined,
C.first);
1418 llvm::Constant *StaticArgs[] = {
1421 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1422 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1424 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1429static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1430 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1436 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1437 if (!SrcSigned && !DstSigned)
1438 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1440 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1442 llvm::Value *Check =
nullptr;
1444 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1446 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1449 return std::make_pair(
1451 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1456static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1457 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1461 llvm::Value *SrcIsNegative =
1464 llvm::Value *DstIsNegative =
1470 llvm::Value *Check =
nullptr;
1472 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1474 return std::make_pair(
1475 ScalarExprEmitter::ICCK_IntegerSignChange,
1476 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1484 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1502 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1503 unsigned DstBits = Info.
Size;
1508 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1510 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1512 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1513 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1517 bool EmitTruncation = DstBits < SrcBits;
1521 bool EmitTruncationFromUnsignedToSigned =
1522 EmitTruncation && DstSigned && !SrcSigned;
1524 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1525 bool BothUnsigned = !SrcSigned && !DstSigned;
1526 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1533 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1538 else if (EmitSignChange) {
1539 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1540 "either the widths should be different, or the signednesses.");
1546 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1547 if (EmitTruncationFromUnsignedToSigned)
1548 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1550 llvm::Constant *StaticArgs[] = {
1553 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1554 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1556 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1560 QualType DstType, llvm::Type *SrcTy,
1562 ScalarConversionOpts Opts) {
1564 llvm::Type *SrcElementTy;
1565 llvm::Type *DstElementTy;
1575 "cannot cast between matrix and non-matrix types");
1576 SrcElementTy = SrcTy;
1577 DstElementTy = DstTy;
1578 SrcElementType = SrcType;
1579 DstElementType = DstType;
1584 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1589 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1591 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1592 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1596 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1603 llvm::Intrinsic::ID IID =
1604 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1605 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1609 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1610 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1613 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1614 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1615 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1617 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1618 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1619 return Builder.CreateFPExt(Src, DstTy,
"conv");
1624Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1627 ScalarConversionOpts Opts) {
1642 return Builder.CreateIsNotNull(Src,
"tobool");
1645 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1648 "Unhandled scalar conversion from a fixed point type to another type.");
1652 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1655 "Unhandled scalar conversion to a fixed point type from another type.");
1658 QualType NoncanonicalSrcType = SrcType;
1659 QualType NoncanonicalDstType = DstType;
1663 if (SrcType == DstType)
return Src;
1667 llvm::Value *OrigSrc = Src;
1668 QualType OrigSrcType = SrcType;
1669 llvm::Type *SrcTy = Src->
getType();
1673 return EmitConversionToBool(Src, SrcType);
1675 llvm::Type *DstTy = ConvertType(DstType);
1684 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1685 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1686 bool OBTrapInvolved =
1687 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1688 bool OBWrapInvolved =
1689 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1694 if (DstTy->isFloatingPointTy()) {
1697 return Builder.CreateFPExt(BitCast, DstTy,
"conv");
1706 Src = Builder.CreateBitCast(Src, CGF.
CGM.
HalfTy);
1709 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1716 if (SrcTy == DstTy) {
1717 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1718 (OBTrapInvolved && !OBWrapInvolved))
1719 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1720 NoncanonicalDstType, Loc, OBTrapInvolved);
1728 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1733 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1738 llvm::Value* IntResult =
1739 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1741 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1747 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1754 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1756 "Splatted expr doesn't match with vector element type?");
1760 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1764 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1768 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1769 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1770 if (SrcSize == DstSize)
1771 return Builder.CreateBitCast(Src, DstTy,
"conv");
1784 assert(((SrcElementTy->isIntegerTy() &&
1785 DstElementTy->isIntegerTy()) ||
1786 (SrcElementTy->isFloatingPointTy() &&
1787 DstElementTy->isFloatingPointTy())) &&
1788 "unexpected conversion between a floating-point vector and an "
1792 if (SrcElementTy->isIntegerTy())
1793 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1796 if (SrcSize > DstSize)
1797 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1800 return Builder.CreateFPExt(Src, DstTy,
"conv");
1804 Value *Res =
nullptr;
1805 llvm::Type *ResTy = DstTy;
1812 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1814 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1820 if (SrcTy->isFloatingPointTy()) {
1829 assert(DstTy->isIntegerTy(16) &&
1831 "Only half FP requires extra conversion");
1832 return Builder.CreateBitCast(Res, DstTy);
1838 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1840 if (DstTy != ResTy) {
1841 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1844 assert(ResTy->isIntegerTy(16) &&
1846 "Only half FP requires extra conversion");
1847 Res = Builder.CreateBitCast(Res, ResTy);
1851 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1852 !OBWrapInvolved && !Opts.PatternExcluded)
1853 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1854 NoncanonicalDstType, Loc, OBTrapInvolved);
1856 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1857 (OBTrapInvolved && !OBWrapInvolved))
1858 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1859 NoncanonicalDstType, Loc, OBTrapInvolved);
1864Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1866 SourceLocation Loc) {
1867 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1870 Result = FPBuilder.CreateFloatingToFixed(Src,
1873 Result = FPBuilder.CreateFixedToFloating(Src,
1875 ConvertType(DstTy));
1881 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1882 DstFPSema.getWidth(),
1883 DstFPSema.isSigned());
1885 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1888 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1895Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1897 SourceLocation Loc) {
1899 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1904 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1905 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1906 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1913 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1916Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1924void ScalarExprEmitter::EmitBinOpCheck(
1925 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1926 const BinOpInfo &Info) {
1929 SmallVector<llvm::Constant *, 4> StaticData;
1930 SmallVector<llvm::Value *, 2> DynamicData;
1938 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1939 if (UO && UO->
getOpcode() == UO_Minus) {
1940 Check = SanitizerHandler::NegateOverflow;
1942 DynamicData.push_back(Info.RHS);
1946 Check = SanitizerHandler::ShiftOutOfBounds;
1948 StaticData.push_back(
1950 StaticData.push_back(
1952 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1954 Check = SanitizerHandler::DivremOverflow;
1958 int ArithOverflowKind = 0;
1961 Check = SanitizerHandler::AddOverflow;
1962 ArithOverflowKind = diag::UBSanArithKind::Add;
1966 Check = SanitizerHandler::SubOverflow;
1967 ArithOverflowKind = diag::UBSanArithKind::Sub;
1971 Check = SanitizerHandler::MulOverflow;
1972 ArithOverflowKind = diag::UBSanArithKind::Mul;
1976 llvm_unreachable(
"unexpected opcode for bin op check");
1980 SanitizerKind::UnsignedIntegerOverflow) ||
1982 SanitizerKind::SignedIntegerOverflow)) {
1986 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1990 DynamicData.push_back(Info.LHS);
1991 DynamicData.push_back(Info.RHS);
1994 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
2001Value *ScalarExprEmitter::VisitExpr(Expr *E) {
2009ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
2011 unsigned AddrSpace =
2013 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2016 llvm::Type *ExprTy = ConvertType(E->
getType());
2017 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2021Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2023 auto It = E->
begin();
2024 return Builder.getInt((*It)->getValue());
2027Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2035 unsigned LHSElts = LTy->getNumElements();
2043 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2044 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2052 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2053 MTy->getNumElements());
2054 Value* NewV = llvm::PoisonValue::get(RTy);
2055 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2056 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2057 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2059 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2060 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2068 SmallVector<int, 32> Indices;
2072 if (Idx.isSigned() && Idx.isAllOnes())
2073 Indices.push_back(-1);
2075 Indices.push_back(Idx.getZExtValue());
2078 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2081Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2089 if (SrcType == DstType)
return Src;
2092 "ConvertVector source type must be a vector");
2094 "ConvertVector destination type must be a vector");
2096 llvm::Type *SrcTy = Src->
getType();
2097 llvm::Type *DstTy = ConvertType(DstType);
2103 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2104 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2106 assert(SrcTy->isVectorTy() &&
2107 "ConvertVector source IR type must be a vector");
2108 assert(DstTy->isVectorTy() &&
2109 "ConvertVector destination IR type must be a vector");
2114 if (DstEltType->isBooleanType()) {
2115 assert((SrcEltTy->isFloatingPointTy() ||
2118 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2119 if (SrcEltTy->isFloatingPointTy()) {
2120 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2121 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2123 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2128 Value *Res =
nullptr;
2133 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2135 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2137 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2139 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2142 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2143 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2144 if (DstEltType->isSignedIntegerOrEnumerationType())
2145 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2147 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2149 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2150 "Unknown real conversion");
2151 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2152 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2153 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2155 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2161Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2170 return Builder.getInt(
Value);
2174 llvm::Value *
Result = EmitLoadOfLValue(E);
2180 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2181 if (llvm::GetElementPtrInst *GEP =
2182 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2183 if (llvm::Instruction *
Pointer =
2184 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2196Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2197 TestAndClearIgnoreResultAssign();
2205 return EmitLoadOfLValue(E);
2213 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2216 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2219Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2220 MatrixSingleSubscriptExpr *E) {
2221 TestAndClearIgnoreResultAssign();
2224 unsigned NumRows = MatrixTy->getNumRows();
2225 unsigned NumColumns = MatrixTy->getNumColumns();
2229 llvm::MatrixBuilder MB(Builder);
2233 MB.CreateIndexAssumption(RowIdx, NumRows);
2237 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2238 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2240 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2241 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2242 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2243 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2244 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2245 IsMatrixRowMajor,
"matrix_row_idx");
2247 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2248 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2249 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2255Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2256 TestAndClearIgnoreResultAssign();
2264 llvm::MatrixBuilder MB(Builder);
2267 unsigned NumCols = MatrixTy->getNumColumns();
2268 unsigned NumRows = MatrixTy->getNumRows();
2269 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2270 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2271 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2274 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2279 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2284 int MV = SVI->getMaskValue(Idx);
2291 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2292 "Index operand too large for shufflevector mask!");
2293 return C->getZExtValue();
2296Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2297 bool Ignore = TestAndClearIgnoreResultAssign();
2300 assert((Ignore ==
false ||
2302 "init list ignored");
2319 llvm::VectorType *VType =
2320 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2323 if (NumInitElements == 0) {
2325 return EmitNullValue(E->
getType());
2332 if (NumInitElements == 0) {
2334 return EmitNullValue(E->
getType());
2337 if (NumInitElements == 1) {
2338 Expr *InitVector = E->
getInit(0);
2343 return Visit(InitVector);
2346 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2353 const ConstantMatrixType *ColMajorMT =
nullptr;
2354 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2355 MT && CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2356 LangOptions::MatrixMemoryLayout::MatrixColMajor)
2364 unsigned CurIdx = 0;
2365 bool VIsPoisonShuffle =
false;
2366 llvm::Value *
V = llvm::PoisonValue::get(VType);
2367 for (
unsigned i = 0; i != NumInitElements; ++i) {
2370 SmallVector<int, 16> Args;
2372 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2382 ->getNumElements() == ResElts) {
2384 Value *LHS =
nullptr, *RHS =
nullptr;
2389 Args.resize(ResElts, -1);
2391 LHS = EI->getVectorOperand();
2393 VIsPoisonShuffle =
true;
2394 }
else if (VIsPoisonShuffle) {
2397 for (
unsigned j = 0; j != CurIdx; ++j)
2399 Args.push_back(ResElts +
C->getZExtValue());
2400 Args.resize(ResElts, -1);
2403 RHS = EI->getVectorOperand();
2404 VIsPoisonShuffle =
false;
2406 if (!Args.empty()) {
2407 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2413 unsigned InsertIdx =
2417 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2419 VIsPoisonShuffle =
false;
2429 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2432 Value *SVOp = SVI->getOperand(0);
2435 if (OpTy->getNumElements() == ResElts) {
2436 for (
unsigned j = 0; j != CurIdx; ++j) {
2439 if (VIsPoisonShuffle) {
2445 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2447 Args.resize(ResElts, -1);
2449 if (VIsPoisonShuffle)
2459 for (
unsigned j = 0; j != InitElts; ++j)
2461 Args.resize(ResElts, -1);
2462 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2465 for (
unsigned j = 0; j != CurIdx; ++j)
2467 for (
unsigned j = 0; j != InitElts; ++j)
2468 Args.push_back(j + Offset);
2469 Args.resize(ResElts, -1);
2476 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2483 llvm::Type *EltTy = VType->getElementType();
2486 for (; CurIdx < ResElts; ++CurIdx) {
2487 unsigned InsertIdx =
2490 Value *Idx = Builder.getInt32(InsertIdx);
2491 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2492 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2505 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2509 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2512 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2531 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2535 if (
const auto *CE = dyn_cast<CastExpr>(E))
2536 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2537 CE->getCastKind() == CK_ArrayToPointerDecay)
2548 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2558 if (ICE->isGLValue())
2573 assert(LoadList.size() >= VecTy->getNumElements() &&
2574 "Flattened type on RHS must have the same number or more elements "
2575 "than vector on LHS.");
2579 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2582 "All flattened source values should be scalars.");
2585 VecTy->getElementType(), Loc);
2586 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2591 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2592 "Flattened type on RHS must have the same number or more elements "
2593 "than vector on LHS.");
2595 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2601 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2602 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2605 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2608 "All flattened source values should be scalars.");
2611 MatTy->getElementType(), Loc);
2612 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2613 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2620 "Destination type must be a vector, matrix, or builtin type.");
2622 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2631 llvm::scope_exit RestoreCurCast(
2632 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2636 QualType DestTy = CE->
getType();
2638 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2642 bool Ignored = TestAndClearIgnoreResultAssign();
2648 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2649 case CK_BuiltinFnToFnPtr:
2650 llvm_unreachable(
"builtin functions are handled elsewhere");
2652 case CK_LValueBitCast:
2653 case CK_ObjCObjectLValueCast: {
2657 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2660 case CK_LValueToRValueBitCast: {
2666 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2669 case CK_CPointerToObjCPointerCast:
2670 case CK_BlockPointerToObjCPointerCast:
2671 case CK_AnyPointerToBlockPointerCast:
2673 Value *Src = Visit(E);
2674 llvm::Type *SrcTy = Src->
getType();
2675 llvm::Type *DstTy = ConvertType(DestTy);
2686 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2700 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2701 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2706 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2707 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2708 "Address-space cast must be used to convert address spaces");
2710 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2711 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2713 PT->getPointeeType(),
2724 const QualType SrcType = E->
getType();
2729 Src = Builder.CreateLaunderInvariantGroup(Src);
2737 Src = Builder.CreateStripInvariantGroup(Src);
2742 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2746 if (!PointeeType.
isNull())
2755 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2756 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2759 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2760 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2761 ScalableDstTy = llvm::ScalableVectorType::get(
2762 FixedSrcTy->getElementType(),
2764 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2766 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2767 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2768 llvm::Value *
Result = Builder.CreateInsertVector(
2769 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2771 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2772 if (
Result->getType() != ScalableDstTy)
2774 if (
Result->getType() != DstTy)
2784 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2785 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2788 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2789 FixedDstTy->getElementType()->isIntegerTy(8)) {
2790 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2791 ScalableSrcTy = llvm::ScalableVectorType::get(
2792 ScalableSrcTy->getElementType(),
2794 ScalableSrcTy->getElementCount().getKnownMinValue()));
2795 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2796 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2800 ScalableSrcTy = llvm::ScalableVectorType::get(
2801 FixedDstTy->getElementType(),
2802 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2803 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2805 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2806 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2827 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2830 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2833 case CK_AddressSpaceConversion: {
2836 Result.Val.isNullPointer()) {
2840 if (
Result.HasSideEffects)
2843 ConvertType(DestTy)), DestTy);
2849 case CK_AtomicToNonAtomic:
2850 case CK_NonAtomicToAtomic:
2851 case CK_UserDefinedConversion:
2858 case CK_BaseToDerived: {
2860 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2874 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2882 case CK_UncheckedDerivedToBase:
2883 case CK_DerivedToBase: {
2896 case CK_ArrayToPointerDecay:
2899 case CK_FunctionToPointerDecay:
2900 return EmitLValue(E).getPointer(CGF);
2902 case CK_NullToPointer:
2903 if (MustVisitNullValue(E))
2909 case CK_NullToMemberPointer: {
2910 if (MustVisitNullValue(E))
2913 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2917 case CK_ReinterpretMemberPointer:
2918 case CK_BaseToDerivedMemberPointer:
2919 case CK_DerivedToBaseMemberPointer: {
2920 Value *Src = Visit(E);
2931 case CK_ARCProduceObject:
2933 case CK_ARCConsumeObject:
2935 case CK_ARCReclaimReturnedObject:
2937 case CK_ARCExtendBlockObject:
2940 case CK_CopyAndAutoreleaseBlockObject:
2943 case CK_FloatingRealToComplex:
2944 case CK_FloatingComplexCast:
2945 case CK_IntegralRealToComplex:
2946 case CK_IntegralComplexCast:
2947 case CK_IntegralComplexToFloatingComplex:
2948 case CK_FloatingComplexToIntegralComplex:
2949 case CK_ConstructorConversion:
2951 case CK_HLSLArrayRValue:
2952 llvm_unreachable(
"scalar cast to non-scalar value");
2954 case CK_LValueToRValue:
2956 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2959 case CK_IntegralToPointer: {
2960 Value *Src = Visit(E);
2964 auto DestLLVMTy = ConvertType(DestTy);
2967 llvm::Value* IntResult =
2968 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2970 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2976 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2982 case CK_PointerToIntegral: {
2983 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2984 auto *PtrExpr = Visit(E);
2987 const QualType SrcType = E->
getType();
2992 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2996 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3002 case CK_MatrixCast: {
3003 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3010 case CK_HLSLAggregateSplatCast:
3011 case CK_VectorSplat: {
3012 llvm::Type *DstTy = ConvertType(DestTy);
3013 Value *Elt = Visit(E);
3015 llvm::ElementCount NumElements =
3017 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3020 case CK_FixedPointCast:
3021 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3024 case CK_FixedPointToBoolean:
3026 "Expected src type to be fixed point type");
3027 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3028 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3031 case CK_FixedPointToIntegral:
3033 "Expected src type to be fixed point type");
3034 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3035 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3038 case CK_IntegralToFixedPoint:
3040 "Expected src type to be an integer");
3042 "Expected dest type to be fixed point type");
3043 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3046 case CK_IntegralCast: {
3048 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3049 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3053 ScalarConversionOpts Opts;
3054 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3055 if (!ICE->isPartOfExplicitCast())
3056 Opts = ScalarConversionOpts(CGF.
SanOpts);
3058 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3061 case CK_IntegralToFloating: {
3064 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3066 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3067 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3069 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3070 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3073 case CK_FloatingToIntegral: {
3076 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3078 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3079 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3081 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3082 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3085 case CK_FloatingCast: {
3088 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3089 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3090 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3091 SrcElTy->
castAs<BuiltinType>()->getKind())
3092 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3093 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3095 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3096 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3099 case CK_FixedPointToFloating:
3100 case CK_FloatingToFixedPoint: {
3101 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3102 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3105 case CK_BooleanToSignedIntegral: {
3106 ScalarConversionOpts Opts;
3107 Opts.TreatBooleanAsSigned =
true;
3108 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3111 case CK_IntegralToBoolean:
3112 return EmitIntToBoolConversion(Visit(E));
3113 case CK_PointerToBoolean:
3114 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3115 case CK_FloatingToBoolean: {
3116 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3117 return EmitFloatToBoolConversion(Visit(E));
3119 case CK_MemberPointerToBoolean: {
3120 llvm::Value *MemPtr = Visit(E);
3121 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3125 case CK_FloatingComplexToReal:
3126 case CK_IntegralComplexToReal:
3129 case CK_FloatingComplexToBoolean:
3130 case CK_IntegralComplexToBoolean: {
3134 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3138 case CK_ZeroToOCLOpaqueType: {
3141 "CK_ZeroToOCLEvent cast on non-event type");
3142 return llvm::Constant::getNullValue(ConvertType(DestTy));
3145 case CK_IntToOCLSampler:
3148 case CK_HLSLVectorTruncation: {
3150 "Destination type must be a vector or builtin type.");
3151 Value *Vec = Visit(E);
3152 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3153 SmallVector<int> Mask;
3154 unsigned NumElts = VecTy->getNumElements();
3155 for (
unsigned I = 0; I != NumElts; ++I)
3158 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3160 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3161 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3163 case CK_HLSLMatrixTruncation: {
3165 "Destination type must be a matrix or builtin type.");
3166 Value *Mat = Visit(E);
3167 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3168 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3169 unsigned NumCols = MatTy->getNumColumns();
3170 unsigned NumRows = MatTy->getNumRows();
3171 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3172 assert(SrcMatTy &&
"Source type must be a matrix type.");
3173 assert(NumRows <= SrcMatTy->getNumRows());
3174 assert(NumCols <= SrcMatTy->getNumColumns());
3175 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
3176 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
3177 for (
unsigned R = 0;
R < NumRows;
R++)
3178 for (
unsigned C = 0;
C < NumCols;
C++)
3179 Mask[MatTy->getFlattenedIndex(R,
C, IsRowMajor)] =
3180 SrcMatTy->getFlattenedIndex(R,
C, IsRowMajor);
3182 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3184 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3185 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3187 case CK_HLSLElementwiseCast: {
3207 llvm_unreachable(
"unknown scalar cast");
3210Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3211 CodeGenFunction::StmtExprEvaluation eval(CGF);
3220Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3221 CodeGenFunction::RunCleanupsScope Scope(CGF);
3225 Scope.ForceCleanup({&
V});
3234 llvm::Value *InVal,
bool IsInc,
3238 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3240 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3241 BinOp.FPFeatures = FPFeatures;
3246llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3247 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3250 llvm::Value *Amount =
3251 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3252 StringRef Name = IsInc ?
"inc" :
"dec";
3256 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3257 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3259 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3260 case LangOptions::OB_Wrap:
3261 return Builder.CreateAdd(InVal, Amount, Name);
3262 case LangOptions::OB_SignedAndDefined:
3264 return Builder.CreateAdd(InVal, Amount, Name);
3266 case LangOptions::OB_Unset:
3268 return Builder.CreateAdd(InVal, Amount, Name);
3270 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3271 : Builder.CreateAdd(InVal, Amount, Name);
3273 case LangOptions::OB_Trap:
3275 return Builder.CreateAdd(InVal, Amount, Name);
3278 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3279 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3280 : Builder.CreateAdd(InVal, Amount, Name);
3281 return EmitOverflowCheckedBinOp(Info);
3283 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3288class OMPLastprivateConditionalUpdateRAII {
3290 CodeGenFunction &CGF;
3291 const UnaryOperator *E;
3294 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3295 const UnaryOperator *E)
3297 ~OMPLastprivateConditionalUpdateRAII() {
3306ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3307 bool isInc,
bool isPre) {
3309 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3311 llvm::PHINode *atomicPHI =
nullptr;
3315 QualType SrcType = E->
getType();
3317 int amount = (isInc ? 1 : -1);
3318 bool isSubtraction = !isInc;
3320 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3321 type = atomicTy->getValueType();
3322 if (isInc &&
type->isBooleanType()) {
3325 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3326 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3327 return Builder.getTrue();
3331 return Builder.CreateAtomicRMW(
3332 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3333 llvm::AtomicOrdering::SequentiallyConsistent);
3338 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3339 !(
type->isUnsignedIntegerType() &&
3340 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3342 LangOptions::SOB_Trapping) {
3343 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3344 llvm::AtomicRMWInst::Sub;
3345 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3346 llvm::Instruction::Sub;
3348 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3350 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3351 llvm::AtomicOrdering::SequentiallyConsistent);
3352 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3356 if (
type->isFloatingType()) {
3357 llvm::Type *Ty = ConvertType(
type);
3358 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3359 llvm::AtomicRMWInst::BinOp aop =
3360 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3361 llvm::Instruction::BinaryOps op =
3362 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3363 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3364 llvm::AtomicRMWInst *old =
3366 llvm::AtomicOrdering::SequentiallyConsistent);
3368 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3371 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3374 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3377 Builder.CreateBr(opBB);
3378 Builder.SetInsertPoint(opBB);
3379 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3380 atomicPHI->addIncoming(value, startBB);
3383 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3394 if (isInc &&
type->isBooleanType()) {
3395 value = Builder.getTrue();
3398 }
else if (
type->isIntegerType()) {
3399 QualType promotedType;
3400 bool canPerformLossyDemotionCheck =
false;
3404 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3405 canPerformLossyDemotionCheck =
true;
3406 canPerformLossyDemotionCheck &=
3409 canPerformLossyDemotionCheck &=
3411 type, promotedType);
3412 assert((!canPerformLossyDemotionCheck ||
3413 type->isSignedIntegerOrEnumerationType() ||
3415 ConvertType(
type)->getScalarSizeInBits() ==
3416 ConvertType(promotedType)->getScalarSizeInBits()) &&
3417 "The following check expects that if we do promotion to different "
3418 "underlying canonical type, at least one of the types (either "
3419 "base or promoted) will be signed, or the bitwidths will match.");
3422 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3423 SanitizerKind::ImplicitBitfieldConversion) &&
3424 canPerformLossyDemotionCheck) {
3438 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3439 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3440 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3444 ScalarConversionOpts Opts;
3445 if (!LV.isBitField())
3446 Opts = ScalarConversionOpts(CGF.
SanOpts);
3447 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3449 SrcType = promotedType;
3453 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3459 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3460 type->isUnsignedIntegerType()) {
3461 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3466 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3467 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3471 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3472 QualType
type = ptr->getPointeeType();
3475 if (
const VariableArrayType *vla
3478 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3481 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3484 elemTy, value, numElts,
false, isSubtraction,
3488 }
else if (
type->isFunctionType()) {
3489 llvm::Value *amt = Builder.getInt32(amount);
3492 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3496 false, isSubtraction,
3501 llvm::Value *amt = Builder.getInt32(amount);
3504 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3507 elemTy, value, amt,
false, isSubtraction,
3512 }
else if (
type->isVectorType()) {
3513 if (
type->hasIntegerRepresentation()) {
3514 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3516 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3518 value = Builder.CreateFAdd(
3520 llvm::ConstantFP::get(value->getType(), amount),
3521 isInc ?
"inc" :
"dec");
3525 }
else if (
type->isRealFloatingType()) {
3528 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3534 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3537 if (value->getType()->isFloatTy())
3538 amt = llvm::ConstantFP::get(VMContext,
3539 llvm::APFloat(
static_cast<float>(amount)));
3540 else if (value->getType()->isDoubleTy())
3541 amt = llvm::ConstantFP::get(VMContext,
3542 llvm::APFloat(
static_cast<double>(amount)));
3546 llvm::APFloat F(
static_cast<float>(amount));
3548 const llvm::fltSemantics *FS;
3551 if (value->getType()->isFP128Ty())
3553 else if (value->getType()->isHalfTy())
3555 else if (value->getType()->isBFloatTy())
3557 else if (value->getType()->isPPC_FP128Ty())
3561 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3562 amt = llvm::ConstantFP::get(VMContext, F);
3564 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3567 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3568 value = Builder.CreateBitCast(value, input->getType());
3572 }
else if (
type->isFixedPointType()) {
3579 Info.Opcode = isInc ? BO_Add : BO_Sub;
3581 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3584 if (
type->isSignedFixedPointType()) {
3585 Info.Opcode = isInc ? BO_Sub : BO_Add;
3586 Info.RHS = Builder.CreateNeg(Info.RHS);
3591 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3593 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3594 value = EmitFixedPointBinOp(Info);
3598 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3601 if (!isInc) size = -size;
3602 llvm::Value *sizeValue =
3603 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3606 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3609 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3611 value = Builder.CreateBitCast(value, input->getType());
3615 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3620 llvm::Value *
success = Pair.second;
3621 atomicPHI->addIncoming(old, curBlock);
3622 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3623 Builder.SetInsertPoint(contBB);
3624 return isPre ? value : input;
3628 if (LV.isBitField()) {
3638 return isPre ? value : input;
3642Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3643 QualType PromotionType) {
3644 QualType promotionTy = PromotionType.
isNull()
3647 Value *result = VisitPlus(E, promotionTy);
3648 if (result && !promotionTy.
isNull())
3649 result = EmitUnPromotedValue(result, E->
getType());
3653Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3654 QualType PromotionType) {
3656 TestAndClearIgnoreResultAssign();
3657 if (!PromotionType.
isNull())
3662Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3663 QualType PromotionType) {
3664 QualType promotionTy = PromotionType.
isNull()
3667 Value *result = VisitMinus(E, promotionTy);
3668 if (result && !promotionTy.
isNull())
3669 result = EmitUnPromotedValue(result, E->
getType());
3673Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3674 QualType PromotionType) {
3675 TestAndClearIgnoreResultAssign();
3677 if (!PromotionType.
isNull())
3683 if (Op->
getType()->isFPOrFPVectorTy())
3684 return Builder.CreateFNeg(Op,
"fneg");
3689 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3691 BinOp.Opcode = BO_Sub;
3694 return EmitSub(BinOp);
3697Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3698 TestAndClearIgnoreResultAssign();
3700 return Builder.CreateNot(Op,
"not");
3703Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3707 VectorKind::Generic) {
3711 if (Oper->
getType()->isFPOrFPVectorTy()) {
3712 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3714 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3716 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3717 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3726 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3729 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3732Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3734 Expr::EvalResult EVResult;
3737 return Builder.getInt(
Value);
3742 llvm::Type* ResultType = ConvertType(E->
getType());
3743 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3745 for (
unsigned i = 0; i != n; ++i) {
3747 llvm::Value *Offset =
nullptr;
3754 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3761 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3765 Offset = Builder.CreateMul(Idx, ElemSize);
3770 FieldDecl *MemberDecl = ON.
getField();
3780 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3783 CurrentType = MemberDecl->
getType();
3788 llvm_unreachable(
"dependent __builtin_offsetof");
3805 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3817ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3818 const UnaryExprOrTypeTraitExpr *E) {
3821 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3822 if (
const VariableArrayType *VAT =
3827 bool EvaluateExtent =
true;
3828 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3830 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3832 if (EvaluateExtent) {
3843 if (Kind == UETT_CountOf)
3852 if (!eltSize.
isOne())
3855 return VlaSize.NumElts;
3858 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3864 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3865 }
else if (E->
getKind() == UETT_VectorElements) {
3867 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3875Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3876 QualType PromotionType) {
3877 QualType promotionTy = PromotionType.
isNull()
3880 Value *result = VisitReal(E, promotionTy);
3881 if (result && !promotionTy.
isNull())
3882 result = EmitUnPromotedValue(result, E->
getType());
3886Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3887 QualType PromotionType) {
3894 if (!PromotionType.
isNull()) {
3896 Op, IgnoreResultAssign,
true);
3911 if (!PromotionType.
isNull())
3916Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3917 QualType PromotionType) {
3918 QualType promotionTy = PromotionType.
isNull()
3921 Value *result = VisitImag(E, promotionTy);
3922 if (result && !promotionTy.
isNull())
3923 result = EmitUnPromotedValue(result, E->
getType());
3927Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3928 QualType PromotionType) {
3935 if (!PromotionType.
isNull()) {
3937 Op,
true, IgnoreResultAssign);
3941 return result.second
3957 else if (!PromotionType.
isNull())
3961 if (!PromotionType.
isNull())
3962 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3963 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3970Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3971 QualType PromotionType) {
3972 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3975Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3976 QualType ExprType) {
3977 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3980Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3982 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3984#define HANDLE_BINOP(OP) \
3986 return Emit##OP(EmitBinOps(BO, PromotionType));
3995 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3998 return VisitImag(UO, PromotionType);
4000 return VisitReal(UO, PromotionType);
4002 return VisitMinus(UO, PromotionType);
4004 return VisitPlus(UO, PromotionType);
4009 auto result = Visit(
const_cast<Expr *
>(E));
4011 if (!PromotionType.
isNull())
4012 return EmitPromotedValue(result, PromotionType);
4014 return EmitUnPromotedValue(result, E->
getType());
4019BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4020 QualType PromotionType) {
4021 TestAndClearIgnoreResultAssign();
4025 if (!PromotionType.
isNull())
4026 Result.Ty = PromotionType;
4035LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4036 const CompoundAssignOperator *E,
4037 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4048 QualType PromotionTypeCR;
4050 if (PromotionTypeCR.
isNull())
4053 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4054 if (!PromotionTypeRHS.
isNull())
4057 OpInfo.RHS = Visit(E->
getRHS());
4058 OpInfo.Ty = PromotionTypeCR;
4065 llvm::PHINode *atomicPHI =
nullptr;
4066 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4067 QualType
type = atomicTy->getValueType();
4068 if (!
type->isBooleanType() &&
type->isIntegerType() &&
4069 !(
type->isUnsignedIntegerType() &&
4070 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4072 LangOptions::SOB_Trapping) {
4073 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4074 llvm::Instruction::BinaryOps Op;
4075 switch (OpInfo.Opcode) {
4077 case BO_MulAssign:
case BO_DivAssign:
4083 AtomicOp = llvm::AtomicRMWInst::Add;
4084 Op = llvm::Instruction::Add;
4087 AtomicOp = llvm::AtomicRMWInst::Sub;
4088 Op = llvm::Instruction::Sub;
4091 AtomicOp = llvm::AtomicRMWInst::And;
4092 Op = llvm::Instruction::And;
4095 AtomicOp = llvm::AtomicRMWInst::Xor;
4096 Op = llvm::Instruction::Xor;
4099 AtomicOp = llvm::AtomicRMWInst::Or;
4100 Op = llvm::Instruction::Or;
4103 llvm_unreachable(
"Invalid compound assignment type");
4105 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4107 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4111 llvm::AtomicRMWInst *OldVal =
4116 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4122 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4124 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4126 Builder.CreateBr(opBB);
4127 Builder.SetInsertPoint(opBB);
4128 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4129 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4130 OpInfo.LHS = atomicPHI;
4133 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4135 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4137 if (!PromotionTypeLHS.
isNull())
4138 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4141 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4152 if (LHSLV.isBitField()) {
4154 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4155 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4157 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4158 Loc, ScalarConversionOpts(CGF.
SanOpts));
4160 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4161 ScalarConversionOpts(CGF.
SanOpts));
4165 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4169 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4170 llvm::Value *
success = Pair.second;
4171 atomicPHI->addIncoming(old, curBlock);
4172 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4173 Builder.SetInsertPoint(contBB);
4181 if (LHSLV.isBitField()) {
4197Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4198 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4199 bool Ignore = TestAndClearIgnoreResultAssign();
4200 Value *RHS =
nullptr;
4201 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4212 if (!LHS.isVolatileQualified())
4216 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4219void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4220 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4221 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4224 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4225 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4226 SanitizerKind::SO_IntegerDivideByZero));
4230 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4231 Ops.Ty->hasSignedIntegerRepresentation() &&
4233 Ops.mayHaveIntegerOverflow() && !Ops.Ty.isWrapType() &&
4235 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4238 llvm::Value *IntMin =
4239 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4240 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4242 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4243 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4244 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4246 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4249 if (Checks.size() > 0)
4250 EmitBinOpCheck(Checks, Ops);
4253Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4255 SanitizerDebugLocation SanScope(&CGF,
4256 {SanitizerKind::SO_IntegerDivideByZero,
4257 SanitizerKind::SO_SignedIntegerOverflow,
4258 SanitizerKind::SO_FloatDivideByZero},
4259 SanitizerHandler::DivremOverflow);
4260 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4261 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4262 Ops.Ty->isIntegerType() &&
4263 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4264 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4265 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4266 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4267 Ops.Ty->isRealFloatingType() &&
4268 Ops.mayHaveFloatDivisionByZero()) {
4269 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4270 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4272 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4276 if (Ops.Ty->isConstantMatrixType()) {
4277 llvm::MatrixBuilder MB(Builder);
4284 "first operand must be a matrix");
4286 "second operand must be an arithmetic type");
4287 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4288 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4289 Ops.Ty->hasUnsignedIntegerRepresentation());
4292 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4294 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4295 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4299 else if (Ops.isFixedPointOp())
4300 return EmitFixedPointBinOp(Ops);
4301 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4302 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4304 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4307Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4309 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4310 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4311 Ops.Ty->isIntegerType() &&
4312 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4313 SanitizerDebugLocation SanScope(&CGF,
4314 {SanitizerKind::SO_IntegerDivideByZero,
4315 SanitizerKind::SO_SignedIntegerOverflow},
4316 SanitizerHandler::DivremOverflow);
4317 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4318 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4321 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4322 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4324 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4325 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4327 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4330Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4335 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4336 switch (Ops.Opcode) {
4340 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4341 llvm::Intrinsic::uadd_with_overflow;
4342 OverflowKind = SanitizerHandler::AddOverflow;
4347 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4348 llvm::Intrinsic::usub_with_overflow;
4349 OverflowKind = SanitizerHandler::SubOverflow;
4354 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4355 llvm::Intrinsic::umul_with_overflow;
4356 OverflowKind = SanitizerHandler::MulOverflow;
4359 llvm_unreachable(
"Unsupported operation for overflow detection");
4365 SanitizerDebugLocation SanScope(&CGF,
4366 {SanitizerKind::SO_SignedIntegerOverflow,
4367 SanitizerKind::SO_UnsignedIntegerOverflow},
4373 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4374 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4375 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4378 const std::string *handlerName =
4380 if (handlerName->empty()) {
4386 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4387 llvm::Value *NotOf = Builder.CreateNot(overflow);
4389 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4392 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4395 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4396 llvm::Value *NotOf = Builder.CreateNot(overflow);
4398 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4401 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4406 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4407 llvm::BasicBlock *continueBB =
4411 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4415 Builder.SetInsertPoint(overflowBB);
4418 llvm::Type *Int8Ty = CGF.
Int8Ty;
4419 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4420 llvm::FunctionType *handlerTy =
4421 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4422 llvm::FunctionCallee handler =
4427 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4428 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4432 llvm::Value *handlerArgs[] = {
4435 Builder.getInt8(OpID),
4438 llvm::Value *handlerResult =
4442 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4443 Builder.CreateBr(continueBB);
4445 Builder.SetInsertPoint(continueBB);
4446 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4447 phi->addIncoming(result, initialBB);
4448 phi->addIncoming(handlerResult, overflowBB);
4457 bool isSubtraction) {
4462 Value *pointer = op.LHS;
4463 Expr *pointerOperand =
expr->getLHS();
4465 Expr *indexOperand =
expr->getRHS();
4468 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4469 std::swap(pointer,
index);
4470 std::swap(pointerOperand, indexOperand);
4474 index, isSubtraction);
4480 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4484 auto &DL =
CGM.getDataLayout();
4507 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4509 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4510 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4511 PtrTy->getPointerAddressSpace()))
4514 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4515 auto CheckHandler = SanitizerHandler::PointerOverflow;
4517 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4519 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4520 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4522 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4523 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4528 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4539 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4549 llvm::Value *objectSize =
4555 return Builder.CreateBitCast(result, pointer->getType());
4560 getContext().getAsVariableArrayType(elementType)) {
4562 llvm::Value *numElements =
getVLASize(vla).NumElts;
4571 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4591 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4604 bool negMul,
bool negAdd) {
4605 Value *MulOp0 = MulOp->getOperand(0);
4606 Value *MulOp1 = MulOp->getOperand(1);
4608 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4610 Addend = Builder.CreateFNeg(Addend,
"neg");
4612 Value *FMulAdd =
nullptr;
4613 if (Builder.getIsFPConstrained()) {
4615 "Only constrained operation should be created when Builder is in FP "
4616 "constrained mode");
4617 FMulAdd = Builder.CreateConstrainedFPCall(
4618 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4620 {MulOp0, MulOp1, Addend});
4622 FMulAdd = Builder.CreateCall(
4624 {MulOp0, MulOp1, Addend});
4626 MulOp->eraseFromParent();
4641 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4642 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4643 "Only fadd/fsub can be the root of an fmuladd.");
4646 if (!op.FPFeatures.allowFPContractWithinStatement())
4649 Value *LHS = op.LHS;
4650 Value *RHS = op.RHS;
4654 bool NegLHS =
false;
4655 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4656 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4657 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4658 LHS = LHSUnOp->getOperand(0);
4663 bool NegRHS =
false;
4664 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4665 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4666 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4667 RHS = RHSUnOp->getOperand(0);
4675 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4676 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4677 (LHSBinOp->use_empty() || NegLHS)) {
4681 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4684 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4685 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4686 (RHSBinOp->use_empty() || NegRHS)) {
4690 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4694 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4695 if (LHSBinOp->getIntrinsicID() ==
4696 llvm::Intrinsic::experimental_constrained_fmul &&
4697 (LHSBinOp->use_empty() || NegLHS)) {
4701 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4704 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4705 if (RHSBinOp->getIntrinsicID() ==
4706 llvm::Intrinsic::experimental_constrained_fmul &&
4707 (RHSBinOp->use_empty() || NegRHS)) {
4711 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4718Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4719 if (op.LHS->getType()->isPointerTy() ||
4720 op.RHS->getType()->isPointerTy())
4723 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4724 op.Ty->isUnsignedIntegerType()) {
4725 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4727 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4728 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4729 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4730 case LangOptions::OB_Wrap:
4731 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4732 case LangOptions::OB_SignedAndDefined:
4734 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4736 case LangOptions::OB_Unset:
4738 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4739 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4741 case LangOptions::OB_Trap:
4742 if (CanElideOverflowCheck(CGF.
getContext(), op))
4743 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4744 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4745 return EmitOverflowCheckedBinOp(op);
4750 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4751 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4757 if (op.Ty->isConstantMatrixType()) {
4758 llvm::MatrixBuilder MB(Builder);
4759 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4760 return MB.CreateAdd(op.LHS, op.RHS);
4763 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4764 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4765 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4768 if (op.isFixedPointOp())
4769 return EmitFixedPointBinOp(op);
4771 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4776Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4778 using llvm::ConstantInt;
4784 QualType ResultTy = op.Ty;
4785 QualType LHSTy, RHSTy;
4786 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4787 RHSTy = BinOp->getRHS()->getType();
4788 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4793 LHSTy = CAO->getComputationLHSType();
4794 ResultTy = CAO->getComputationResultType();
4796 LHSTy = BinOp->getLHS()->getType();
4797 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4798 LHSTy = UnOp->getSubExpr()->getType();
4799 RHSTy = UnOp->getSubExpr()->getType();
4802 Value *LHS = op.LHS;
4803 Value *RHS = op.RHS;
4808 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4812 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4813 switch (op.Opcode) {
4816 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4820 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4824 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4828 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4832 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4836 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4839 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4841 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4843 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4845 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4850 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4852 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4856 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4869 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4875 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4880Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4882 if (!op.LHS->getType()->isPointerTy()) {
4883 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4884 op.Ty->isUnsignedIntegerType()) {
4885 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4887 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4888 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4889 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4890 case LangOptions::OB_Wrap:
4891 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4892 case LangOptions::OB_SignedAndDefined:
4894 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4896 case LangOptions::OB_Unset:
4898 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4899 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4901 case LangOptions::OB_Trap:
4902 if (CanElideOverflowCheck(CGF.
getContext(), op))
4903 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4904 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4905 return EmitOverflowCheckedBinOp(op);
4910 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4911 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4917 if (op.Ty->isConstantMatrixType()) {
4918 llvm::MatrixBuilder MB(Builder);
4919 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4920 return MB.CreateSub(op.LHS, op.RHS);
4923 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4924 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4925 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4928 if (op.isFixedPointOp())
4929 return EmitFixedPointBinOp(op);
4931 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4936 if (!op.RHS->getType()->isPointerTy())
4943 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4945 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4946 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4950 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4952 llvm::Value *divisor =
nullptr;
4955 if (
const VariableArrayType *vla
4958 elementType = VlaSize.Type;
4959 divisor = VlaSize.NumElts;
4963 if (!eltSize.
isOne())
4970 CharUnits elementSize;
4979 if (elementSize.
isOne())
4988 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4991Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4993 llvm::IntegerType *Ty;
4994 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5002 llvm::Type *RHSTy = RHS->
getType();
5003 llvm::APInt RHSMax =
5004 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5005 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5006 if (RHSMax.ult(Ty->getBitWidth()))
5007 return llvm::ConstantInt::get(RHSTy, RHSMax);
5008 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5012 const Twine &Name) {
5013 llvm::IntegerType *Ty;
5014 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5019 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5020 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5022 return Builder.CreateURem(
5023 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5026Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5028 if (Ops.isFixedPointOp())
5029 return EmitFixedPointBinOp(Ops);
5033 Value *RHS = Ops.RHS;
5034 if (Ops.LHS->getType() != RHS->
getType())
5035 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5037 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5038 Ops.Ty->hasSignedIntegerRepresentation() &&
5041 bool SanitizeUnsignedBase =
5042 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5043 Ops.Ty->hasUnsignedIntegerRepresentation();
5044 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5045 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5048 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5049 else if ((SanitizeBase || SanitizeExponent) &&
5051 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5052 if (SanitizeSignedBase)
5053 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5054 if (SanitizeUnsignedBase)
5055 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5056 if (SanitizeExponent)
5057 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5059 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5060 SanitizerHandler::ShiftOutOfBounds);
5061 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5062 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5063 llvm::Value *WidthMinusOne =
5064 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5065 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5067 if (SanitizeExponent) {
5069 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5076 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5079 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5080 llvm::Value *PromotedWidthMinusOne =
5081 (RHS == Ops.RHS) ? WidthMinusOne
5082 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5084 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5085 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5094 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5095 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5097 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5098 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5100 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5101 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5102 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5103 Checks.push_back(std::make_pair(
5104 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5105 : SanitizerKind::SO_UnsignedShiftBase));
5108 assert(!Checks.empty());
5109 EmitBinOpCheck(Checks, Ops);
5112 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5115Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5117 if (Ops.isFixedPointOp())
5118 return EmitFixedPointBinOp(Ops);
5122 Value *RHS = Ops.RHS;
5123 if (Ops.LHS->getType() != RHS->
getType())
5124 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5128 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5129 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5131 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5132 SanitizerHandler::ShiftOutOfBounds);
5133 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5134 llvm::Value *
Valid = Builder.CreateICmpULE(
5135 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5136 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5139 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5140 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5141 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5149 default: llvm_unreachable(
"unexpected element type");
5150 case BuiltinType::Char_U:
5151 case BuiltinType::UChar:
5152 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5153 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5154 case BuiltinType::Char_S:
5155 case BuiltinType::SChar:
5156 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5157 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5158 case BuiltinType::UShort:
5159 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5160 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5161 case BuiltinType::Short:
5162 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5163 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5164 case BuiltinType::UInt:
5165 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5166 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5167 case BuiltinType::Int:
5168 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5169 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5170 case BuiltinType::ULong:
5171 case BuiltinType::ULongLong:
5172 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5173 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5174 case BuiltinType::Long:
5175 case BuiltinType::LongLong:
5176 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5177 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5178 case BuiltinType::Float:
5179 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5180 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5181 case BuiltinType::Double:
5182 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5183 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5184 case BuiltinType::UInt128:
5185 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5186 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5187 case BuiltinType::Int128:
5188 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5189 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5193Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5194 llvm::CmpInst::Predicate UICmpOpc,
5195 llvm::CmpInst::Predicate SICmpOpc,
5196 llvm::CmpInst::Predicate FCmpOpc,
5198 TestAndClearIgnoreResultAssign();
5202 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5208 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5210 BinOpInfo BOInfo = EmitBinOps(E);
5211 Value *LHS = BOInfo.LHS;
5212 Value *RHS = BOInfo.RHS;
5218 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5220 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5223 Value *FirstVecArg = LHS,
5224 *SecondVecArg = RHS;
5226 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5230 default: llvm_unreachable(
"is not a comparison operation");
5242 std::swap(FirstVecArg, SecondVecArg);
5249 if (ElementKind == BuiltinType::Float) {
5251 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5252 std::swap(FirstVecArg, SecondVecArg);
5260 if (ElementKind == BuiltinType::Float) {
5262 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5267 std::swap(FirstVecArg, SecondVecArg);
5272 Value *CR6Param = Builder.getInt32(CR6);
5274 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5282 if (ResultTy->getBitWidth() > 1 &&
5284 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5289 if (BOInfo.isFixedPointOp()) {
5290 Result = EmitFixedPointBinOp(BOInfo);
5291 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5292 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5294 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5296 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5298 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5313 LHS = Builder.CreateStripInvariantGroup(LHS);
5315 RHS = Builder.CreateStripInvariantGroup(RHS);
5318 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5324 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5330 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5332 CETy = CTy->getElementType();
5334 LHS.first = Visit(E->
getLHS());
5335 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5338 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5341 CTy->getElementType()) &&
5342 "The element types must always match.");
5345 RHS.first = Visit(E->
getRHS());
5346 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5348 "The element types must always match.");
5351 Value *ResultR, *ResultI;
5355 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5356 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5360 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5361 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5365 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5368 "Complex comparison other than == or != ?");
5369 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5381 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5382 CastKind Kind = ICE->getCastKind();
5383 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5384 *SrcType = ICE->getSubExpr()->getType();
5397 bool Ignore = TestAndClearIgnoreResultAssign();
5431 RHS = Visit(E->
getRHS());
5447 RHS = Visit(E->
getRHS());
5487 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5490Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5501 if (LHS->
getType()->isFPOrFPVectorTy()) {
5502 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5504 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5505 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5507 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5508 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5510 Value *
And = Builder.CreateAnd(LHS, RHS);
5511 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5515 llvm::Type *ResTy = ConvertType(E->
getType());
5534 if (InstrumentRegions &&
5538 llvm::BasicBlock *RHSSkip =
5541 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5558 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5569 return llvm::Constant::getNullValue(ResTy);
5580 llvm::BasicBlock *LHSFalseBlock =
5583 CodeGenFunction::ConditionalEvaluation eval(CGF);
5598 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5600 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5602 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5611 RHSBlock = Builder.GetInsertBlock();
5616 llvm::BasicBlock *ContIncoming = RHSBlock;
5617 if (InstrumentRegions &&
5621 llvm::BasicBlock *RHSBlockSkip =
5623 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5627 PN->addIncoming(RHSCond, RHSBlockCnt);
5632 ContIncoming = RHSBlockSkip;
5643 PN->addIncoming(RHSCond, ContIncoming);
5652 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5656 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5659Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5670 if (LHS->
getType()->isFPOrFPVectorTy()) {
5671 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5673 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5674 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5676 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5677 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5679 Value *
Or = Builder.CreateOr(LHS, RHS);
5680 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5684 llvm::Type *ResTy = ConvertType(E->
getType());
5703 if (InstrumentRegions &&
5707 llvm::BasicBlock *RHSSkip =
5710 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5727 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5738 return llvm::ConstantInt::get(ResTy, 1);
5748 llvm::BasicBlock *LHSTrueBlock =
5751 CodeGenFunction::ConditionalEvaluation eval(CGF);
5767 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5769 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5771 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5783 RHSBlock = Builder.GetInsertBlock();
5788 llvm::BasicBlock *ContIncoming = RHSBlock;
5789 if (InstrumentRegions &&
5793 llvm::BasicBlock *RHSTrueBlock =
5795 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5799 PN->addIncoming(RHSCond, RHSBlockCnt);
5804 ContIncoming = RHSTrueBlock;
5811 PN->addIncoming(RHSCond, ContIncoming);
5818 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5821Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5824 return Visit(E->
getRHS());
5849Value *ScalarExprEmitter::
5850VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5851 TestAndClearIgnoreResultAssign();
5854 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5856 Expr *condExpr = E->
getCond();
5864 Expr *live = lhsExpr, *dead = rhsExpr;
5865 if (!CondExprBool) std::swap(live, dead);
5892 llvm::Value *LHS = Visit(lhsExpr);
5893 llvm::Value *RHS = Visit(rhsExpr);
5895 llvm::Type *condType = ConvertType(condExpr->
getType());
5898 unsigned numElem = vecTy->getNumElements();
5899 llvm::Type *elemType = vecTy->getElementType();
5901 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5902 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5903 llvm::Value *tmp = Builder.CreateSExt(
5904 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5905 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5908 llvm::Value *RHSTmp = RHS;
5909 llvm::Value *LHSTmp = LHS;
5910 bool wasCast =
false;
5912 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5913 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5914 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5918 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5919 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5920 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5922 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5932 llvm::Value *LHS = Visit(lhsExpr);
5933 llvm::Value *RHS = Visit(rhsExpr);
5935 llvm::Type *CondType = ConvertType(condExpr->
getType());
5938 if (VecTy->getElementType()->isIntegerTy(1))
5939 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5942 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5944 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5946 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5947 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5957 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5961 llvm::Value *LHS = Visit(lhsExpr);
5962 llvm::Value *RHS = Visit(rhsExpr);
5965 assert(!RHS &&
"LHS and RHS types must match");
5968 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5979 CodeGenFunction::ConditionalEvaluation eval(CGF);
5993 Value *LHS = Visit(lhsExpr);
5996 LHSBlock = Builder.GetInsertBlock();
5997 Builder.CreateBr(ContBlock);
6009 Value *RHS = Visit(rhsExpr);
6012 RHSBlock = Builder.GetInsertBlock();
6022 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6023 PN->addIncoming(LHS, LHSBlock);
6024 PN->addIncoming(RHS, RHSBlock);
6029Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6033Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6035 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6040Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6046 Value *Src,
unsigned NumElementsDst) {
6047 static constexpr int Mask[] = {0, 1, 2, -1};
6048 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6068 const llvm::DataLayout &DL,
6069 Value *Src, llvm::Type *DstTy,
6070 StringRef Name =
"") {
6074 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6075 return Builder.CreateBitCast(Src, DstTy, Name);
6078 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6079 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6082 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6084 if (!DstTy->isIntegerTy())
6085 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6087 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6091 if (!SrcTy->isIntegerTy())
6092 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6094 return Builder.CreateIntToPtr(Src, DstTy, Name);
6097Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6099 llvm::Type *DstTy = ConvertType(E->
getType());
6101 llvm::Type *SrcTy = Src->
getType();
6102 unsigned NumElementsSrc =
6106 unsigned NumElementsDst =
6117 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6122 Src->setName(
"astype");
6129 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6130 auto *Vec4Ty = llvm::FixedVectorType::get(
6136 Src->setName(
"astype");
6141 Src, DstTy,
"astype");
6144Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6156 "Invalid scalar expression to emit");
6158 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6159 .Visit(
const_cast<Expr *
>(E));
6168 "Invalid scalar expression to emit");
6169 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6179 "Invalid complex -> scalar conversion");
6180 return ScalarExprEmitter(*
this)
6181 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6188 if (!PromotionType.
isNull())
6189 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6191 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6197 bool isInc,
bool isPre) {
6198 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6208 llvm::Type *BaseTy =
6224 ScalarExprEmitter Scalar(*
this);
6227#define COMPOUND_OP(Op) \
6228 case BO_##Op##Assign: \
6229 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6266 llvm_unreachable(
"Not valid compound assignment operators");
6269 llvm_unreachable(
"Unhandled compound assignment operator");
6284 llvm::LLVMContext &VMContext,
6290 llvm::Value *TotalOffset =
nullptr;
6296 Value *BasePtr_int =
6297 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6299 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6300 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6301 return {TotalOffset, Builder.getFalse()};
6305 assert(GEP->getPointerOperand() == BasePtr &&
6306 "BasePtr must be the base of the GEP.");
6307 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6309 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6312 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6313 auto *SAddIntrinsic =
6314 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6315 auto *SMulIntrinsic =
6316 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6319 llvm::Value *OffsetOverflows = Builder.getFalse();
6323 llvm::Value *RHS) -> llvm::Value * {
6324 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6327 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6328 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6330 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6333 OffsetOverflows = Builder.getTrue();
6334 return llvm::ConstantInt::get(VMContext, N);
6339 auto *ResultAndOverflow = Builder.CreateCall(
6340 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6341 OffsetOverflows = Builder.CreateOr(
6342 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6343 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6347 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6348 GTI != GTE; ++GTI) {
6349 llvm::Value *LocalOffset;
6350 auto *Index = GTI.getOperand();
6352 if (
auto *STy = GTI.getStructTypeOrNull()) {
6356 LocalOffset = llvm::ConstantInt::get(
6357 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6362 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6363 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6364 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6369 if (!TotalOffset || TotalOffset ==
Zero)
6370 TotalOffset = LocalOffset;
6372 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6375 return {TotalOffset, OffsetOverflows};
6380 ArrayRef<Value *> IdxList,
6381 bool SignedIndices,
bool IsSubtraction,
6382 SourceLocation Loc,
const Twine &Name) {
6383 llvm::Type *PtrTy = Ptr->
getType();
6385 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6386 if (!SignedIndices && !IsSubtraction)
6387 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6389 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6392 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6396 bool PerformNullCheck = !NullPointerIsDefined(
6397 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6400 bool PerformOverflowCheck =
6403 if (!(PerformNullCheck || PerformOverflowCheck))
6406 const auto &DL = CGM.getDataLayout();
6408 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6409 auto CheckHandler = SanitizerHandler::PointerOverflow;
6410 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6411 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6413 GEPOffsetAndOverflow EvaluatedGEP =
6418 "If the offset got constant-folded, we don't expect that there was an "
6421 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6429 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6430 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6432 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6436 if (PerformNullCheck) {
6444 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6445 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6446 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6447 Checks.emplace_back(
Valid, CheckOrdinal);
6450 if (PerformOverflowCheck) {
6455 llvm::Value *ValidGEP;
6456 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6457 if (SignedIndices) {
6463 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6464 auto *PosOrZeroOffset =
6466 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6468 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6469 }
else if (!IsSubtraction) {
6474 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6480 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6482 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6483 Checks.emplace_back(ValidGEP, CheckOrdinal);
6486 assert(!Checks.empty() &&
"Should have produced some checks.");
6488 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6490 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6491 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6497 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6498 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6499 const Twine &Name) {
6500 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6501 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6502 if (!SignedIndices && !IsSubtraction)
6503 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6505 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6509 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6510 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6511 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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
virtual bool useFP16ConversionIntrinsics() const
Check whether conversions to and from __fp16 should go through an integer bitcast with i16.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool BitCast(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::Type * HalfTy
half, bfloat, float, double
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.