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 "Unknown scalar type to convert");
1047 return EmitIntToBoolConversion(Src);
1050 return EmitPointerToBoolConversion(Src, SrcType);
1053void ScalarExprEmitter::EmitFloatConversionCheck(
1054 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1055 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1056 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1060 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1061 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1062 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1063 using llvm::APFloat;
1066 llvm::Value *Check =
nullptr;
1067 const llvm::fltSemantics &SrcSema =
1077 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1078 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1079 APFloat::opOverflow)
1082 MinSrc = APFloat::getInf(SrcSema,
true);
1086 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1089 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1090 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1091 APFloat::opOverflow)
1094 MaxSrc = APFloat::getInf(SrcSema,
false);
1098 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1103 const llvm::fltSemantics &Sema =
1106 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1107 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1111 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1113 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1114 Check = Builder.CreateAnd(GE, LE);
1119 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1125static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1126 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1129 llvm::Type *SrcTy = Src->
getType();
1130 llvm::Type *DstTy = Dst->
getType();
1135 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1137 "non-integer llvm type");
1144 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1146 if (!SrcSigned && !DstSigned) {
1147 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1148 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1150 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1151 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1154 llvm::Value *Check =
nullptr;
1156 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1158 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1160 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1168void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1169 Value *Dst, QualType DstType,
1171 bool OBTrapInvolved) {
1172 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1182 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1183 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1185 if (SrcBits <= DstBits)
1188 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1195 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1196 (!SrcSigned && DstSigned))
1199 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1200 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1203 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1208 SanitizerDebugLocation SanScope(
1210 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1211 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1227 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1235 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1236 if (OBT->isWrapKind())
1239 if (ignoredBySanitizer && !OBTrapInvolved)
1242 llvm::Constant *StaticArgs[] = {
1245 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1246 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1248 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1255 llvm::Type *VTy =
V->getType();
1258 return llvm::ConstantInt::getFalse(VTy->getContext());
1260 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1261 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1262 llvm::Twine(Name) +
"." +
V->getName() +
1263 ".negativitycheck");
1268static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1269 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1272 llvm::Type *SrcTy = Src->
getType();
1273 llvm::Type *DstTy = Dst->
getType();
1276 "non-integer llvm type");
1282 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1283 unsigned DstBits = DstTy->getScalarSizeInBits();
1287 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1288 "either the widths should be different, or the signednesses.");
1291 llvm::Value *SrcIsNegative =
1294 llvm::Value *DstIsNegative =
1300 llvm::Value *Check =
nullptr;
1301 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1303 return std::make_pair(
1304 ScalarExprEmitter::ICCK_IntegerSignChange,
1305 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1308void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1309 Value *Dst, QualType DstType,
1311 bool OBTrapInvolved) {
1312 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1316 llvm::Type *SrcTy = Src->
getType();
1317 llvm::Type *DstTy = Dst->
getType();
1327 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1328 unsigned DstBits = DstTy->getScalarSizeInBits();
1335 if (SrcSigned == DstSigned && SrcBits == DstBits)
1339 if (!SrcSigned && !DstSigned)
1344 if ((DstBits > SrcBits) && DstSigned)
1346 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1347 (SrcBits > DstBits) && SrcSigned) {
1356 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1360 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1364 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1365 SanitizerDebugLocation SanScope(
1367 {SanitizerKind::SO_ImplicitIntegerSignChange,
1368 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1369 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1372 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1373 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1377 ImplicitConversionCheckKind CheckKind;
1378 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1385 CheckKind = Check.first;
1386 Checks.emplace_back(Check.second);
1388 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1389 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1395 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1396 Checks.emplace_back(Check.second);
1400 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1401 if (OBTrapInvolved) {
1402 llvm::Value *Combined = Check.second.first;
1403 for (
const auto &
C : Checks)
1404 Combined = Builder.CreateAnd(Combined,
C.first);
1410 llvm::Constant *StaticArgs[] = {
1413 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1414 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1416 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1421static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1422 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1428 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1429 if (!SrcSigned && !DstSigned)
1430 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1432 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1434 llvm::Value *Check =
nullptr;
1436 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1438 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1441 return std::make_pair(
1443 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1448static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1449 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1453 llvm::Value *SrcIsNegative =
1456 llvm::Value *DstIsNegative =
1462 llvm::Value *Check =
nullptr;
1464 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1466 return std::make_pair(
1467 ScalarExprEmitter::ICCK_IntegerSignChange,
1468 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1476 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1494 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1495 unsigned DstBits = Info.
Size;
1500 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1502 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1504 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1505 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1509 bool EmitTruncation = DstBits < SrcBits;
1513 bool EmitTruncationFromUnsignedToSigned =
1514 EmitTruncation && DstSigned && !SrcSigned;
1516 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1517 bool BothUnsigned = !SrcSigned && !DstSigned;
1518 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1525 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1530 else if (EmitSignChange) {
1531 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1532 "either the widths should be different, or the signednesses.");
1538 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1539 if (EmitTruncationFromUnsignedToSigned)
1540 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1542 llvm::Constant *StaticArgs[] = {
1545 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1546 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1548 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1552 QualType DstType, llvm::Type *SrcTy,
1554 ScalarConversionOpts Opts) {
1556 llvm::Type *SrcElementTy;
1557 llvm::Type *DstElementTy;
1567 "cannot cast between matrix and non-matrix types");
1568 SrcElementTy = SrcTy;
1569 DstElementTy = DstTy;
1570 SrcElementType = SrcType;
1571 DstElementType = DstType;
1576 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1581 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1583 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1584 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1588 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1595 llvm::Intrinsic::ID IID =
1596 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1597 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1601 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1602 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1605 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1606 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1607 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1609 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1610 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1611 return Builder.CreateFPExt(Src, DstTy,
"conv");
1616Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1619 ScalarConversionOpts Opts) {
1634 return Builder.CreateIsNotNull(Src,
"tobool");
1637 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1640 "Unhandled scalar conversion from a fixed point type to another type.");
1644 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1647 "Unhandled scalar conversion to a fixed point type from another type.");
1650 QualType NoncanonicalSrcType = SrcType;
1651 QualType NoncanonicalDstType = DstType;
1655 if (SrcType == DstType)
return Src;
1659 llvm::Value *OrigSrc = Src;
1660 QualType OrigSrcType = SrcType;
1661 llvm::Type *SrcTy = Src->
getType();
1665 return EmitConversionToBool(Src, SrcType);
1667 llvm::Type *DstTy = ConvertType(DstType);
1672 if (DstTy->isFloatingPointTy()) {
1675 return Builder.CreateFPExt(BitCast, DstTy,
"conv");
1684 Src = Builder.CreateBitCast(Src, CGF.
CGM.
HalfTy);
1687 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1694 if (SrcTy == DstTy) {
1695 if (Opts.EmitImplicitIntegerSignChangeChecks)
1696 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1697 NoncanonicalDstType, Loc);
1705 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1710 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1715 llvm::Value* IntResult =
1716 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1718 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1724 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1731 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1733 "Splatted expr doesn't match with vector element type?");
1737 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1741 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1745 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1746 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1747 if (SrcSize == DstSize)
1748 return Builder.CreateBitCast(Src, DstTy,
"conv");
1761 assert(((SrcElementTy->isIntegerTy() &&
1762 DstElementTy->isIntegerTy()) ||
1763 (SrcElementTy->isFloatingPointTy() &&
1764 DstElementTy->isFloatingPointTy())) &&
1765 "unexpected conversion between a floating-point vector and an "
1769 if (SrcElementTy->isIntegerTy())
1770 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1773 if (SrcSize > DstSize)
1774 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1777 return Builder.CreateFPExt(Src, DstTy,
"conv");
1781 Value *Res =
nullptr;
1782 llvm::Type *ResTy = DstTy;
1789 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1791 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1797 if (SrcTy->isFloatingPointTy()) {
1806 assert(DstTy->isIntegerTy(16) &&
1808 "Only half FP requires extra conversion");
1809 return Builder.CreateBitCast(Res, DstTy);
1815 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1817 if (DstTy != ResTy) {
1818 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1821 assert(ResTy->isIntegerTy(16) &&
1823 "Only half FP requires extra conversion");
1824 Res = Builder.CreateBitCast(Res, ResTy);
1835 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1836 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1837 bool OBTrapInvolved =
1838 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1839 bool OBWrapInvolved =
1840 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1842 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1843 !OBWrapInvolved && !Opts.PatternExcluded)
1844 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1845 NoncanonicalDstType, Loc, OBTrapInvolved);
1847 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1848 (OBTrapInvolved && !OBWrapInvolved))
1849 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1850 NoncanonicalDstType, Loc, OBTrapInvolved);
1855Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1857 SourceLocation Loc) {
1858 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1861 Result = FPBuilder.CreateFloatingToFixed(Src,
1864 Result = FPBuilder.CreateFixedToFloating(Src,
1866 ConvertType(DstTy));
1872 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1873 DstFPSema.getWidth(),
1874 DstFPSema.isSigned());
1876 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1879 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1886Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1888 SourceLocation Loc) {
1890 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1895 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1896 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1897 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1904 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1907Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1915void ScalarExprEmitter::EmitBinOpCheck(
1916 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1917 const BinOpInfo &Info) {
1920 SmallVector<llvm::Constant *, 4> StaticData;
1921 SmallVector<llvm::Value *, 2> DynamicData;
1929 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1930 if (UO && UO->
getOpcode() == UO_Minus) {
1931 Check = SanitizerHandler::NegateOverflow;
1933 DynamicData.push_back(Info.RHS);
1937 Check = SanitizerHandler::ShiftOutOfBounds;
1939 StaticData.push_back(
1941 StaticData.push_back(
1943 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1945 Check = SanitizerHandler::DivremOverflow;
1949 int ArithOverflowKind = 0;
1952 Check = SanitizerHandler::AddOverflow;
1953 ArithOverflowKind = diag::UBSanArithKind::Add;
1957 Check = SanitizerHandler::SubOverflow;
1958 ArithOverflowKind = diag::UBSanArithKind::Sub;
1962 Check = SanitizerHandler::MulOverflow;
1963 ArithOverflowKind = diag::UBSanArithKind::Mul;
1967 llvm_unreachable(
"unexpected opcode for bin op check");
1971 SanitizerKind::UnsignedIntegerOverflow) ||
1973 SanitizerKind::SignedIntegerOverflow)) {
1977 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1981 DynamicData.push_back(Info.LHS);
1982 DynamicData.push_back(Info.RHS);
1985 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1992Value *ScalarExprEmitter::VisitExpr(Expr *E) {
2000ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
2002 unsigned AddrSpace =
2004 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
2007 llvm::Type *ExprTy = ConvertType(E->
getType());
2008 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2012Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2014 auto It = E->
begin();
2015 return Builder.getInt((*It)->getValue());
2018Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2026 unsigned LHSElts = LTy->getNumElements();
2034 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2035 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2043 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2044 MTy->getNumElements());
2045 Value* NewV = llvm::PoisonValue::get(RTy);
2046 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2047 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2048 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2050 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2051 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2059 SmallVector<int, 32> Indices;
2063 if (Idx.isSigned() && Idx.isAllOnes())
2064 Indices.push_back(-1);
2066 Indices.push_back(Idx.getZExtValue());
2069 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2072Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2080 if (SrcType == DstType)
return Src;
2083 "ConvertVector source type must be a vector");
2085 "ConvertVector destination type must be a vector");
2087 llvm::Type *SrcTy = Src->
getType();
2088 llvm::Type *DstTy = ConvertType(DstType);
2094 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2095 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2097 assert(SrcTy->isVectorTy() &&
2098 "ConvertVector source IR type must be a vector");
2099 assert(DstTy->isVectorTy() &&
2100 "ConvertVector destination IR type must be a vector");
2105 if (DstEltType->isBooleanType()) {
2106 assert((SrcEltTy->isFloatingPointTy() ||
2109 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2110 if (SrcEltTy->isFloatingPointTy()) {
2111 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2112 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2114 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2119 Value *Res =
nullptr;
2124 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2126 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2128 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2130 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2133 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2134 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2135 if (DstEltType->isSignedIntegerOrEnumerationType())
2136 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2138 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2140 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2141 "Unknown real conversion");
2142 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2143 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2144 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2146 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2152Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2161 return Builder.getInt(
Value);
2165 llvm::Value *
Result = EmitLoadOfLValue(E);
2171 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2172 if (llvm::GetElementPtrInst *GEP =
2173 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2174 if (llvm::Instruction *
Pointer =
2175 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2187Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2188 TestAndClearIgnoreResultAssign();
2196 return EmitLoadOfLValue(E);
2204 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2207 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2210Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2211 MatrixSingleSubscriptExpr *E) {
2212 TestAndClearIgnoreResultAssign();
2215 unsigned NumRows = MatrixTy->getNumRows();
2216 unsigned NumColumns = MatrixTy->getNumColumns();
2220 llvm::MatrixBuilder MB(Builder);
2224 MB.CreateIndexAssumption(RowIdx, NumRows);
2228 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2229 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2231 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2232 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2233 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2234 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2235 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2236 IsMatrixRowMajor,
"matrix_row_idx");
2238 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2239 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2240 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2246Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2247 TestAndClearIgnoreResultAssign();
2255 llvm::MatrixBuilder MB(Builder);
2258 unsigned NumCols = MatrixTy->getNumColumns();
2259 unsigned NumRows = MatrixTy->getNumRows();
2260 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2261 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2262 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2265 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2270 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2275 int MV = SVI->getMaskValue(Idx);
2282 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2283 "Index operand too large for shufflevector mask!");
2284 return C->getZExtValue();
2287Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2288 bool Ignore = TestAndClearIgnoreResultAssign();
2291 assert((Ignore ==
false ||
2293 "init list ignored");
2310 llvm::VectorType *VType =
2311 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2314 if (NumInitElements == 0) {
2316 return EmitNullValue(E->
getType());
2323 if (NumInitElements == 0) {
2325 return EmitNullValue(E->
getType());
2328 if (NumInitElements == 1) {
2329 Expr *InitVector = E->
getInit(0);
2334 return Visit(InitVector);
2337 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2344 const ConstantMatrixType *ColMajorMT =
nullptr;
2345 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
2346 MT && CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2347 LangOptions::MatrixMemoryLayout::MatrixColMajor)
2355 unsigned CurIdx = 0;
2356 bool VIsPoisonShuffle =
false;
2357 llvm::Value *
V = llvm::PoisonValue::get(VType);
2358 for (
unsigned i = 0; i != NumInitElements; ++i) {
2361 SmallVector<int, 16> Args;
2363 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2373 ->getNumElements() == ResElts) {
2375 Value *LHS =
nullptr, *RHS =
nullptr;
2380 Args.resize(ResElts, -1);
2382 LHS = EI->getVectorOperand();
2384 VIsPoisonShuffle =
true;
2385 }
else if (VIsPoisonShuffle) {
2388 for (
unsigned j = 0; j != CurIdx; ++j)
2390 Args.push_back(ResElts +
C->getZExtValue());
2391 Args.resize(ResElts, -1);
2394 RHS = EI->getVectorOperand();
2395 VIsPoisonShuffle =
false;
2397 if (!Args.empty()) {
2398 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2404 unsigned InsertIdx =
2408 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(InsertIdx),
2410 VIsPoisonShuffle =
false;
2420 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2423 Value *SVOp = SVI->getOperand(0);
2426 if (OpTy->getNumElements() == ResElts) {
2427 for (
unsigned j = 0; j != CurIdx; ++j) {
2430 if (VIsPoisonShuffle) {
2436 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2438 Args.resize(ResElts, -1);
2440 if (VIsPoisonShuffle)
2450 for (
unsigned j = 0; j != InitElts; ++j)
2452 Args.resize(ResElts, -1);
2453 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2456 for (
unsigned j = 0; j != CurIdx; ++j)
2458 for (
unsigned j = 0; j != InitElts; ++j)
2459 Args.push_back(j + Offset);
2460 Args.resize(ResElts, -1);
2467 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2474 llvm::Type *EltTy = VType->getElementType();
2477 for (; CurIdx < ResElts; ++CurIdx) {
2478 unsigned InsertIdx =
2481 Value *Idx = Builder.getInt32(InsertIdx);
2482 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2483 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2496 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2500 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2503 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2522 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2526 if (
const auto *CE = dyn_cast<CastExpr>(E))
2527 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2528 CE->getCastKind() == CK_ArrayToPointerDecay)
2539 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2549 if (ICE->isGLValue())
2564 assert(LoadList.size() >= VecTy->getNumElements() &&
2565 "Flattened type on RHS must have the same number or more elements "
2566 "than vector on LHS.");
2570 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2573 "All flattened source values should be scalars.");
2576 VecTy->getElementType(), Loc);
2577 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2582 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2583 "Flattened type on RHS must have the same number or more elements "
2584 "than vector on LHS.");
2586 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2592 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2593 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2596 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2599 "All flattened source values should be scalars.");
2602 MatTy->getElementType(), Loc);
2603 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2604 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2611 "Destination type must be a vector, matrix, or builtin type.");
2613 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2622 llvm::scope_exit RestoreCurCast(
2623 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2627 QualType DestTy = CE->
getType();
2629 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2633 bool Ignored = TestAndClearIgnoreResultAssign();
2639 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2640 case CK_BuiltinFnToFnPtr:
2641 llvm_unreachable(
"builtin functions are handled elsewhere");
2643 case CK_LValueBitCast:
2644 case CK_ObjCObjectLValueCast: {
2645 Address
Addr = EmitLValue(E).getAddress();
2648 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2651 case CK_LValueToRValueBitCast: {
2657 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2660 case CK_CPointerToObjCPointerCast:
2661 case CK_BlockPointerToObjCPointerCast:
2662 case CK_AnyPointerToBlockPointerCast:
2664 Value *Src = Visit(E);
2665 llvm::Type *SrcTy = Src->
getType();
2666 llvm::Type *DstTy = ConvertType(DestTy);
2677 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2691 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2692 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2697 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2698 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2699 "Address-space cast must be used to convert address spaces");
2701 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2702 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2704 PT->getPointeeType(),
2715 const QualType SrcType = E->
getType();
2720 Src = Builder.CreateLaunderInvariantGroup(Src);
2728 Src = Builder.CreateStripInvariantGroup(Src);
2733 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2737 if (!PointeeType.
isNull())
2746 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2747 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2750 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2751 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2752 ScalableDstTy = llvm::ScalableVectorType::get(
2753 FixedSrcTy->getElementType(),
2755 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2757 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2758 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2759 llvm::Value *
Result = Builder.CreateInsertVector(
2760 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2762 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2763 if (
Result->getType() != ScalableDstTy)
2765 if (
Result->getType() != DstTy)
2775 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2776 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2779 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2780 FixedDstTy->getElementType()->isIntegerTy(8)) {
2781 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2782 ScalableSrcTy = llvm::ScalableVectorType::get(
2783 ScalableSrcTy->getElementType(),
2785 ScalableSrcTy->getElementCount().getKnownMinValue()));
2786 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2787 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2791 ScalableSrcTy = llvm::ScalableVectorType::get(
2792 FixedDstTy->getElementType(),
2793 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2794 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2796 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2797 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2818 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2821 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2824 case CK_AddressSpaceConversion: {
2827 Result.Val.isNullPointer()) {
2831 if (
Result.HasSideEffects)
2834 ConvertType(DestTy)), DestTy);
2840 case CK_AtomicToNonAtomic:
2841 case CK_NonAtomicToAtomic:
2842 case CK_UserDefinedConversion:
2849 case CK_BaseToDerived: {
2851 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2865 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2873 case CK_UncheckedDerivedToBase:
2874 case CK_DerivedToBase: {
2887 case CK_ArrayToPointerDecay:
2890 case CK_FunctionToPointerDecay:
2891 return EmitLValue(E).getPointer(CGF);
2893 case CK_NullToPointer:
2894 if (MustVisitNullValue(E))
2900 case CK_NullToMemberPointer: {
2901 if (MustVisitNullValue(E))
2904 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2908 case CK_ReinterpretMemberPointer:
2909 case CK_BaseToDerivedMemberPointer:
2910 case CK_DerivedToBaseMemberPointer: {
2911 Value *Src = Visit(E);
2922 case CK_ARCProduceObject:
2924 case CK_ARCConsumeObject:
2926 case CK_ARCReclaimReturnedObject:
2928 case CK_ARCExtendBlockObject:
2931 case CK_CopyAndAutoreleaseBlockObject:
2934 case CK_FloatingRealToComplex:
2935 case CK_FloatingComplexCast:
2936 case CK_IntegralRealToComplex:
2937 case CK_IntegralComplexCast:
2938 case CK_IntegralComplexToFloatingComplex:
2939 case CK_FloatingComplexToIntegralComplex:
2940 case CK_ConstructorConversion:
2942 case CK_HLSLArrayRValue:
2943 llvm_unreachable(
"scalar cast to non-scalar value");
2945 case CK_LValueToRValue:
2947 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2950 case CK_IntegralToPointer: {
2951 Value *Src = Visit(E);
2955 auto DestLLVMTy = ConvertType(DestTy);
2958 llvm::Value* IntResult =
2959 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2961 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2967 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2973 case CK_PointerToIntegral: {
2974 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2975 auto *PtrExpr = Visit(E);
2978 const QualType SrcType = E->
getType();
2983 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2987 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2993 case CK_MatrixCast: {
2994 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3001 case CK_HLSLAggregateSplatCast:
3002 case CK_VectorSplat: {
3003 llvm::Type *DstTy = ConvertType(DestTy);
3004 Value *Elt = Visit(E);
3006 llvm::ElementCount NumElements =
3008 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3011 case CK_FixedPointCast:
3012 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3015 case CK_FixedPointToBoolean:
3017 "Expected src type to be fixed point type");
3018 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3019 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3022 case CK_FixedPointToIntegral:
3024 "Expected src type to be fixed point type");
3025 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3026 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3029 case CK_IntegralToFixedPoint:
3031 "Expected src type to be an integer");
3033 "Expected dest type to be fixed point type");
3034 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3037 case CK_IntegralCast: {
3039 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3040 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3044 ScalarConversionOpts Opts;
3045 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3046 if (!ICE->isPartOfExplicitCast())
3047 Opts = ScalarConversionOpts(CGF.
SanOpts);
3049 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3052 case CK_IntegralToFloating: {
3055 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3057 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3058 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3060 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3061 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3064 case CK_FloatingToIntegral: {
3067 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3069 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3070 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3072 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3073 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3076 case CK_FloatingCast: {
3079 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3080 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3081 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3082 SrcElTy->
castAs<BuiltinType>()->getKind())
3083 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3084 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3086 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3087 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3090 case CK_FixedPointToFloating:
3091 case CK_FloatingToFixedPoint: {
3092 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3093 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3096 case CK_BooleanToSignedIntegral: {
3097 ScalarConversionOpts Opts;
3098 Opts.TreatBooleanAsSigned =
true;
3099 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3102 case CK_IntegralToBoolean:
3103 return EmitIntToBoolConversion(Visit(E));
3104 case CK_PointerToBoolean:
3105 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3106 case CK_FloatingToBoolean: {
3107 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3108 return EmitFloatToBoolConversion(Visit(E));
3110 case CK_MemberPointerToBoolean: {
3111 llvm::Value *MemPtr = Visit(E);
3112 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3116 case CK_FloatingComplexToReal:
3117 case CK_IntegralComplexToReal:
3120 case CK_FloatingComplexToBoolean:
3121 case CK_IntegralComplexToBoolean: {
3125 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3129 case CK_ZeroToOCLOpaqueType: {
3132 "CK_ZeroToOCLEvent cast on non-event type");
3133 return llvm::Constant::getNullValue(ConvertType(DestTy));
3136 case CK_IntToOCLSampler:
3139 case CK_HLSLVectorTruncation: {
3141 "Destination type must be a vector or builtin type.");
3142 Value *Vec = Visit(E);
3143 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3144 SmallVector<int> Mask;
3145 unsigned NumElts = VecTy->getNumElements();
3146 for (
unsigned I = 0; I != NumElts; ++I)
3149 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3151 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3152 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3154 case CK_HLSLMatrixTruncation: {
3156 "Destination type must be a matrix or builtin type.");
3157 Value *Mat = Visit(E);
3158 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3159 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3160 unsigned NumCols = MatTy->getNumColumns();
3161 unsigned NumRows = MatTy->getNumRows();
3162 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3163 assert(SrcMatTy &&
"Source type must be a matrix type.");
3164 assert(NumRows <= SrcMatTy->getNumRows());
3165 assert(NumCols <= SrcMatTy->getNumColumns());
3166 bool IsRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
3167 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
3168 for (
unsigned R = 0;
R < NumRows;
R++)
3169 for (
unsigned C = 0;
C < NumCols;
C++)
3170 Mask[MatTy->getFlattenedIndex(R,
C, IsRowMajor)] =
3171 SrcMatTy->getFlattenedIndex(R,
C, IsRowMajor);
3173 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3175 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3176 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3178 case CK_HLSLElementwiseCast: {
3198 llvm_unreachable(
"unknown scalar cast");
3201Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3202 CodeGenFunction::StmtExprEvaluation eval(CGF);
3211Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3212 CodeGenFunction::RunCleanupsScope Scope(CGF);
3216 Scope.ForceCleanup({&
V});
3225 llvm::Value *InVal,
bool IsInc,
3229 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3231 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3232 BinOp.FPFeatures = FPFeatures;
3237llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3238 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3241 llvm::Value *Amount =
3242 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3243 StringRef Name = IsInc ?
"inc" :
"dec";
3247 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3248 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3250 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3251 case LangOptions::OB_Wrap:
3252 return Builder.CreateAdd(InVal, Amount, Name);
3253 case LangOptions::OB_SignedAndDefined:
3255 return Builder.CreateAdd(InVal, Amount, Name);
3257 case LangOptions::OB_Unset:
3259 return Builder.CreateAdd(InVal, Amount, Name);
3261 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3262 : Builder.CreateAdd(InVal, Amount, Name);
3264 case LangOptions::OB_Trap:
3266 return Builder.CreateAdd(InVal, Amount, Name);
3269 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3270 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3271 : Builder.CreateAdd(InVal, Amount, Name);
3272 return EmitOverflowCheckedBinOp(Info);
3274 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3279class OMPLastprivateConditionalUpdateRAII {
3281 CodeGenFunction &CGF;
3282 const UnaryOperator *E;
3285 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3286 const UnaryOperator *E)
3288 ~OMPLastprivateConditionalUpdateRAII() {
3297ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3298 bool isInc,
bool isPre) {
3300 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3302 llvm::PHINode *atomicPHI =
nullptr;
3306 QualType SrcType = E->
getType();
3308 int amount = (isInc ? 1 : -1);
3309 bool isSubtraction = !isInc;
3311 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3312 type = atomicTy->getValueType();
3313 if (isInc &&
type->isBooleanType()) {
3316 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3317 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3318 return Builder.getTrue();
3322 return Builder.CreateAtomicRMW(
3323 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3324 llvm::AtomicOrdering::SequentiallyConsistent);
3329 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3330 !(
type->isUnsignedIntegerType() &&
3331 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3333 LangOptions::SOB_Trapping) {
3334 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3335 llvm::AtomicRMWInst::Sub;
3336 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3337 llvm::Instruction::Sub;
3339 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3341 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3342 llvm::AtomicOrdering::SequentiallyConsistent);
3343 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3347 if (
type->isFloatingType()) {
3348 llvm::Type *Ty = ConvertType(
type);
3349 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3350 llvm::AtomicRMWInst::BinOp aop =
3351 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3352 llvm::Instruction::BinaryOps op =
3353 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3354 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3355 llvm::AtomicRMWInst *old =
3357 llvm::AtomicOrdering::SequentiallyConsistent);
3359 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3362 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3365 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3368 Builder.CreateBr(opBB);
3369 Builder.SetInsertPoint(opBB);
3370 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3371 atomicPHI->addIncoming(value, startBB);
3374 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3385 if (isInc &&
type->isBooleanType()) {
3386 value = Builder.getTrue();
3389 }
else if (
type->isIntegerType()) {
3390 QualType promotedType;
3391 bool canPerformLossyDemotionCheck =
false;
3395 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3396 canPerformLossyDemotionCheck =
true;
3397 canPerformLossyDemotionCheck &=
3400 canPerformLossyDemotionCheck &=
3402 type, promotedType);
3403 assert((!canPerformLossyDemotionCheck ||
3404 type->isSignedIntegerOrEnumerationType() ||
3406 ConvertType(
type)->getScalarSizeInBits() ==
3407 ConvertType(promotedType)->getScalarSizeInBits()) &&
3408 "The following check expects that if we do promotion to different "
3409 "underlying canonical type, at least one of the types (either "
3410 "base or promoted) will be signed, or the bitwidths will match.");
3413 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3414 SanitizerKind::ImplicitBitfieldConversion) &&
3415 canPerformLossyDemotionCheck) {
3429 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3430 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3431 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3435 ScalarConversionOpts Opts;
3436 if (!LV.isBitField())
3437 Opts = ScalarConversionOpts(CGF.
SanOpts);
3438 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3440 SrcType = promotedType;
3444 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3450 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3451 type->isUnsignedIntegerType()) {
3452 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3457 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3458 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3462 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3463 QualType
type = ptr->getPointeeType();
3466 if (
const VariableArrayType *vla
3469 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3472 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3475 elemTy, value, numElts,
false, isSubtraction,
3479 }
else if (
type->isFunctionType()) {
3480 llvm::Value *amt = Builder.getInt32(amount);
3483 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3487 false, isSubtraction,
3492 llvm::Value *amt = Builder.getInt32(amount);
3495 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3498 elemTy, value, amt,
false, isSubtraction,
3503 }
else if (
type->isVectorType()) {
3504 if (
type->hasIntegerRepresentation()) {
3505 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3507 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3509 value = Builder.CreateFAdd(
3511 llvm::ConstantFP::get(value->getType(), amount),
3512 isInc ?
"inc" :
"dec");
3516 }
else if (
type->isRealFloatingType()) {
3519 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3525 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3528 if (value->getType()->isFloatTy())
3529 amt = llvm::ConstantFP::get(VMContext,
3530 llvm::APFloat(
static_cast<float>(amount)));
3531 else if (value->getType()->isDoubleTy())
3532 amt = llvm::ConstantFP::get(VMContext,
3533 llvm::APFloat(
static_cast<double>(amount)));
3537 llvm::APFloat F(
static_cast<float>(amount));
3539 const llvm::fltSemantics *FS;
3542 if (value->getType()->isFP128Ty())
3544 else if (value->getType()->isHalfTy())
3546 else if (value->getType()->isBFloatTy())
3548 else if (value->getType()->isPPC_FP128Ty())
3552 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3553 amt = llvm::ConstantFP::get(VMContext, F);
3555 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3558 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3559 value = Builder.CreateBitCast(value, input->getType());
3563 }
else if (
type->isFixedPointType()) {
3570 Info.Opcode = isInc ? BO_Add : BO_Sub;
3572 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3575 if (
type->isSignedFixedPointType()) {
3576 Info.Opcode = isInc ? BO_Sub : BO_Add;
3577 Info.RHS = Builder.CreateNeg(Info.RHS);
3582 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3584 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3585 value = EmitFixedPointBinOp(Info);
3589 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3592 if (!isInc) size = -size;
3593 llvm::Value *sizeValue =
3594 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3597 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3600 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3602 value = Builder.CreateBitCast(value, input->getType());
3606 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3611 llvm::Value *
success = Pair.second;
3612 atomicPHI->addIncoming(old, curBlock);
3613 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3614 Builder.SetInsertPoint(contBB);
3615 return isPre ? value : input;
3619 if (LV.isBitField()) {
3629 return isPre ? value : input;
3633Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3634 QualType PromotionType) {
3635 QualType promotionTy = PromotionType.
isNull()
3638 Value *result = VisitPlus(E, promotionTy);
3639 if (result && !promotionTy.
isNull())
3640 result = EmitUnPromotedValue(result, E->
getType());
3644Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3645 QualType PromotionType) {
3647 TestAndClearIgnoreResultAssign();
3648 if (!PromotionType.
isNull())
3653Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3654 QualType PromotionType) {
3655 QualType promotionTy = PromotionType.
isNull()
3658 Value *result = VisitMinus(E, promotionTy);
3659 if (result && !promotionTy.
isNull())
3660 result = EmitUnPromotedValue(result, E->
getType());
3664Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3665 QualType PromotionType) {
3666 TestAndClearIgnoreResultAssign();
3668 if (!PromotionType.
isNull())
3674 if (Op->
getType()->isFPOrFPVectorTy())
3675 return Builder.CreateFNeg(Op,
"fneg");
3680 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3682 BinOp.Opcode = BO_Sub;
3685 return EmitSub(BinOp);
3688Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3689 TestAndClearIgnoreResultAssign();
3691 return Builder.CreateNot(Op,
"not");
3694Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3698 VectorKind::Generic) {
3702 if (Oper->
getType()->isFPOrFPVectorTy()) {
3703 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3705 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3707 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3708 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3717 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3720 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3723Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3725 Expr::EvalResult EVResult;
3728 return Builder.getInt(
Value);
3733 llvm::Type* ResultType = ConvertType(E->
getType());
3734 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3736 for (
unsigned i = 0; i != n; ++i) {
3738 llvm::Value *Offset =
nullptr;
3745 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3752 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3756 Offset = Builder.CreateMul(Idx, ElemSize);
3761 FieldDecl *MemberDecl = ON.
getField();
3771 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3774 CurrentType = MemberDecl->
getType();
3779 llvm_unreachable(
"dependent __builtin_offsetof");
3796 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3808ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3809 const UnaryExprOrTypeTraitExpr *E) {
3812 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3813 if (
const VariableArrayType *VAT =
3818 bool EvaluateExtent =
true;
3819 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3821 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3823 if (EvaluateExtent) {
3834 if (Kind == UETT_CountOf)
3843 if (!eltSize.
isOne())
3846 return VlaSize.NumElts;
3849 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3855 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3856 }
else if (E->
getKind() == UETT_VectorElements) {
3858 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3866Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3867 QualType PromotionType) {
3868 QualType promotionTy = PromotionType.
isNull()
3871 Value *result = VisitReal(E, promotionTy);
3872 if (result && !promotionTy.
isNull())
3873 result = EmitUnPromotedValue(result, E->
getType());
3877Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3878 QualType PromotionType) {
3885 if (!PromotionType.
isNull()) {
3887 Op, IgnoreResultAssign,
true);
3902 if (!PromotionType.
isNull())
3907Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3908 QualType PromotionType) {
3909 QualType promotionTy = PromotionType.
isNull()
3912 Value *result = VisitImag(E, promotionTy);
3913 if (result && !promotionTy.
isNull())
3914 result = EmitUnPromotedValue(result, E->
getType());
3918Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3919 QualType PromotionType) {
3926 if (!PromotionType.
isNull()) {
3928 Op,
true, IgnoreResultAssign);
3932 return result.second
3948 else if (!PromotionType.
isNull())
3952 if (!PromotionType.
isNull())
3953 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3954 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3961Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3962 QualType PromotionType) {
3963 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3966Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3967 QualType ExprType) {
3968 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3971Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3973 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3975#define HANDLE_BINOP(OP) \
3977 return Emit##OP(EmitBinOps(BO, PromotionType));
3986 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3989 return VisitImag(UO, PromotionType);
3991 return VisitReal(UO, PromotionType);
3993 return VisitMinus(UO, PromotionType);
3995 return VisitPlus(UO, PromotionType);
4000 auto result = Visit(
const_cast<Expr *
>(E));
4002 if (!PromotionType.
isNull())
4003 return EmitPromotedValue(result, PromotionType);
4005 return EmitUnPromotedValue(result, E->
getType());
4010BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4011 QualType PromotionType) {
4012 TestAndClearIgnoreResultAssign();
4016 if (!PromotionType.
isNull())
4017 Result.Ty = PromotionType;
4026LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4027 const CompoundAssignOperator *E,
4028 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4039 QualType PromotionTypeCR;
4041 if (PromotionTypeCR.
isNull())
4044 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4045 if (!PromotionTypeRHS.
isNull())
4048 OpInfo.RHS = Visit(E->
getRHS());
4049 OpInfo.Ty = PromotionTypeCR;
4056 llvm::PHINode *atomicPHI =
nullptr;
4057 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4058 QualType
type = atomicTy->getValueType();
4059 if (!
type->isBooleanType() &&
type->isIntegerType() &&
4060 !(
type->isUnsignedIntegerType() &&
4061 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4063 LangOptions::SOB_Trapping) {
4064 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4065 llvm::Instruction::BinaryOps Op;
4066 switch (OpInfo.Opcode) {
4068 case BO_MulAssign:
case BO_DivAssign:
4074 AtomicOp = llvm::AtomicRMWInst::Add;
4075 Op = llvm::Instruction::Add;
4078 AtomicOp = llvm::AtomicRMWInst::Sub;
4079 Op = llvm::Instruction::Sub;
4082 AtomicOp = llvm::AtomicRMWInst::And;
4083 Op = llvm::Instruction::And;
4086 AtomicOp = llvm::AtomicRMWInst::Xor;
4087 Op = llvm::Instruction::Xor;
4090 AtomicOp = llvm::AtomicRMWInst::Or;
4091 Op = llvm::Instruction::Or;
4094 llvm_unreachable(
"Invalid compound assignment type");
4096 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4098 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4102 llvm::AtomicRMWInst *OldVal =
4107 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4113 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4115 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4117 Builder.CreateBr(opBB);
4118 Builder.SetInsertPoint(opBB);
4119 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4120 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4121 OpInfo.LHS = atomicPHI;
4124 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4126 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4128 if (!PromotionTypeLHS.
isNull())
4129 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4132 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4143 if (LHSLV.isBitField()) {
4145 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4146 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4148 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4149 Loc, ScalarConversionOpts(CGF.
SanOpts));
4151 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4152 ScalarConversionOpts(CGF.
SanOpts));
4156 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4160 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4161 llvm::Value *
success = Pair.second;
4162 atomicPHI->addIncoming(old, curBlock);
4163 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4164 Builder.SetInsertPoint(contBB);
4172 if (LHSLV.isBitField()) {
4188Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4189 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4190 bool Ignore = TestAndClearIgnoreResultAssign();
4191 Value *RHS =
nullptr;
4192 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4203 if (!LHS.isVolatileQualified())
4207 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4210void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4211 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4212 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4215 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4216 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4217 SanitizerKind::SO_IntegerDivideByZero));
4221 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4222 Ops.Ty->hasSignedIntegerRepresentation() &&
4224 Ops.mayHaveIntegerOverflow() && !Ops.Ty.isWrapType() &&
4226 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4229 llvm::Value *IntMin =
4230 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4231 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4233 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4234 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4235 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4237 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4240 if (Checks.size() > 0)
4241 EmitBinOpCheck(Checks, Ops);
4244Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4246 SanitizerDebugLocation SanScope(&CGF,
4247 {SanitizerKind::SO_IntegerDivideByZero,
4248 SanitizerKind::SO_SignedIntegerOverflow,
4249 SanitizerKind::SO_FloatDivideByZero},
4250 SanitizerHandler::DivremOverflow);
4251 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4252 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4253 Ops.Ty->isIntegerType() &&
4254 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4255 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4256 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4257 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4258 Ops.Ty->isRealFloatingType() &&
4259 Ops.mayHaveFloatDivisionByZero()) {
4260 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4261 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4263 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4267 if (Ops.Ty->isConstantMatrixType()) {
4268 llvm::MatrixBuilder MB(Builder);
4275 "first operand must be a matrix");
4277 "second operand must be an arithmetic type");
4278 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4279 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4280 Ops.Ty->hasUnsignedIntegerRepresentation());
4283 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4285 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4286 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4290 else if (Ops.isFixedPointOp())
4291 return EmitFixedPointBinOp(Ops);
4292 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4293 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4295 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4298Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4300 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4301 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4302 Ops.Ty->isIntegerType() &&
4303 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4304 SanitizerDebugLocation SanScope(&CGF,
4305 {SanitizerKind::SO_IntegerDivideByZero,
4306 SanitizerKind::SO_SignedIntegerOverflow},
4307 SanitizerHandler::DivremOverflow);
4308 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4309 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4312 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4313 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4315 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4316 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4318 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4321Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4326 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4327 switch (Ops.Opcode) {
4331 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4332 llvm::Intrinsic::uadd_with_overflow;
4333 OverflowKind = SanitizerHandler::AddOverflow;
4338 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4339 llvm::Intrinsic::usub_with_overflow;
4340 OverflowKind = SanitizerHandler::SubOverflow;
4345 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4346 llvm::Intrinsic::umul_with_overflow;
4347 OverflowKind = SanitizerHandler::MulOverflow;
4350 llvm_unreachable(
"Unsupported operation for overflow detection");
4356 SanitizerDebugLocation SanScope(&CGF,
4357 {SanitizerKind::SO_SignedIntegerOverflow,
4358 SanitizerKind::SO_UnsignedIntegerOverflow},
4364 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4365 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4366 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4369 const std::string *handlerName =
4371 if (handlerName->empty()) {
4377 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4378 llvm::Value *NotOf = Builder.CreateNot(overflow);
4380 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4383 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4386 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4387 llvm::Value *NotOf = Builder.CreateNot(overflow);
4389 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4392 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4397 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4398 llvm::BasicBlock *continueBB =
4402 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4406 Builder.SetInsertPoint(overflowBB);
4409 llvm::Type *Int8Ty = CGF.
Int8Ty;
4410 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4411 llvm::FunctionType *handlerTy =
4412 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4413 llvm::FunctionCallee handler =
4418 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4419 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4423 llvm::Value *handlerArgs[] = {
4426 Builder.getInt8(OpID),
4429 llvm::Value *handlerResult =
4433 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4434 Builder.CreateBr(continueBB);
4436 Builder.SetInsertPoint(continueBB);
4437 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4438 phi->addIncoming(result, initialBB);
4439 phi->addIncoming(handlerResult, overflowBB);
4448 bool isSubtraction) {
4453 Value *pointer = op.LHS;
4454 Expr *pointerOperand =
expr->getLHS();
4456 Expr *indexOperand =
expr->getRHS();
4459 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4460 std::swap(pointer,
index);
4461 std::swap(pointerOperand, indexOperand);
4465 index, isSubtraction);
4471 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4475 auto &DL =
CGM.getDataLayout();
4498 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4500 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4501 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4502 PtrTy->getPointerAddressSpace()))
4505 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4506 auto CheckHandler = SanitizerHandler::PointerOverflow;
4508 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4510 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4511 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4513 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4514 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4519 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4530 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4540 llvm::Value *objectSize =
4546 return Builder.CreateBitCast(result, pointer->getType());
4551 getContext().getAsVariableArrayType(elementType)) {
4553 llvm::Value *numElements =
getVLASize(vla).NumElts;
4562 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4582 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4595 bool negMul,
bool negAdd) {
4596 Value *MulOp0 = MulOp->getOperand(0);
4597 Value *MulOp1 = MulOp->getOperand(1);
4599 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4601 Addend = Builder.CreateFNeg(Addend,
"neg");
4603 Value *FMulAdd =
nullptr;
4604 if (Builder.getIsFPConstrained()) {
4606 "Only constrained operation should be created when Builder is in FP "
4607 "constrained mode");
4608 FMulAdd = Builder.CreateConstrainedFPCall(
4609 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4611 {MulOp0, MulOp1, Addend});
4613 FMulAdd = Builder.CreateCall(
4615 {MulOp0, MulOp1, Addend});
4617 MulOp->eraseFromParent();
4632 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4633 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4634 "Only fadd/fsub can be the root of an fmuladd.");
4637 if (!op.FPFeatures.allowFPContractWithinStatement())
4640 Value *LHS = op.LHS;
4641 Value *RHS = op.RHS;
4645 bool NegLHS =
false;
4646 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4647 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4648 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4649 LHS = LHSUnOp->getOperand(0);
4654 bool NegRHS =
false;
4655 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4656 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4657 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4658 RHS = RHSUnOp->getOperand(0);
4666 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4667 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4668 (LHSBinOp->use_empty() || NegLHS)) {
4672 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4675 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4676 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4677 (RHSBinOp->use_empty() || NegRHS)) {
4681 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4685 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4686 if (LHSBinOp->getIntrinsicID() ==
4687 llvm::Intrinsic::experimental_constrained_fmul &&
4688 (LHSBinOp->use_empty() || NegLHS)) {
4692 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4695 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4696 if (RHSBinOp->getIntrinsicID() ==
4697 llvm::Intrinsic::experimental_constrained_fmul &&
4698 (RHSBinOp->use_empty() || NegRHS)) {
4702 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4709Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4710 if (op.LHS->getType()->isPointerTy() ||
4711 op.RHS->getType()->isPointerTy())
4714 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4715 op.Ty->isUnsignedIntegerType()) {
4716 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4718 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4719 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4720 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4721 case LangOptions::OB_Wrap:
4722 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4723 case LangOptions::OB_SignedAndDefined:
4725 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4727 case LangOptions::OB_Unset:
4729 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4730 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4732 case LangOptions::OB_Trap:
4733 if (CanElideOverflowCheck(CGF.
getContext(), op))
4734 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4735 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4736 return EmitOverflowCheckedBinOp(op);
4741 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4742 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4748 if (op.Ty->isConstantMatrixType()) {
4749 llvm::MatrixBuilder MB(Builder);
4750 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4751 return MB.CreateAdd(op.LHS, op.RHS);
4754 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4755 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4756 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4759 if (op.isFixedPointOp())
4760 return EmitFixedPointBinOp(op);
4762 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4767Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4769 using llvm::ConstantInt;
4775 QualType ResultTy = op.Ty;
4776 QualType LHSTy, RHSTy;
4777 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4778 RHSTy = BinOp->getRHS()->getType();
4779 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4784 LHSTy = CAO->getComputationLHSType();
4785 ResultTy = CAO->getComputationResultType();
4787 LHSTy = BinOp->getLHS()->getType();
4788 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4789 LHSTy = UnOp->getSubExpr()->getType();
4790 RHSTy = UnOp->getSubExpr()->getType();
4793 Value *LHS = op.LHS;
4794 Value *RHS = op.RHS;
4799 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4803 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4804 switch (op.Opcode) {
4807 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4811 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4815 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4819 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4823 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4827 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4830 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4832 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4834 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4836 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4841 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4843 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4847 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4860 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4866 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4871Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4873 if (!op.LHS->getType()->isPointerTy()) {
4874 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4875 op.Ty->isUnsignedIntegerType()) {
4876 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4878 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4879 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4880 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4881 case LangOptions::OB_Wrap:
4882 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4883 case LangOptions::OB_SignedAndDefined:
4885 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4887 case LangOptions::OB_Unset:
4889 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4890 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4892 case LangOptions::OB_Trap:
4893 if (CanElideOverflowCheck(CGF.
getContext(), op))
4894 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4895 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4896 return EmitOverflowCheckedBinOp(op);
4901 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4902 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4908 if (op.Ty->isConstantMatrixType()) {
4909 llvm::MatrixBuilder MB(Builder);
4910 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4911 return MB.CreateSub(op.LHS, op.RHS);
4914 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4915 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4916 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4919 if (op.isFixedPointOp())
4920 return EmitFixedPointBinOp(op);
4922 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4927 if (!op.RHS->getType()->isPointerTy())
4934 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4936 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4937 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4941 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4943 llvm::Value *divisor =
nullptr;
4946 if (
const VariableArrayType *vla
4949 elementType = VlaSize.Type;
4950 divisor = VlaSize.NumElts;
4954 if (!eltSize.
isOne())
4961 CharUnits elementSize;
4970 if (elementSize.
isOne())
4979 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4982Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4984 llvm::IntegerType *Ty;
4985 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4993 llvm::Type *RHSTy = RHS->
getType();
4994 llvm::APInt RHSMax =
4995 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4996 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4997 if (RHSMax.ult(Ty->getBitWidth()))
4998 return llvm::ConstantInt::get(RHSTy, RHSMax);
4999 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5003 const Twine &Name) {
5004 llvm::IntegerType *Ty;
5005 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5010 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5011 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5013 return Builder.CreateURem(
5014 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5017Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5019 if (Ops.isFixedPointOp())
5020 return EmitFixedPointBinOp(Ops);
5024 Value *RHS = Ops.RHS;
5025 if (Ops.LHS->getType() != RHS->
getType())
5026 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5028 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5029 Ops.Ty->hasSignedIntegerRepresentation() &&
5032 bool SanitizeUnsignedBase =
5033 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5034 Ops.Ty->hasUnsignedIntegerRepresentation();
5035 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5036 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5039 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5040 else if ((SanitizeBase || SanitizeExponent) &&
5042 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5043 if (SanitizeSignedBase)
5044 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5045 if (SanitizeUnsignedBase)
5046 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5047 if (SanitizeExponent)
5048 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5050 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5051 SanitizerHandler::ShiftOutOfBounds);
5052 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5053 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5054 llvm::Value *WidthMinusOne =
5055 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5056 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5058 if (SanitizeExponent) {
5060 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5067 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5070 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5071 llvm::Value *PromotedWidthMinusOne =
5072 (RHS == Ops.RHS) ? WidthMinusOne
5073 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5075 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5076 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5085 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5086 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5088 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5089 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5091 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5092 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5093 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5094 Checks.push_back(std::make_pair(
5095 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5096 : SanitizerKind::SO_UnsignedShiftBase));
5099 assert(!Checks.empty());
5100 EmitBinOpCheck(Checks, Ops);
5103 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5106Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5108 if (Ops.isFixedPointOp())
5109 return EmitFixedPointBinOp(Ops);
5113 Value *RHS = Ops.RHS;
5114 if (Ops.LHS->getType() != RHS->
getType())
5115 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5119 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5120 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5122 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5123 SanitizerHandler::ShiftOutOfBounds);
5124 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5125 llvm::Value *
Valid = Builder.CreateICmpULE(
5126 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5127 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5130 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5131 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5132 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5140 default: llvm_unreachable(
"unexpected element type");
5141 case BuiltinType::Char_U:
5142 case BuiltinType::UChar:
5143 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5144 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5145 case BuiltinType::Char_S:
5146 case BuiltinType::SChar:
5147 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5148 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5149 case BuiltinType::UShort:
5150 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5151 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5152 case BuiltinType::Short:
5153 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5154 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5155 case BuiltinType::UInt:
5156 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5157 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5158 case BuiltinType::Int:
5159 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5160 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5161 case BuiltinType::ULong:
5162 case BuiltinType::ULongLong:
5163 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5164 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5165 case BuiltinType::Long:
5166 case BuiltinType::LongLong:
5167 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5168 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5169 case BuiltinType::Float:
5170 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5171 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5172 case BuiltinType::Double:
5173 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5174 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5175 case BuiltinType::UInt128:
5176 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5177 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5178 case BuiltinType::Int128:
5179 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5180 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5184Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5185 llvm::CmpInst::Predicate UICmpOpc,
5186 llvm::CmpInst::Predicate SICmpOpc,
5187 llvm::CmpInst::Predicate FCmpOpc,
5189 TestAndClearIgnoreResultAssign();
5193 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5199 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5201 BinOpInfo BOInfo = EmitBinOps(E);
5202 Value *LHS = BOInfo.LHS;
5203 Value *RHS = BOInfo.RHS;
5209 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5211 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5214 Value *FirstVecArg = LHS,
5215 *SecondVecArg = RHS;
5217 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5221 default: llvm_unreachable(
"is not a comparison operation");
5233 std::swap(FirstVecArg, SecondVecArg);
5240 if (ElementKind == BuiltinType::Float) {
5242 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5243 std::swap(FirstVecArg, SecondVecArg);
5251 if (ElementKind == BuiltinType::Float) {
5253 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5258 std::swap(FirstVecArg, SecondVecArg);
5263 Value *CR6Param = Builder.getInt32(CR6);
5265 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5273 if (ResultTy->getBitWidth() > 1 &&
5275 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5280 if (BOInfo.isFixedPointOp()) {
5281 Result = EmitFixedPointBinOp(BOInfo);
5282 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5283 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5285 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5287 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5289 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5304 LHS = Builder.CreateStripInvariantGroup(LHS);
5306 RHS = Builder.CreateStripInvariantGroup(RHS);
5309 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5315 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5321 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5323 CETy = CTy->getElementType();
5325 LHS.first = Visit(E->
getLHS());
5326 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5329 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5332 CTy->getElementType()) &&
5333 "The element types must always match.");
5336 RHS.first = Visit(E->
getRHS());
5337 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5339 "The element types must always match.");
5342 Value *ResultR, *ResultI;
5346 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5347 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5351 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5352 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5356 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5359 "Complex comparison other than == or != ?");
5360 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5372 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5373 CastKind Kind = ICE->getCastKind();
5374 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5375 *SrcType = ICE->getSubExpr()->getType();
5388 bool Ignore = TestAndClearIgnoreResultAssign();
5422 RHS = Visit(E->
getRHS());
5438 RHS = Visit(E->
getRHS());
5478 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5481Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5492 if (LHS->
getType()->isFPOrFPVectorTy()) {
5493 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5495 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5496 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5498 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5499 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5501 Value *
And = Builder.CreateAnd(LHS, RHS);
5502 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5506 llvm::Type *ResTy = ConvertType(E->
getType());
5525 if (InstrumentRegions &&
5529 llvm::BasicBlock *RHSSkip =
5532 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5549 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5560 return llvm::Constant::getNullValue(ResTy);
5571 llvm::BasicBlock *LHSFalseBlock =
5574 CodeGenFunction::ConditionalEvaluation eval(CGF);
5589 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5591 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5593 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5602 RHSBlock = Builder.GetInsertBlock();
5607 llvm::BasicBlock *ContIncoming = RHSBlock;
5608 if (InstrumentRegions &&
5612 llvm::BasicBlock *RHSBlockSkip =
5614 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5618 PN->addIncoming(RHSCond, RHSBlockCnt);
5623 ContIncoming = RHSBlockSkip;
5634 PN->addIncoming(RHSCond, ContIncoming);
5643 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5647 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5650Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5661 if (LHS->
getType()->isFPOrFPVectorTy()) {
5662 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5664 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5665 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5667 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5668 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5670 Value *
Or = Builder.CreateOr(LHS, RHS);
5671 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5675 llvm::Type *ResTy = ConvertType(E->
getType());
5694 if (InstrumentRegions &&
5698 llvm::BasicBlock *RHSSkip =
5701 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5718 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5729 return llvm::ConstantInt::get(ResTy, 1);
5739 llvm::BasicBlock *LHSTrueBlock =
5742 CodeGenFunction::ConditionalEvaluation eval(CGF);
5758 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5760 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5762 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5774 RHSBlock = Builder.GetInsertBlock();
5779 llvm::BasicBlock *ContIncoming = RHSBlock;
5780 if (InstrumentRegions &&
5784 llvm::BasicBlock *RHSTrueBlock =
5786 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5790 PN->addIncoming(RHSCond, RHSBlockCnt);
5795 ContIncoming = RHSTrueBlock;
5802 PN->addIncoming(RHSCond, ContIncoming);
5809 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5812Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5815 return Visit(E->
getRHS());
5840Value *ScalarExprEmitter::
5841VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5842 TestAndClearIgnoreResultAssign();
5845 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5847 Expr *condExpr = E->
getCond();
5855 Expr *live = lhsExpr, *dead = rhsExpr;
5856 if (!CondExprBool) std::swap(live, dead);
5883 llvm::Value *LHS = Visit(lhsExpr);
5884 llvm::Value *RHS = Visit(rhsExpr);
5886 llvm::Type *condType = ConvertType(condExpr->
getType());
5889 unsigned numElem = vecTy->getNumElements();
5890 llvm::Type *elemType = vecTy->getElementType();
5892 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5893 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5894 llvm::Value *tmp = Builder.CreateSExt(
5895 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5896 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5899 llvm::Value *RHSTmp = RHS;
5900 llvm::Value *LHSTmp = LHS;
5901 bool wasCast =
false;
5903 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5904 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5905 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5909 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5910 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5911 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5913 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5923 llvm::Value *LHS = Visit(lhsExpr);
5924 llvm::Value *RHS = Visit(rhsExpr);
5926 llvm::Type *CondType = ConvertType(condExpr->
getType());
5929 if (VecTy->getElementType()->isIntegerTy(1))
5930 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5933 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5935 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5937 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5938 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5948 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5952 llvm::Value *LHS = Visit(lhsExpr);
5953 llvm::Value *RHS = Visit(rhsExpr);
5956 assert(!RHS &&
"LHS and RHS types must match");
5959 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5970 CodeGenFunction::ConditionalEvaluation eval(CGF);
5984 Value *LHS = Visit(lhsExpr);
5987 LHSBlock = Builder.GetInsertBlock();
5988 Builder.CreateBr(ContBlock);
6000 Value *RHS = Visit(rhsExpr);
6003 RHSBlock = Builder.GetInsertBlock();
6013 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6014 PN->addIncoming(LHS, LHSBlock);
6015 PN->addIncoming(RHS, RHSBlock);
6020Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6024Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6026 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6031Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6037 Value *Src,
unsigned NumElementsDst) {
6038 static constexpr int Mask[] = {0, 1, 2, -1};
6039 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6059 const llvm::DataLayout &DL,
6060 Value *Src, llvm::Type *DstTy,
6061 StringRef Name =
"") {
6065 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6066 return Builder.CreateBitCast(Src, DstTy, Name);
6069 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6070 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6073 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6075 if (!DstTy->isIntegerTy())
6076 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6078 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6082 if (!SrcTy->isIntegerTy())
6083 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6085 return Builder.CreateIntToPtr(Src, DstTy, Name);
6088Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6090 llvm::Type *DstTy = ConvertType(E->
getType());
6092 llvm::Type *SrcTy = Src->
getType();
6093 unsigned NumElementsSrc =
6097 unsigned NumElementsDst =
6108 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6113 Src->setName(
"astype");
6120 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6121 auto *Vec4Ty = llvm::FixedVectorType::get(
6127 Src->setName(
"astype");
6132 Src, DstTy,
"astype");
6135Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6147 "Invalid scalar expression to emit");
6149 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6150 .Visit(
const_cast<Expr *
>(E));
6159 "Invalid scalar expression to emit");
6160 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6170 "Invalid complex -> scalar conversion");
6171 return ScalarExprEmitter(*
this)
6172 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6179 if (!PromotionType.
isNull())
6180 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6182 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6188 bool isInc,
bool isPre) {
6189 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6199 llvm::Type *BaseTy =
6215 ScalarExprEmitter Scalar(*
this);
6218#define COMPOUND_OP(Op) \
6219 case BO_##Op##Assign: \
6220 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6257 llvm_unreachable(
"Not valid compound assignment operators");
6260 llvm_unreachable(
"Unhandled compound assignment operator");
6275 llvm::LLVMContext &VMContext,
6281 llvm::Value *TotalOffset =
nullptr;
6287 Value *BasePtr_int =
6288 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6290 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6291 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6292 return {TotalOffset, Builder.getFalse()};
6296 assert(GEP->getPointerOperand() == BasePtr &&
6297 "BasePtr must be the base of the GEP.");
6298 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6300 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6303 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6304 auto *SAddIntrinsic =
6305 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6306 auto *SMulIntrinsic =
6307 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6310 llvm::Value *OffsetOverflows = Builder.getFalse();
6314 llvm::Value *RHS) -> llvm::Value * {
6315 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6318 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6319 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6321 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6324 OffsetOverflows = Builder.getTrue();
6325 return llvm::ConstantInt::get(VMContext, N);
6330 auto *ResultAndOverflow = Builder.CreateCall(
6331 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6332 OffsetOverflows = Builder.CreateOr(
6333 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6334 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6338 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6339 GTI != GTE; ++GTI) {
6340 llvm::Value *LocalOffset;
6341 auto *Index = GTI.getOperand();
6343 if (
auto *STy = GTI.getStructTypeOrNull()) {
6347 LocalOffset = llvm::ConstantInt::get(
6348 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6353 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6354 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6355 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6360 if (!TotalOffset || TotalOffset ==
Zero)
6361 TotalOffset = LocalOffset;
6363 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6366 return {TotalOffset, OffsetOverflows};
6371 ArrayRef<Value *> IdxList,
6372 bool SignedIndices,
bool IsSubtraction,
6373 SourceLocation Loc,
const Twine &Name) {
6374 llvm::Type *PtrTy = Ptr->
getType();
6376 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6377 if (!SignedIndices && !IsSubtraction)
6378 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6380 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6383 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6387 bool PerformNullCheck = !NullPointerIsDefined(
6388 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6391 bool PerformOverflowCheck =
6394 if (!(PerformNullCheck || PerformOverflowCheck))
6397 const auto &DL = CGM.getDataLayout();
6399 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6400 auto CheckHandler = SanitizerHandler::PointerOverflow;
6401 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6402 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6404 GEPOffsetAndOverflow EvaluatedGEP =
6409 "If the offset got constant-folded, we don't expect that there was an "
6412 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6420 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6421 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6423 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6427 if (PerformNullCheck) {
6435 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6436 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6437 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6438 Checks.emplace_back(
Valid, CheckOrdinal);
6441 if (PerformOverflowCheck) {
6446 llvm::Value *ValidGEP;
6447 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6448 if (SignedIndices) {
6454 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6455 auto *PosOrZeroOffset =
6457 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6459 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6460 }
else if (!IsSubtraction) {
6465 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6471 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6473 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6474 Checks.emplace_back(ValidGEP, CheckOrdinal);
6477 assert(!Checks.empty() &&
"Should have produced some checks.");
6479 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6481 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6482 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6488 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6489 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6490 const Twine &Name) {
6491 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6492 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6493 if (!SignedIndices && !IsSubtraction)
6494 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6496 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6500 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6501 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6502 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)
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.