36#include "llvm/ADT/APFixedPoint.h"
37#include "llvm/ADT/ScopeExit.h"
38#include "llvm/IR/Argument.h"
39#include "llvm/IR/CFG.h"
40#include "llvm/IR/Constants.h"
41#include "llvm/IR/DataLayout.h"
42#include "llvm/IR/DerivedTypes.h"
43#include "llvm/IR/FixedPointBuilder.h"
44#include "llvm/IR/Function.h"
45#include "llvm/IR/GEPNoWrapFlags.h"
46#include "llvm/IR/GetElementPtrTypeIterator.h"
47#include "llvm/IR/GlobalVariable.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/IntrinsicsPowerPC.h"
50#include "llvm/IR/IntrinsicsWebAssembly.h"
51#include "llvm/IR/MatrixBuilder.h"
52#include "llvm/IR/Module.h"
53#include "llvm/Support/TypeSize.h"
76bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
81 const auto &LHSAP = LHS->getValue();
82 const auto &RHSAP = RHS->getValue();
83 if (Opcode == BO_Add) {
85 : LHSAP.uadd_ov(RHSAP, Overflow);
86 }
else if (Opcode == BO_Sub) {
88 : LHSAP.usub_ov(RHSAP, Overflow);
89 }
else if (Opcode == BO_Mul) {
91 : LHSAP.umul_ov(RHSAP, Overflow);
92 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
93 if (
Signed && !RHS->isZero())
94 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
106 FPOptions FPFeatures;
110 bool mayHaveIntegerOverflow()
const {
112 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
113 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
114 if (!LHSCI || !RHSCI)
118 return ::mayHaveIntegerOverflow(
123 bool isDivremOp()
const {
129 bool mayHaveIntegerDivisionByZero()
const {
131 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
137 bool mayHaveFloatDivisionByZero()
const {
139 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
140 return CFP->isZero();
147 bool isFixedPointOp()
const {
150 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
151 QualType LHSType = BinOp->getLHS()->getType();
152 QualType RHSType = BinOp->getRHS()->getType();
155 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
156 return UnOp->getSubExpr()->getType()->isFixedPointType();
161 bool rhsHasSignedIntegerRepresentation()
const {
162 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
163 QualType RHSType = BinOp->getRHS()->getType();
170static bool MustVisitNullValue(
const Expr *E) {
193static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
203 const OverflowBehaviorType *OBT = Ty->
getAs<OverflowBehaviorType>();
208 switch (OBT->getBehaviorKind()) {
209 case OverflowBehaviorType::OverflowBehaviorKind::Wrap:
211 case OverflowBehaviorType::OverflowBehaviorKind::Trap:
214 llvm_unreachable(
"Unknown OverflowBehaviorKind");
221 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
229 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
233static bool CanElideOverflowCheck(
ASTContext &Ctx,
const BinOpInfo &Op) {
235 "Expected a unary or binary operator");
239 if (!Op.mayHaveIntegerOverflow())
246 const auto *BO = dyn_cast<BinaryOperator>(Op.E);
247 if (BO && BO->hasExcludedOverflowPattern())
250 if (Op.Ty.isWrapType())
252 if (Op.Ty.isTrapType())
255 if (Op.Ty->isSignedIntegerType() &&
261 if (Op.Ty->isUnsignedIntegerType() &&
286 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
292 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
293 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
297class ScalarExprEmitter
299 CodeGenFunction &CGF;
300 CGBuilderTy &Builder;
301 bool IgnoreResultAssign;
302 llvm::LLVMContext &VMContext;
305 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
306 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
307 VMContext(cgf.getLLVMContext()) {
314 bool TestAndClearIgnoreResultAssign() {
315 bool I = IgnoreResultAssign;
316 IgnoreResultAssign =
false;
320 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
321 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
327 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
328 const BinOpInfo &Info);
330 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
334 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
335 const AlignValueAttr *AVAttr =
nullptr;
336 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
337 const ValueDecl *VD = DRE->getDecl();
340 if (
const auto *TTy =
342 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
352 AVAttr = VD->
getAttr<AlignValueAttr>();
357 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
358 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
371 Value *EmitLoadOfLValue(
const Expr *E) {
375 EmitLValueAlignmentAssumption(E,
V);
381 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
385 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
386 Value *Src, QualType SrcType, QualType DstType,
387 llvm::Type *DstTy, SourceLocation Loc);
392 enum ImplicitConversionCheckKind :
unsigned char {
393 ICCK_IntegerTruncation = 0,
394 ICCK_UnsignedIntegerTruncation = 1,
395 ICCK_SignedIntegerTruncation = 2,
396 ICCK_IntegerSignChange = 3,
397 ICCK_SignedIntegerTruncationOrSignChange = 4,
402 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
403 QualType DstType, SourceLocation Loc,
404 bool OBTrapInvolved =
false);
409 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
410 QualType DstType, SourceLocation Loc,
411 bool OBTrapInvolved =
false);
415 struct ScalarConversionOpts {
416 bool TreatBooleanAsSigned;
417 bool EmitImplicitIntegerTruncationChecks;
418 bool EmitImplicitIntegerSignChangeChecks;
420 bool PatternExcluded;
422 ScalarConversionOpts()
423 : TreatBooleanAsSigned(
false),
424 EmitImplicitIntegerTruncationChecks(
false),
425 EmitImplicitIntegerSignChangeChecks(
false), PatternExcluded(
false) {}
427 ScalarConversionOpts(clang::SanitizerSet SanOpts)
428 : TreatBooleanAsSigned(
false),
429 EmitImplicitIntegerTruncationChecks(
430 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
431 EmitImplicitIntegerSignChangeChecks(
432 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)),
433 PatternExcluded(
false) {}
435 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
436 llvm::Type *SrcTy, llvm::Type *DstTy,
437 ScalarConversionOpts Opts);
439 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
441 ScalarConversionOpts Opts = ScalarConversionOpts());
445 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
451 QualType SrcTy, QualType DstTy,
455 Value *EmitNullValue(QualType Ty);
460 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
461 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
465 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
468 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
475 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
476 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
482 ZI->eraseFromParent();
487 return Builder.CreateIsNotNull(
V,
"tobool");
494 Value *Visit(Expr *E) {
495 ApplyDebugLocation DL(CGF, E);
496 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
499 Value *VisitStmt(Stmt *S) {
501 llvm_unreachable(
"Stmt can't have complex result type!");
503 Value *VisitExpr(Expr *S);
505 Value *VisitConstantExpr(ConstantExpr *E) {
511 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
526 Value *VisitParenExpr(ParenExpr *PE) {
529 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
532 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
533 return Visit(
GE->getResultExpr());
535 Value *VisitCoawaitExpr(CoawaitExpr *S) {
538 Value *VisitCoyieldExpr(CoyieldExpr *S) {
541 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
546 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
547 return Builder.getInt(E->
getValue());
549 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
550 return Builder.getInt(E->
getValue());
552 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
553 return llvm::ConstantFP::get(VMContext, E->
getValue());
555 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
558 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
561 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
562 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
564 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
565 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
567 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
571 return EmitNullValue(E->
getType());
573 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
574 return EmitNullValue(E->
getType());
576 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
577 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
578 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
580 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
583 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
587 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
591 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
592 Value *VisitEmbedExpr(EmbedExpr *E);
594 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
603 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
604 llvm_unreachable(
"Codegen for this isn't defined/implemented");
608 Value *VisitDeclRefExpr(DeclRefExpr *E) {
611 return EmitLoadOfLValue(E);
614 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
617 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
620 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
621 return EmitLoadOfLValue(E);
623 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
626 return EmitLoadOfLValue(E);
630 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
636 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
642 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
647 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
648 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
649 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
650 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
651 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
652 Value *VisitMemberExpr(MemberExpr *E);
653 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
654 Value *VisitMatrixElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
655 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
661 return EmitLoadOfLValue(E);
664 Value *VisitInitListExpr(InitListExpr *E);
666 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
668 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
672 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
673 return EmitNullValue(E->
getType());
675 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
677 return VisitCastExpr(E);
681 Value *VisitCallExpr(
const CallExpr *E) {
683 return EmitLoadOfLValue(E);
685 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
689 EmitLValueAlignmentAssumption(E,
V);
693 Value *VisitStmtExpr(
const StmtExpr *E);
696 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
698 return EmitScalarPrePostIncDec(E, LV,
false,
false);
700 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
702 return EmitScalarPrePostIncDec(E, LV,
true,
false);
704 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
706 return EmitScalarPrePostIncDec(E, LV,
false,
true);
708 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
710 return EmitScalarPrePostIncDec(E, LV,
true,
true);
713 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
717 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
718 bool isInc,
bool isPre);
721 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
725 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
727 Value *VisitUnaryDeref(
const UnaryOperator *E) {
730 return EmitLoadOfLValue(E);
733 Value *VisitUnaryPlus(
const UnaryOperator *E,
734 QualType PromotionType = QualType());
735 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
736 Value *VisitUnaryMinus(
const UnaryOperator *E,
737 QualType PromotionType = QualType());
738 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
740 Value *VisitUnaryNot (
const UnaryOperator *E);
741 Value *VisitUnaryLNot (
const UnaryOperator *E);
742 Value *VisitUnaryReal(
const UnaryOperator *E,
743 QualType PromotionType = QualType());
744 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
745 Value *VisitUnaryImag(
const UnaryOperator *E,
746 QualType PromotionType = QualType());
747 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
748 Value *VisitUnaryExtension(
const UnaryOperator *E) {
753 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
754 return EmitLoadOfLValue(E);
756 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
764 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
765 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
768 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
769 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
772 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
776 Value *VisitExprWithCleanups(ExprWithCleanups *E);
777 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
780 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
785 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
787 return llvm::ConstantInt::get(ConvertType(E->
getType()),
791 return llvm::ConstantInt::get(ConvertType(E->
getType()),
795 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
803 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
804 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
807 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
808 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
811 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
821 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
822 return EmitNullValue(E->
getType());
825 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
830 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
831 return Builder.getInt1(E->
getValue());
835 Value *EmitMul(
const BinOpInfo &Ops) {
836 if (Ops.Ty->isSignedIntegerOrEnumerationType() ||
837 Ops.Ty->isUnsignedIntegerType()) {
838 const bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
840 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
841 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
842 switch (getOverflowBehaviorConsideringType(CGF, Ops.Ty)) {
843 case LangOptions::OB_Wrap:
844 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
845 case LangOptions::OB_SignedAndDefined:
847 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
849 case LangOptions::OB_Unset:
851 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
852 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
854 case LangOptions::OB_Trap:
855 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
856 return isSigned ? Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul")
857 : Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
858 return EmitOverflowCheckedBinOp(Ops);
862 if (Ops.Ty->isConstantMatrixType()) {
863 llvm::MatrixBuilder MB(Builder);
867 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
868 BO->getLHS()->getType().getCanonicalType());
869 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
870 BO->getRHS()->getType().getCanonicalType());
871 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
872 if (LHSMatTy && RHSMatTy)
873 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
874 LHSMatTy->getNumColumns(),
875 RHSMatTy->getNumColumns());
876 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
879 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
881 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
882 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
884 if (Ops.isFixedPointOp())
885 return EmitFixedPointBinOp(Ops);
886 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
890 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
893 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
894 llvm::Value *
Zero,
bool isDiv);
896 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
902 Value *EmitDiv(
const BinOpInfo &Ops);
903 Value *EmitRem(
const BinOpInfo &Ops);
904 Value *EmitAdd(
const BinOpInfo &Ops);
905 Value *EmitSub(
const BinOpInfo &Ops);
906 Value *EmitShl(
const BinOpInfo &Ops);
907 Value *EmitShr(
const BinOpInfo &Ops);
908 Value *EmitAnd(
const BinOpInfo &Ops) {
909 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
911 Value *EmitXor(
const BinOpInfo &Ops) {
912 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
914 Value *EmitOr (
const BinOpInfo &Ops) {
915 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
919 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
921 BinOpInfo EmitBinOps(
const BinaryOperator *E,
922 QualType PromotionTy = QualType());
924 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
925 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
926 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
928 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
929 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
932 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
933 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
935 QualType getPromotionType(QualType Ty) {
937 if (
auto *CT = Ty->
getAs<ComplexType>()) {
938 QualType ElementType = CT->getElementType();
939 if (ElementType.UseExcessPrecision(Ctx))
944 if (
auto *VT = Ty->
getAs<VectorType>()) {
945 unsigned NumElements = VT->getNumElements();
955#define HANDLEBINOP(OP) \
956 Value *VisitBin##OP(const BinaryOperator *E) { \
957 QualType promotionTy = getPromotionType(E->getType()); \
958 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
959 if (result && !promotionTy.isNull()) \
960 result = EmitUnPromotedValue(result, E->getType()); \
963 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
964 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
965 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
981 llvm::CmpInst::Predicate SICmpOpc,
982 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
983#define VISITCOMP(CODE, UI, SI, FP, SIG) \
984 Value *VisitBin##CODE(const BinaryOperator *E) { \
985 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
986 llvm::FCmpInst::FP, SIG); }
987 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
1001 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
1002 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
1004 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
1009 Value *VisitBlockExpr(
const BlockExpr *BE);
1010 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
1011 Value *VisitChooseExpr(ChooseExpr *CE);
1012 Value *VisitVAArgExpr(VAArgExpr *VE);
1013 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
1016 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1019 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1022 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1025 Value *VisitAsTypeExpr(AsTypeExpr *CE);
1026 Value *VisitAtomicExpr(AtomicExpr *AE);
1027 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
1040 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
1043 return EmitFloatToBoolConversion(Src);
1045 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
1049 if (SrcType == CGF.
getContext().AMDGPUFeaturePredicateTy)
1053 "Unknown scalar type to convert");
1056 return EmitIntToBoolConversion(Src);
1059 return EmitPointerToBoolConversion(Src, SrcType);
1062void ScalarExprEmitter::EmitFloatConversionCheck(
1063 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1064 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1065 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1069 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1070 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1071 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1072 using llvm::APFloat;
1075 llvm::Value *Check =
nullptr;
1076 const llvm::fltSemantics &SrcSema =
1086 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1087 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1088 APFloat::opOverflow)
1091 MinSrc = APFloat::getInf(SrcSema,
true);
1095 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1098 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1099 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1100 APFloat::opOverflow)
1103 MaxSrc = APFloat::getInf(SrcSema,
false);
1107 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1112 const llvm::fltSemantics &Sema =
1115 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1116 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1120 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1122 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1123 Check = Builder.CreateAnd(GE, LE);
1128 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1134static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1135 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1138 llvm::Type *SrcTy = Src->
getType();
1139 llvm::Type *DstTy = Dst->
getType();
1144 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1146 "non-integer llvm type");
1153 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1155 if (!SrcSigned && !DstSigned) {
1156 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1157 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1159 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1160 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1163 llvm::Value *Check =
nullptr;
1165 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1167 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1169 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1177void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1178 Value *Dst, QualType DstType,
1180 bool OBTrapInvolved) {
1181 if (!CGF.
SanOpts.
hasOneOf(SanitizerKind::ImplicitIntegerTruncation) &&
1191 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1192 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1194 if (SrcBits <= DstBits)
1197 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1204 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1205 (!SrcSigned && DstSigned))
1208 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1209 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1212 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1217 SanitizerDebugLocation SanScope(
1219 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1220 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1236 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1244 if (
const auto *OBT = DstType->
getAs<OverflowBehaviorType>()) {
1245 if (OBT->isWrapKind())
1248 if (ignoredBySanitizer && !OBTrapInvolved)
1251 llvm::Constant *StaticArgs[] = {
1254 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1255 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1257 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1264 llvm::Type *VTy =
V->getType();
1267 return llvm::ConstantInt::getFalse(VTy->getContext());
1269 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1270 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1271 llvm::Twine(Name) +
"." +
V->getName() +
1272 ".negativitycheck");
1277static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1278 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1281 llvm::Type *SrcTy = Src->
getType();
1282 llvm::Type *DstTy = Dst->
getType();
1285 "non-integer llvm type");
1291 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1292 unsigned DstBits = DstTy->getScalarSizeInBits();
1296 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1297 "either the widths should be different, or the signednesses.");
1300 llvm::Value *SrcIsNegative =
1303 llvm::Value *DstIsNegative =
1309 llvm::Value *Check =
nullptr;
1310 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1312 return std::make_pair(
1313 ScalarExprEmitter::ICCK_IntegerSignChange,
1314 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1317void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1318 Value *Dst, QualType DstType,
1320 bool OBTrapInvolved) {
1321 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange) &&
1325 llvm::Type *SrcTy = Src->
getType();
1326 llvm::Type *DstTy = Dst->
getType();
1336 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1337 unsigned DstBits = DstTy->getScalarSizeInBits();
1344 if (SrcSigned == DstSigned && SrcBits == DstBits)
1348 if (!SrcSigned && !DstSigned)
1353 if ((DstBits > SrcBits) && DstSigned)
1355 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1356 (SrcBits > DstBits) && SrcSigned) {
1365 if (!OBTrapInvolved) {
1368 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1372 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1377 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1378 SanitizerDebugLocation SanScope(
1380 {SanitizerKind::SO_ImplicitIntegerSignChange,
1381 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1382 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1385 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1386 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1390 ImplicitConversionCheckKind CheckKind;
1391 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1398 CheckKind = Check.first;
1399 Checks.emplace_back(Check.second);
1401 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1402 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1408 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1409 Checks.emplace_back(Check.second);
1413 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange)) {
1414 if (OBTrapInvolved) {
1415 llvm::Value *Combined = Check.second.first;
1416 for (
const auto &
C : Checks)
1417 Combined = Builder.CreateAnd(Combined,
C.first);
1423 llvm::Constant *StaticArgs[] = {
1426 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1427 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1429 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1434static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1435 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1441 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1442 if (!SrcSigned && !DstSigned)
1443 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1445 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1447 llvm::Value *Check =
nullptr;
1449 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1451 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1454 return std::make_pair(
1456 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1461static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1462 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1466 llvm::Value *SrcIsNegative =
1469 llvm::Value *DstIsNegative =
1475 llvm::Value *Check =
nullptr;
1477 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1479 return std::make_pair(
1480 ScalarExprEmitter::ICCK_IntegerSignChange,
1481 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1489 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1507 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1508 unsigned DstBits = Info.
Size;
1513 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1515 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1517 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1518 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1522 bool EmitTruncation = DstBits < SrcBits;
1526 bool EmitTruncationFromUnsignedToSigned =
1527 EmitTruncation && DstSigned && !SrcSigned;
1529 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1530 bool BothUnsigned = !SrcSigned && !DstSigned;
1531 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1538 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1543 else if (EmitSignChange) {
1544 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1545 "either the widths should be different, or the signednesses.");
1551 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1552 if (EmitTruncationFromUnsignedToSigned)
1553 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1555 llvm::Constant *StaticArgs[] = {
1558 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1559 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1561 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1565 QualType DstType, llvm::Type *SrcTy,
1567 ScalarConversionOpts Opts) {
1569 llvm::Type *SrcElementTy;
1570 llvm::Type *DstElementTy;
1580 "cannot cast between matrix and non-matrix types");
1581 SrcElementTy = SrcTy;
1582 DstElementTy = DstTy;
1583 SrcElementType = SrcType;
1584 DstElementType = DstType;
1589 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1594 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1596 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1597 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1601 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1608 llvm::Intrinsic::ID IID =
1609 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1610 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1614 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1615 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1618 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1619 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1620 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1622 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1623 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1624 return Builder.CreateFPExt(Src, DstTy,
"conv");
1629Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1632 ScalarConversionOpts Opts) {
1647 return Builder.CreateIsNotNull(Src,
"tobool");
1650 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1653 "Unhandled scalar conversion from a fixed point type to another type.");
1657 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1660 "Unhandled scalar conversion to a fixed point type from another type.");
1663 QualType NoncanonicalSrcType = SrcType;
1664 QualType NoncanonicalDstType = DstType;
1668 if (SrcType == DstType)
return Src;
1672 llvm::Value *OrigSrc = Src;
1673 QualType OrigSrcType = SrcType;
1674 llvm::Type *SrcTy = Src->
getType();
1678 return EmitConversionToBool(Src, SrcType);
1680 llvm::Type *DstTy = ConvertType(DstType);
1689 const auto *DstOBT = NoncanonicalDstType->
getAs<OverflowBehaviorType>();
1690 const auto *SrcOBT = NoncanonicalSrcType->
getAs<OverflowBehaviorType>();
1691 bool OBTrapInvolved =
1692 (DstOBT && DstOBT->isTrapKind()) || (SrcOBT && SrcOBT->isTrapKind());
1693 bool OBWrapInvolved =
1694 (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
1699 if (DstTy->isFloatingPointTy())
1700 return Builder.CreateFPExt(Src, DstTy,
"conv");
1704 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1710 if (SrcTy == DstTy) {
1711 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1712 (OBTrapInvolved && !OBWrapInvolved))
1713 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1714 NoncanonicalDstType, Loc, OBTrapInvolved);
1722 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1727 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1732 llvm::Value* IntResult =
1733 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1735 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1741 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1748 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1750 "Splatted expr doesn't match with vector element type?");
1754 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1758 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1762 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1763 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1764 if (SrcSize == DstSize)
1765 return Builder.CreateBitCast(Src, DstTy,
"conv");
1778 assert(((SrcElementTy->isIntegerTy() &&
1779 DstElementTy->isIntegerTy()) ||
1780 (SrcElementTy->isFloatingPointTy() &&
1781 DstElementTy->isFloatingPointTy())) &&
1782 "unexpected conversion between a floating-point vector and an "
1786 if (SrcElementTy->isIntegerTy())
1787 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1790 if (SrcSize > DstSize)
1791 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1794 return Builder.CreateFPExt(Src, DstTy,
"conv");
1798 Value *Res =
nullptr;
1799 llvm::Type *ResTy = DstTy;
1806 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1808 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1816 if (SrcTy->isFloatingPointTy())
1817 return Builder.CreateFPTrunc(Src, CGF.
CGM.
HalfTy,
"conv");
1822 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1824 if (DstTy != ResTy) {
1825 Res = Builder.CreateFPTrunc(Res, CGF.
CGM.
HalfTy,
"conv");
1828 assert(ResTy->isIntegerTy(16) &&
1829 "Only half FP requires extra conversion");
1830 Res = Builder.CreateBitCast(Res, ResTy);
1834 if ((Opts.EmitImplicitIntegerTruncationChecks || OBTrapInvolved) &&
1835 !OBWrapInvolved && !Opts.PatternExcluded)
1836 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1837 NoncanonicalDstType, Loc, OBTrapInvolved);
1839 if (Opts.EmitImplicitIntegerSignChangeChecks ||
1840 (OBTrapInvolved && !OBWrapInvolved))
1841 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1842 NoncanonicalDstType, Loc, OBTrapInvolved);
1847Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1849 SourceLocation Loc) {
1850 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1853 Result = FPBuilder.CreateFloatingToFixed(Src,
1856 Result = FPBuilder.CreateFixedToFloating(Src,
1858 ConvertType(DstTy));
1864 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1865 DstFPSema.getWidth(),
1866 DstFPSema.isSigned());
1868 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1871 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1878Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1880 SourceLocation Loc) {
1882 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1887 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1888 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1889 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1896 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1899Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1907void ScalarExprEmitter::EmitBinOpCheck(
1908 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1909 const BinOpInfo &Info) {
1912 SmallVector<llvm::Constant *, 4> StaticData;
1913 SmallVector<llvm::Value *, 2> DynamicData;
1921 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1922 if (UO && UO->
getOpcode() == UO_Minus) {
1923 Check = SanitizerHandler::NegateOverflow;
1925 DynamicData.push_back(Info.RHS);
1929 Check = SanitizerHandler::ShiftOutOfBounds;
1931 StaticData.push_back(
1933 StaticData.push_back(
1935 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1937 Check = SanitizerHandler::DivremOverflow;
1941 int ArithOverflowKind = 0;
1944 Check = SanitizerHandler::AddOverflow;
1945 ArithOverflowKind = diag::UBSanArithKind::Add;
1949 Check = SanitizerHandler::SubOverflow;
1950 ArithOverflowKind = diag::UBSanArithKind::Sub;
1954 Check = SanitizerHandler::MulOverflow;
1955 ArithOverflowKind = diag::UBSanArithKind::Mul;
1959 llvm_unreachable(
"unexpected opcode for bin op check");
1963 SanitizerKind::UnsignedIntegerOverflow) ||
1965 SanitizerKind::SignedIntegerOverflow)) {
1969 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1973 DynamicData.push_back(Info.LHS);
1974 DynamicData.push_back(Info.RHS);
1977 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1984Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1992ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1994 unsigned AddrSpace =
1996 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1999 llvm::Type *ExprTy = ConvertType(E->
getType());
2000 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
2004Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
2006 auto It = E->
begin();
2007 return Builder.getInt((*It)->getValue());
2010Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
2018 unsigned LHSElts = LTy->getNumElements();
2026 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
2027 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
2035 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
2036 MTy->getNumElements());
2037 Value* NewV = llvm::PoisonValue::get(RTy);
2038 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
2039 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
2040 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
2042 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
2043 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
2051 SmallVector<int, 32> Indices;
2055 if (Idx.isSigned() && Idx.isAllOnes())
2056 Indices.push_back(-1);
2058 Indices.push_back(Idx.getZExtValue());
2061 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
2064Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
2072 if (SrcType == DstType)
return Src;
2075 "ConvertVector source type must be a vector");
2077 "ConvertVector destination type must be a vector");
2079 llvm::Type *SrcTy = Src->
getType();
2080 llvm::Type *DstTy = ConvertType(DstType);
2086 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2087 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2089 assert(SrcTy->isVectorTy() &&
2090 "ConvertVector source IR type must be a vector");
2091 assert(DstTy->isVectorTy() &&
2092 "ConvertVector destination IR type must be a vector");
2097 if (DstEltType->isBooleanType()) {
2098 assert((SrcEltTy->isFloatingPointTy() ||
2101 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2102 if (SrcEltTy->isFloatingPointTy()) {
2103 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2104 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2106 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2111 Value *Res =
nullptr;
2116 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2118 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2120 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2122 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2125 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2126 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2127 if (DstEltType->isSignedIntegerOrEnumerationType())
2128 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2130 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2132 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2133 "Unknown real conversion");
2134 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2135 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2136 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2138 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2144Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2153 return Builder.getInt(
Value);
2157 llvm::Value *
Result = EmitLoadOfLValue(E);
2163 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2164 if (llvm::GetElementPtrInst *GEP =
2165 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2166 if (llvm::Instruction *
Pointer =
2167 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2179Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2180 TestAndClearIgnoreResultAssign();
2188 return EmitLoadOfLValue(E);
2196 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2199 Value *
Ret = Builder.CreateExtractElement(Base, Idx,
"vecext");
2203 Ret = Builder.CreateInsertElement(
2204 llvm::PoisonValue::get(llvm::FixedVectorType::get(CGF.
Int8Ty, 1)), Ret,
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 bool IsMatrixRowMajor =
2234 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2235 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2236 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2237 IsMatrixRowMajor,
"matrix_row_idx");
2239 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2240 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2241 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2247Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2248 TestAndClearIgnoreResultAssign();
2256 llvm::MatrixBuilder MB(Builder);
2259 unsigned NumCols = MatrixTy->getNumColumns();
2260 unsigned NumRows = MatrixTy->getNumRows();
2261 bool IsMatrixRowMajor =
2263 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2266 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2271 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2276 int MV = SVI->getMaskValue(Idx);
2283 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2284 "Index operand too large for shufflevector mask!");
2285 return C->getZExtValue();
2288Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2289 bool Ignore = TestAndClearIgnoreResultAssign();
2292 assert((Ignore ==
false ||
2294 "init list ignored");
2311 llvm::VectorType *VType =
2312 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2315 if (NumInitElements == 0) {
2317 return EmitNullValue(E->
getType());
2324 if (NumInitElements == 0) {
2326 return EmitNullValue(E->
getType());
2329 if (NumInitElements == 1) {
2330 Expr *InitVector = E->
getInit(0);
2335 return Visit(InitVector);
2338 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2345 const ConstantMatrixType *ColMajorMT =
nullptr;
2346 if (
const auto *MT = E->
getType()->
getAs<ConstantMatrixType>();
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.");
2591 for (
unsigned Row = 0, RE = MatTy->getNumRows(); Row < RE; Row++) {
2592 for (
unsigned Col = 0, CE = MatTy->getNumColumns(); Col < CE; Col++) {
2595 unsigned LoadIdx = MatTy->getRowMajorFlattenedIndex(Row, Col);
2598 "All flattened source values should be scalars.");
2601 MatTy->getElementType(), Loc);
2602 unsigned MatrixIdx = MatTy->getFlattenedIndex(Row, Col, IsRowMajor);
2603 V = CGF.
Builder.CreateInsertElement(
V, Cast, MatrixIdx);
2610 "Destination type must be a vector, matrix, or builtin type.");
2612 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2621 llvm::scope_exit RestoreCurCast(
2622 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2626 QualType DestTy = CE->
getType();
2628 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2632 bool Ignored = TestAndClearIgnoreResultAssign();
2638 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2639 case CK_BuiltinFnToFnPtr:
2640 llvm_unreachable(
"builtin functions are handled elsewhere");
2642 case CK_LValueBitCast:
2643 case CK_ObjCObjectLValueCast: {
2647 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2650 case CK_LValueToRValueBitCast: {
2656 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2659 case CK_CPointerToObjCPointerCast:
2660 case CK_BlockPointerToObjCPointerCast:
2661 case CK_AnyPointerToBlockPointerCast:
2663 Value *Src = Visit(E);
2664 llvm::Type *SrcTy = Src->
getType();
2665 llvm::Type *DstTy = ConvertType(DestTy);
2676 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2690 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2691 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
2696 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2697 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2698 "Address-space cast must be used to convert address spaces");
2700 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2701 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2703 PT->getPointeeType(),
2714 const QualType SrcType = E->
getType();
2719 Src = Builder.CreateLaunderInvariantGroup(Src);
2727 Src = Builder.CreateStripInvariantGroup(Src);
2732 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2736 if (!PointeeType.
isNull())
2745 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2746 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2749 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2750 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2751 ScalableDstTy = llvm::ScalableVectorType::get(
2752 FixedSrcTy->getElementType(),
2754 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2756 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2757 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2758 llvm::Value *
Result = Builder.CreateInsertVector(
2759 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2761 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2762 if (
Result->getType() != ScalableDstTy)
2764 if (
Result->getType() != DstTy)
2774 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2775 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2778 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2779 FixedDstTy->getElementType()->isIntegerTy(8)) {
2780 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2781 ScalableSrcTy = llvm::ScalableVectorType::get(
2782 ScalableSrcTy->getElementType(),
2784 ScalableSrcTy->getElementCount().getKnownMinValue()));
2785 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2786 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2790 ScalableSrcTy = llvm::ScalableVectorType::get(
2791 FixedDstTy->getElementType(),
2792 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2793 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2795 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2796 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2817 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2820 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2823 case CK_AddressSpaceConversion: {
2824 llvm::Type *DestLTy = ConvertType(DestTy);
2827 auto IsWasmFuncref = [](llvm::Type *
T) {
2828 auto *TET = dyn_cast<llvm::TargetExtType>(
T);
2829 return TET && TET->getName() ==
"wasm.funcref";
2831 bool SrcIsFuncref = IsWasmFuncref(ConvertType(E->
getType()));
2832 bool DestIsFuncref = IsWasmFuncref(DestLTy);
2833 if (SrcIsFuncref && DestIsFuncref) {
2838 if (SrcIsFuncref && !DestIsFuncref) {
2842 llvm::Function *ToPtr =
2844 return CGF.
Builder.CreateCall(ToPtr, {Visit(E)});
2846 if (!SrcIsFuncref && DestIsFuncref) {
2849 Expr::EvalResult NullResult;
2854 return llvm::Constant::getNullValue(DestLTy);
2857 llvm::Function *ToFuncref =
2859 return CGF.
Builder.CreateCall(ToFuncref, {Visit(E)});
2863 Result.Val.isNullPointer()) {
2867 if (
Result.HasSideEffects)
2875 case CK_AtomicToNonAtomic:
2876 case CK_NonAtomicToAtomic:
2877 case CK_UserDefinedConversion:
2884 case CK_BaseToDerived: {
2886 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2900 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2908 case CK_UncheckedDerivedToBase:
2909 case CK_DerivedToBase: {
2922 case CK_ArrayToPointerDecay:
2925 case CK_FunctionToPointerDecay:
2926 return EmitLValue(E).getPointer(CGF);
2928 case CK_NullToPointer:
2929 if (MustVisitNullValue(E))
2935 case CK_NullToMemberPointer: {
2936 if (MustVisitNullValue(E))
2939 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2943 case CK_ReinterpretMemberPointer:
2944 case CK_BaseToDerivedMemberPointer:
2945 case CK_DerivedToBaseMemberPointer: {
2946 Value *Src = Visit(E);
2957 case CK_ARCProduceObject:
2959 case CK_ARCConsumeObject:
2961 case CK_ARCReclaimReturnedObject:
2963 case CK_ARCExtendBlockObject:
2966 case CK_CopyAndAutoreleaseBlockObject:
2969 case CK_FloatingRealToComplex:
2970 case CK_FloatingComplexCast:
2971 case CK_IntegralRealToComplex:
2972 case CK_IntegralComplexCast:
2973 case CK_IntegralComplexToFloatingComplex:
2974 case CK_FloatingComplexToIntegralComplex:
2975 case CK_ConstructorConversion:
2977 case CK_HLSLArrayRValue:
2978 llvm_unreachable(
"scalar cast to non-scalar value");
2980 case CK_LValueToRValue:
2982 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2985 case CK_IntegralToPointer: {
2986 Value *Src = Visit(E);
2990 auto DestLLVMTy = ConvertType(DestTy);
2993 llvm::Value* IntResult =
2994 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2996 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
3002 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
3008 case CK_PointerToIntegral: {
3009 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
3010 auto *PtrExpr = Visit(E);
3013 const QualType SrcType = E->
getType();
3018 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
3022 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
3028 case CK_MatrixCast: {
3029 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3036 case CK_HLSLAggregateSplatCast:
3037 case CK_VectorSplat: {
3038 llvm::Type *DstTy = ConvertType(DestTy);
3039 Value *Elt = Visit(E);
3041 llvm::ElementCount NumElements =
3043 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
3046 case CK_FixedPointCast:
3047 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3050 case CK_FixedPointToBoolean:
3052 "Expected src type to be fixed point type");
3053 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
3054 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3057 case CK_FixedPointToIntegral:
3059 "Expected src type to be fixed point type");
3060 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
3061 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3064 case CK_IntegralToFixedPoint:
3066 "Expected src type to be an integer");
3068 "Expected dest type to be fixed point type");
3069 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3072 case CK_IntegralCast: {
3074 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3075 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
3079 ScalarConversionOpts Opts;
3080 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
3081 if (!ICE->isPartOfExplicitCast())
3082 Opts = ScalarConversionOpts(CGF.
SanOpts);
3084 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3087 case CK_IntegralToFloating: {
3090 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3092 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
3093 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
3095 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3096 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3099 case CK_FloatingToIntegral: {
3102 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3104 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
3105 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
3107 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3108 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3111 case CK_FloatingCast: {
3114 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
3115 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
3116 if (DstElTy->
castAs<BuiltinType>()->getKind() <
3117 SrcElTy->
castAs<BuiltinType>()->getKind())
3118 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
3119 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
3121 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3122 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3125 case CK_FixedPointToFloating:
3126 case CK_FloatingToFixedPoint: {
3127 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3128 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3131 case CK_BooleanToSignedIntegral: {
3132 ScalarConversionOpts Opts;
3133 Opts.TreatBooleanAsSigned =
true;
3134 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
3137 case CK_IntegralToBoolean:
3138 return EmitIntToBoolConversion(Visit(E));
3139 case CK_PointerToBoolean:
3140 return EmitPointerToBoolConversion(Visit(E), E->
getType());
3141 case CK_FloatingToBoolean: {
3142 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
3143 return EmitFloatToBoolConversion(Visit(E));
3145 case CK_MemberPointerToBoolean: {
3146 llvm::Value *MemPtr = Visit(E);
3147 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
3151 case CK_FloatingComplexToReal:
3152 case CK_IntegralComplexToReal:
3155 case CK_FloatingComplexToBoolean:
3156 case CK_IntegralComplexToBoolean: {
3160 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3164 case CK_ZeroToOCLOpaqueType: {
3167 "CK_ZeroToOCLEvent cast on non-event type");
3168 return llvm::Constant::getNullValue(ConvertType(DestTy));
3171 case CK_IntToOCLSampler:
3174 case CK_HLSLVectorTruncation: {
3176 "Destination type must be a vector or builtin type.");
3177 Value *Vec = Visit(E);
3178 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3179 SmallVector<int> Mask;
3180 unsigned NumElts = VecTy->getNumElements();
3181 for (
unsigned I = 0; I != NumElts; ++I)
3184 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3186 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3187 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3189 case CK_HLSLMatrixTruncation: {
3191 "Destination type must be a matrix or builtin type.");
3192 Value *Mat = Visit(E);
3193 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3194 SmallVector<int> Mask(MatTy->getNumElementsFlattened());
3195 unsigned NumCols = MatTy->getNumColumns();
3196 unsigned NumRows = MatTy->getNumRows();
3197 auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>();
3198 assert(SrcMatTy &&
"Source type must be a matrix type.");
3199 assert(NumRows <= SrcMatTy->getNumRows());
3200 assert(NumCols <= SrcMatTy->getNumColumns());
3207 for (
unsigned R = 0;
R < NumRows;
R++)
3208 for (
unsigned C = 0;
C < NumCols;
C++)
3209 Mask[MatTy->getFlattenedIndex(R,
C, IsDstRowMajor)] =
3210 SrcMatTy->getFlattenedIndex(R,
C, IsSrcRowMajor);
3212 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3214 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3215 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3217 case CK_HLSLElementwiseCast: {
3237 llvm_unreachable(
"unknown scalar cast");
3240Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3241 CodeGenFunction::StmtExprEvaluation eval(CGF);
3250Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3251 CodeGenFunction::RunCleanupsScope Scope(CGF);
3255 Scope.ForceCleanup({&
V});
3264 llvm::Value *InVal,
bool IsInc,
3268 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3270 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3271 BinOp.FPFeatures = FPFeatures;
3276llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3277 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3280 llvm::Value *Amount =
3281 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, !IsInc);
3282 StringRef Name = IsInc ?
"inc" :
"dec";
3286 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
3287 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
3289 switch (getOverflowBehaviorConsideringType(CGF, Ty)) {
3290 case LangOptions::OB_Wrap:
3291 return Builder.CreateAdd(InVal, Amount, Name);
3292 case LangOptions::OB_SignedAndDefined:
3294 return Builder.CreateAdd(InVal, Amount, Name);
3296 case LangOptions::OB_Unset:
3298 return Builder.CreateAdd(InVal, Amount, Name);
3300 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3301 : Builder.CreateAdd(InVal, Amount, Name);
3303 case LangOptions::OB_Trap:
3305 return Builder.CreateAdd(InVal, Amount, Name);
3308 if (CanElideOverflowCheck(CGF.
getContext(), Info))
3309 return isSigned ? Builder.CreateNSWAdd(InVal, Amount, Name)
3310 : Builder.CreateAdd(InVal, Amount, Name);
3311 return EmitOverflowCheckedBinOp(Info);
3313 llvm_unreachable(
"Unknown OverflowBehaviorKind");
3318class OMPLastprivateConditionalUpdateRAII {
3320 CodeGenFunction &CGF;
3321 const UnaryOperator *E;
3324 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3325 const UnaryOperator *E)
3327 ~OMPLastprivateConditionalUpdateRAII() {
3336ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3337 bool isInc,
bool isPre) {
3339 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3341 llvm::PHINode *atomicPHI =
nullptr;
3345 QualType SrcType = E->
getType();
3347 int amount = (isInc ? 1 : -1);
3348 bool isSubtraction = !isInc;
3350 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3351 type = atomicTy->getValueType();
3352 if (isInc &&
type->isBooleanType()) {
3355 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3356 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3357 return Builder.getTrue();
3361 return Builder.CreateAtomicRMW(
3362 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3363 llvm::AtomicOrdering::SequentiallyConsistent);
3368 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3369 !(
type->isUnsignedIntegerType() &&
3370 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3372 LangOptions::SOB_Trapping) {
3373 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3374 llvm::AtomicRMWInst::Sub;
3375 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3376 llvm::Instruction::Sub;
3378 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3380 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3381 llvm::AtomicOrdering::SequentiallyConsistent);
3382 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3386 if (
type->isFloatingType()) {
3387 llvm::Type *Ty = ConvertType(
type);
3388 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3389 llvm::AtomicRMWInst::BinOp aop =
3390 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3391 llvm::Instruction::BinaryOps op =
3392 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3393 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3394 llvm::AtomicRMWInst *old =
3396 llvm::AtomicOrdering::SequentiallyConsistent);
3398 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3401 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3404 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3407 Builder.CreateBr(opBB);
3408 Builder.SetInsertPoint(opBB);
3409 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3410 atomicPHI->addIncoming(value, startBB);
3413 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3424 if (isInc &&
type->isBooleanType()) {
3425 value = Builder.getTrue();
3428 }
else if (
type->isIntegerType()) {
3429 QualType promotedType;
3430 bool canPerformLossyDemotionCheck =
false;
3434 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3435 canPerformLossyDemotionCheck =
true;
3436 canPerformLossyDemotionCheck &=
3439 canPerformLossyDemotionCheck &=
3441 type, promotedType);
3442 assert((!canPerformLossyDemotionCheck ||
3443 type->isSignedIntegerOrEnumerationType() ||
3445 ConvertType(
type)->getScalarSizeInBits() ==
3446 ConvertType(promotedType)->getScalarSizeInBits()) &&
3447 "The following check expects that if we do promotion to different "
3448 "underlying canonical type, at least one of the types (either "
3449 "base or promoted) will be signed, or the bitwidths will match.");
3452 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3453 SanitizerKind::ImplicitBitfieldConversion) &&
3454 canPerformLossyDemotionCheck) {
3468 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3469 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3470 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3474 ScalarConversionOpts Opts;
3475 if (!LV.isBitField())
3476 Opts = ScalarConversionOpts(CGF.
SanOpts);
3477 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3479 SrcType = promotedType;
3483 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3489 }
else if (
type->isSignedIntegerOrEnumerationType() ||
3490 type->isUnsignedIntegerType()) {
3491 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3496 llvm::ConstantInt::get(value->getType(), amount, !isInc);
3497 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3501 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3502 QualType
type = ptr->getPointeeType();
3505 if (
const VariableArrayType *vla
3508 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3511 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3514 elemTy, value, numElts,
false, isSubtraction,
3518 }
else if (
type->isFunctionType()) {
3519 llvm::Value *amt = Builder.getInt32(amount);
3522 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3526 false, isSubtraction,
3531 llvm::Value *amt = Builder.getInt32(amount);
3534 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3537 elemTy, value, amt,
false, isSubtraction,
3542 }
else if (
type->isVectorType()) {
3543 if (
type->hasIntegerRepresentation()) {
3544 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3546 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3548 value = Builder.CreateFAdd(
3550 llvm::ConstantFP::get(value->getType(), amount),
3551 isInc ?
"inc" :
"dec");
3555 }
else if (
type->isRealFloatingType()) {
3558 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3564 value = Builder.CreateFPExt(bitcast, CGF.
CGM.
FloatTy,
"incdec.conv");
3567 if (value->getType()->isFloatTy())
3568 amt = llvm::ConstantFP::get(VMContext,
3569 llvm::APFloat(
static_cast<float>(amount)));
3570 else if (value->getType()->isDoubleTy())
3571 amt = llvm::ConstantFP::get(VMContext,
3572 llvm::APFloat(
static_cast<double>(amount)));
3576 llvm::APFloat F(
static_cast<float>(amount));
3578 const llvm::fltSemantics *FS;
3581 if (value->getType()->isFP128Ty())
3583 else if (value->getType()->isHalfTy())
3585 else if (value->getType()->isBFloatTy())
3587 else if (value->getType()->isPPC_FP128Ty())
3591 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3592 amt = llvm::ConstantFP::get(VMContext, F);
3594 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3597 value = Builder.CreateFPTrunc(value, CGF.
CGM.
HalfTy,
"incdec.conv");
3598 value = Builder.CreateBitCast(value, input->getType());
3602 }
else if (
type->isFixedPointType()) {
3609 Info.Opcode = isInc ? BO_Add : BO_Sub;
3611 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3614 if (
type->isSignedFixedPointType()) {
3615 Info.Opcode = isInc ? BO_Sub : BO_Add;
3616 Info.RHS = Builder.CreateNeg(Info.RHS);
3621 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3623 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3624 value = EmitFixedPointBinOp(Info);
3628 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3631 if (!isInc) size = -size;
3632 llvm::Value *sizeValue =
3633 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3636 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3639 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3641 value = Builder.CreateBitCast(value, input->getType());
3645 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3650 llvm::Value *
success = Pair.second;
3651 atomicPHI->addIncoming(old, curBlock);
3652 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3653 Builder.SetInsertPoint(contBB);
3654 return isPre ? value : input;
3658 if (LV.isBitField()) {
3668 return isPre ? value : input;
3672Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3673 QualType PromotionType) {
3674 QualType promotionTy = PromotionType.
isNull()
3677 Value *result = VisitPlus(E, promotionTy);
3678 if (result && !promotionTy.
isNull())
3679 result = EmitUnPromotedValue(result, E->
getType());
3683Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3684 QualType PromotionType) {
3686 TestAndClearIgnoreResultAssign();
3687 if (!PromotionType.
isNull())
3692Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3693 QualType PromotionType) {
3694 QualType promotionTy = PromotionType.
isNull()
3697 Value *result = VisitMinus(E, promotionTy);
3698 if (result && !promotionTy.
isNull())
3699 result = EmitUnPromotedValue(result, E->
getType());
3703Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3704 QualType PromotionType) {
3705 TestAndClearIgnoreResultAssign();
3707 if (!PromotionType.
isNull())
3713 if (Op->
getType()->isFPOrFPVectorTy()) {
3714 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3715 return Builder.CreateFNeg(Op,
"fneg");
3721 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3723 BinOp.Opcode = BO_Sub;
3726 return EmitSub(BinOp);
3729Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3730 TestAndClearIgnoreResultAssign();
3732 return Builder.CreateNot(Op,
"not");
3735Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3739 VectorKind::Generic) {
3743 if (Oper->
getType()->isFPOrFPVectorTy()) {
3744 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3746 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3748 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3749 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3758 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3761 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3764Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3766 Expr::EvalResult EVResult;
3769 return Builder.getInt(
Value);
3774 llvm::Type* ResultType = ConvertType(E->
getType());
3775 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3777 for (
unsigned i = 0; i != n; ++i) {
3779 llvm::Value *Offset =
nullptr;
3786 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3793 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3797 Offset = Builder.CreateMul(Idx, ElemSize);
3802 FieldDecl *MemberDecl = ON.
getField();
3812 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3815 CurrentType = MemberDecl->
getType();
3820 llvm_unreachable(
"dependent __builtin_offsetof");
3837 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3849ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3850 const UnaryExprOrTypeTraitExpr *E) {
3853 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3854 if (
const VariableArrayType *VAT =
3859 bool EvaluateExtent =
true;
3860 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3862 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3864 if (EvaluateExtent) {
3875 if (Kind == UETT_CountOf)
3884 if (!eltSize.
isOne())
3887 return VlaSize.NumElts;
3890 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3896 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3897 }
else if (E->
getKind() == UETT_VectorElements) {
3899 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3907Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3908 QualType PromotionType) {
3909 QualType promotionTy = PromotionType.
isNull()
3912 Value *result = VisitReal(E, promotionTy);
3913 if (result && !promotionTy.
isNull())
3914 result = EmitUnPromotedValue(result, E->
getType());
3918Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3919 QualType PromotionType) {
3926 if (!PromotionType.
isNull()) {
3928 Op, IgnoreResultAssign,
true);
3943 if (!PromotionType.
isNull())
3948Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3949 QualType PromotionType) {
3950 QualType promotionTy = PromotionType.
isNull()
3953 Value *result = VisitImag(E, promotionTy);
3954 if (result && !promotionTy.
isNull())
3955 result = EmitUnPromotedValue(result, E->
getType());
3959Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3960 QualType PromotionType) {
3967 if (!PromotionType.
isNull()) {
3969 Op,
true, IgnoreResultAssign);
3973 return result.second
3989 else if (!PromotionType.
isNull())
3993 if (!PromotionType.
isNull())
3994 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3995 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
4002Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
4003 QualType PromotionType) {
4004 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
4007Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
4008 QualType ExprType) {
4009 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
4012Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
4014 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
4016#define HANDLE_BINOP(OP) \
4018 return Emit##OP(EmitBinOps(BO, PromotionType));
4027 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
4030 return VisitImag(UO, PromotionType);
4032 return VisitReal(UO, PromotionType);
4034 return VisitMinus(UO, PromotionType);
4036 return VisitPlus(UO, PromotionType);
4041 auto result = Visit(
const_cast<Expr *
>(E));
4043 if (!PromotionType.
isNull())
4044 return EmitPromotedValue(result, PromotionType);
4046 return EmitUnPromotedValue(result, E->
getType());
4051BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
4052 QualType PromotionType) {
4053 TestAndClearIgnoreResultAssign();
4057 if (!PromotionType.
isNull())
4058 Result.Ty = PromotionType;
4067LValue ScalarExprEmitter::EmitCompoundAssignLValue(
4068 const CompoundAssignOperator *E,
4069 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
4080 QualType PromotionTypeCR;
4082 if (PromotionTypeCR.
isNull())
4085 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
4086 if (!PromotionTypeRHS.
isNull())
4089 OpInfo.RHS = Visit(E->
getRHS());
4090 OpInfo.Ty = PromotionTypeCR;
4097 llvm::PHINode *atomicPHI =
nullptr;
4098 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
4100 QualType AtomicValueTy = atomicTy->getValueType();
4109 bool CanEmitAtomicRMW;
4111 llvm::Type *IRTy = CGF.
ConvertType(AtomicValueTy);
4115 !OpInfo.FPFeatures.isFPConstrained() &&
4117 llvm::isPowerOf2_64(StoreBits);
4123 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
4125 LangOptions::SOB_Trapping;
4127 if (CanEmitAtomicRMW) {
4128 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
4129 llvm::Instruction::BinaryOps Op;
4131 switch (OpInfo.Opcode) {
4133 AtomicOp = llvm::AtomicRMWInst::FAdd;
4134 Op = llvm::Instruction::FAdd;
4137 AtomicOp = llvm::AtomicRMWInst::FSub;
4138 Op = llvm::Instruction::FSub;
4144 switch (OpInfo.Opcode) {
4146 case BO_MulAssign:
case BO_DivAssign:
4152 AtomicOp = llvm::AtomicRMWInst::Add;
4153 Op = llvm::Instruction::Add;
4156 AtomicOp = llvm::AtomicRMWInst::Sub;
4157 Op = llvm::Instruction::Sub;
4160 AtomicOp = llvm::AtomicRMWInst::And;
4161 Op = llvm::Instruction::And;
4164 AtomicOp = llvm::AtomicRMWInst::Xor;
4165 Op = llvm::Instruction::Xor;
4168 AtomicOp = llvm::AtomicRMWInst::Or;
4169 Op = llvm::Instruction::Or;
4172 llvm_unreachable(
"Invalid compound assignment type");
4175 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
4177 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4181 llvm::AtomicRMWInst *OldVal =
4186 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4192 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4194 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4195 OpInfo.LHS = CGF.
EmitToMemory(OpInfo.LHS, AtomicValueTy);
4196 Builder.CreateBr(opBB);
4197 Builder.SetInsertPoint(opBB);
4198 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4199 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4200 OpInfo.LHS = atomicPHI;
4203 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4205 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4207 if (!PromotionTypeLHS.
isNull())
4208 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4211 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4222 if (LHSLV.isBitField()) {
4224 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4225 }
else if (
const auto *atomicTy = LHSTy->
getAs<AtomicType>()) {
4227 EmitScalarConversion(
Result, PromotionTypeCR, atomicTy->getValueType(),
4228 Loc, ScalarConversionOpts(CGF.
SanOpts));
4230 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4231 ScalarConversionOpts(CGF.
SanOpts));
4235 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4239 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4240 llvm::Value *
success = Pair.second;
4241 atomicPHI->addIncoming(old, curBlock);
4242 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4243 Builder.SetInsertPoint(contBB);
4251 if (LHSLV.isBitField()) {
4267Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4268 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4269 bool Ignore = TestAndClearIgnoreResultAssign();
4270 Value *RHS =
nullptr;
4271 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4282 if (!LHS.isVolatileQualified())
4286 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4289void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4290 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4291 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4294 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4295 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4296 SanitizerKind::SO_IntegerDivideByZero));
4300 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4301 Ops.Ty->hasSignedIntegerRepresentation() &&
4303 Ops.mayHaveIntegerOverflow() &&
4305 SanitizerKind::SignedIntegerOverflow, Ops.Ty)) {
4308 llvm::Value *IntMin =
4309 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4310 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4312 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4313 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4314 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4316 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4319 if (Checks.size() > 0)
4320 EmitBinOpCheck(Checks, Ops);
4323Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4325 SanitizerDebugLocation SanScope(&CGF,
4326 {SanitizerKind::SO_IntegerDivideByZero,
4327 SanitizerKind::SO_SignedIntegerOverflow,
4328 SanitizerKind::SO_FloatDivideByZero},
4329 SanitizerHandler::DivremOverflow);
4330 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4331 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4332 Ops.Ty->isIntegerType() &&
4333 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4334 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4335 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4336 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4337 Ops.Ty->isRealFloatingType() &&
4338 Ops.mayHaveFloatDivisionByZero()) {
4339 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4340 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4342 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4346 if (Ops.Ty->isConstantMatrixType()) {
4347 llvm::MatrixBuilder MB(Builder);
4354 "first operand must be a matrix");
4356 "second operand must be an arithmetic type");
4357 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4358 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4359 Ops.Ty->hasUnsignedIntegerRepresentation());
4362 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4364 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4365 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4369 else if (Ops.isFixedPointOp())
4370 return EmitFixedPointBinOp(Ops);
4371 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4372 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4374 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4377Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4379 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4380 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4381 Ops.Ty->isIntegerType() &&
4382 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4383 SanitizerDebugLocation SanScope(&CGF,
4384 {SanitizerKind::SO_IntegerDivideByZero,
4385 SanitizerKind::SO_SignedIntegerOverflow},
4386 SanitizerHandler::DivremOverflow);
4387 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4388 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4391 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4392 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4394 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4395 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4397 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4400Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4405 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4406 switch (Ops.Opcode) {
4410 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4411 llvm::Intrinsic::uadd_with_overflow;
4412 OverflowKind = SanitizerHandler::AddOverflow;
4417 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4418 llvm::Intrinsic::usub_with_overflow;
4419 OverflowKind = SanitizerHandler::SubOverflow;
4424 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4425 llvm::Intrinsic::umul_with_overflow;
4426 OverflowKind = SanitizerHandler::MulOverflow;
4429 llvm_unreachable(
"Unsupported operation for overflow detection");
4435 SanitizerDebugLocation SanScope(&CGF,
4436 {SanitizerKind::SO_SignedIntegerOverflow,
4437 SanitizerKind::SO_UnsignedIntegerOverflow},
4443 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4444 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4445 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4448 const std::string *handlerName =
4450 if (handlerName->empty()) {
4456 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4457 llvm::Value *NotOf = Builder.CreateNot(overflow);
4459 std::make_pair(NotOf, SanitizerKind::SO_SignedIntegerOverflow),
4462 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4465 if (CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
4466 llvm::Value *NotOf = Builder.CreateNot(overflow);
4468 std::make_pair(NotOf, SanitizerKind::SO_UnsignedIntegerOverflow),
4471 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4476 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4477 llvm::BasicBlock *continueBB =
4481 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4485 Builder.SetInsertPoint(overflowBB);
4488 llvm::Type *Int8Ty = CGF.
Int8Ty;
4489 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4490 llvm::FunctionType *handlerTy =
4491 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4492 llvm::FunctionCallee handler =
4497 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4498 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4502 llvm::Value *handlerArgs[] = {
4505 Builder.getInt8(OpID),
4508 llvm::Value *handlerResult =
4512 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4513 Builder.CreateBr(continueBB);
4515 Builder.SetInsertPoint(continueBB);
4516 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4517 phi->addIncoming(result, initialBB);
4518 phi->addIncoming(handlerResult, overflowBB);
4527 bool isSubtraction) {
4532 Value *pointer = op.LHS;
4533 Expr *pointerOperand =
expr->getLHS();
4535 Expr *indexOperand =
expr->getRHS();
4538 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4539 std::swap(pointer,
index);
4540 std::swap(pointerOperand, indexOperand);
4544 index, isSubtraction);
4550 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4554 auto &DL =
CGM.getDataLayout();
4577 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4579 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4580 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4581 PtrTy->getPointerAddressSpace()))
4584 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4585 auto CheckHandler = SanitizerHandler::PointerOverflow;
4587 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4589 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4590 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4592 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4593 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4598 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4609 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4619 llvm::Value *objectSize =
4625 return Builder.CreateBitCast(result, pointer->getType());
4630 getContext().getAsVariableArrayType(elementType)) {
4632 llvm::Value *numElements =
getVLASize(vla).NumElts;
4641 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4661 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4674 bool negMul,
bool negAdd) {
4675 Value *MulOp0 = MulOp->getOperand(0);
4676 Value *MulOp1 = MulOp->getOperand(1);
4678 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4680 Addend = Builder.CreateFNeg(Addend,
"neg");
4682 Value *FMulAdd =
nullptr;
4683 if (Builder.getIsFPConstrained()) {
4685 "Only constrained operation should be created when Builder is in FP "
4686 "constrained mode");
4687 FMulAdd = Builder.CreateConstrainedFPCall(
4688 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4690 {MulOp0, MulOp1, Addend});
4692 FMulAdd = Builder.CreateCall(
4694 {MulOp0, MulOp1, Addend});
4696 MulOp->eraseFromParent();
4711 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4712 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4713 "Only fadd/fsub can be the root of an fmuladd.");
4716 if (!op.FPFeatures.allowFPContractWithinStatement())
4719 Value *LHS = op.LHS;
4720 Value *RHS = op.RHS;
4724 bool NegLHS =
false;
4725 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4726 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4727 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4728 LHS = LHSUnOp->getOperand(0);
4733 bool NegRHS =
false;
4734 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4735 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4736 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4737 RHS = RHSUnOp->getOperand(0);
4745 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4746 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4747 (LHSBinOp->use_empty() || NegLHS)) {
4751 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4754 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4755 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4756 (RHSBinOp->use_empty() || NegRHS)) {
4760 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4764 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4765 if (LHSBinOp->getIntrinsicID() ==
4766 llvm::Intrinsic::experimental_constrained_fmul &&
4767 (LHSBinOp->use_empty() || NegLHS)) {
4771 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4774 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4775 if (RHSBinOp->getIntrinsicID() ==
4776 llvm::Intrinsic::experimental_constrained_fmul &&
4777 (RHSBinOp->use_empty() || NegRHS)) {
4781 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4788Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4789 if (op.LHS->getType()->isPointerTy() ||
4790 op.RHS->getType()->isPointerTy())
4793 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4794 op.Ty->isUnsignedIntegerType()) {
4795 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4797 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4798 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4799 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4800 case LangOptions::OB_Wrap:
4801 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4802 case LangOptions::OB_SignedAndDefined:
4804 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4806 case LangOptions::OB_Unset:
4808 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4809 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4811 case LangOptions::OB_Trap:
4812 if (CanElideOverflowCheck(CGF.
getContext(), op))
4813 return isSigned ? Builder.CreateNSWAdd(op.LHS, op.RHS,
"add")
4814 : Builder.CreateAdd(op.LHS, op.RHS,
"add");
4815 return EmitOverflowCheckedBinOp(op);
4820 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4821 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4827 if (op.Ty->isConstantMatrixType()) {
4828 llvm::MatrixBuilder MB(Builder);
4829 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4830 return MB.CreateAdd(op.LHS, op.RHS);
4833 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4834 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4835 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4838 if (op.isFixedPointOp())
4839 return EmitFixedPointBinOp(op);
4841 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4846Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4848 using llvm::ConstantInt;
4854 QualType ResultTy = op.Ty;
4855 QualType LHSTy, RHSTy;
4856 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4857 RHSTy = BinOp->getRHS()->getType();
4858 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4863 LHSTy = CAO->getComputationLHSType();
4864 ResultTy = CAO->getComputationResultType();
4866 LHSTy = BinOp->getLHS()->getType();
4867 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4868 LHSTy = UnOp->getSubExpr()->getType();
4869 RHSTy = UnOp->getSubExpr()->getType();
4872 Value *LHS = op.LHS;
4873 Value *RHS = op.RHS;
4878 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4882 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4883 switch (op.Opcode) {
4886 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4890 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4894 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4898 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4902 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4906 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4909 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4911 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4913 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4915 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4920 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4922 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4926 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4939 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4945 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4950Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4952 if (!op.LHS->getType()->isPointerTy()) {
4953 if (op.Ty->isSignedIntegerOrEnumerationType() ||
4954 op.Ty->isUnsignedIntegerType()) {
4955 const bool isSigned = op.Ty->isSignedIntegerOrEnumerationType();
4957 isSigned ? CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)
4958 : CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow);
4959 switch (getOverflowBehaviorConsideringType(CGF, op.Ty)) {
4960 case LangOptions::OB_Wrap:
4961 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4962 case LangOptions::OB_SignedAndDefined:
4964 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4966 case LangOptions::OB_Unset:
4968 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4969 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4971 case LangOptions::OB_Trap:
4972 if (CanElideOverflowCheck(CGF.
getContext(), op))
4973 return isSigned ? Builder.CreateNSWSub(op.LHS, op.RHS,
"sub")
4974 : Builder.CreateSub(op.LHS, op.RHS,
"sub");
4975 return EmitOverflowCheckedBinOp(op);
4980 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4981 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4987 if (op.Ty->isConstantMatrixType()) {
4988 llvm::MatrixBuilder MB(Builder);
4989 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4990 return MB.CreateSub(op.LHS, op.RHS);
4993 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4994 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4995 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4998 if (op.isFixedPointOp())
4999 return EmitFixedPointBinOp(op);
5001 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
5006 if (!op.RHS->getType()->isPointerTy())
5016 LHS = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
5017 RHS = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
5019 LHS = Builder.CreatePtrToAddr(op.LHS,
"sub.ptr.lhs.cast");
5020 RHS = Builder.CreatePtrToAddr(op.RHS,
"sub.ptr.rhs.cast");
5022 LHS = Builder.CreateZExtOrTrunc(LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5024 RHS = Builder.CreateZExtOrTrunc(RHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.ext");
5026 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
5030 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
5032 llvm::Value *divisor =
nullptr;
5035 if (
const VariableArrayType *vla
5038 elementType = VlaSize.Type;
5039 divisor = VlaSize.NumElts;
5043 if (!eltSize.
isOne())
5050 CharUnits elementSize;
5059 if (elementSize.
isOne())
5066 return Builder.CreateSDiv(diffInChars, divisor,
"sub.ptr.div");
5070 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
5073Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
5075 llvm::IntegerType *Ty;
5076 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5084 llvm::Type *RHSTy = RHS->
getType();
5085 llvm::APInt RHSMax =
5086 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
5087 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
5088 if (RHSMax.ult(Ty->getBitWidth()))
5089 return llvm::ConstantInt::get(RHSTy, RHSMax);
5090 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
5094 const Twine &Name) {
5095 llvm::IntegerType *Ty;
5096 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
5101 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
5102 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
5104 return Builder.CreateURem(
5105 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
5108Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
5110 if (Ops.isFixedPointOp())
5111 return EmitFixedPointBinOp(Ops);
5115 Value *RHS = Ops.RHS;
5116 if (Ops.LHS->getType() != RHS->
getType())
5117 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5119 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
5120 Ops.Ty->hasSignedIntegerRepresentation() &&
5123 bool SanitizeUnsignedBase =
5124 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
5125 Ops.Ty->hasUnsignedIntegerRepresentation();
5126 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
5127 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
5130 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
5131 else if ((SanitizeBase || SanitizeExponent) &&
5133 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
5134 if (SanitizeSignedBase)
5135 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
5136 if (SanitizeUnsignedBase)
5137 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
5138 if (SanitizeExponent)
5139 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
5141 SanitizerDebugLocation SanScope(&CGF, Ordinals,
5142 SanitizerHandler::ShiftOutOfBounds);
5143 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
5144 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5145 llvm::Value *WidthMinusOne =
5146 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
5147 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
5149 if (SanitizeExponent) {
5151 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
5158 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
5161 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
5162 llvm::Value *PromotedWidthMinusOne =
5163 (RHS == Ops.RHS) ? WidthMinusOne
5164 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
5166 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
5167 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
5176 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
5177 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
5179 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
5180 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
5182 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
5183 BaseCheck->addIncoming(Builder.getTrue(), Orig);
5184 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
5185 Checks.push_back(std::make_pair(
5186 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
5187 : SanitizerKind::SO_UnsignedShiftBase));
5190 assert(!Checks.empty());
5191 EmitBinOpCheck(Checks, Ops);
5194 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
5197Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
5199 if (Ops.isFixedPointOp())
5200 return EmitFixedPointBinOp(Ops);
5204 Value *RHS = Ops.RHS;
5205 if (Ops.LHS->getType() != RHS->
getType())
5206 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
5210 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
5211 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
5213 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
5214 SanitizerHandler::ShiftOutOfBounds);
5215 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
5216 llvm::Value *
Valid = Builder.CreateICmpULE(
5217 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
5218 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5221 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5222 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5223 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5231 default: llvm_unreachable(
"unexpected element type");
5232 case BuiltinType::Char_U:
5233 case BuiltinType::UChar:
5234 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5235 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5236 case BuiltinType::Char_S:
5237 case BuiltinType::SChar:
5238 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5239 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5240 case BuiltinType::UShort:
5241 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5242 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5243 case BuiltinType::Short:
5244 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5245 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5246 case BuiltinType::UInt:
5247 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5248 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5249 case BuiltinType::Int:
5250 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5251 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5252 case BuiltinType::ULong:
5253 case BuiltinType::ULongLong:
5254 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5255 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5256 case BuiltinType::Long:
5257 case BuiltinType::LongLong:
5258 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5259 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5260 case BuiltinType::Float:
5261 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5262 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5263 case BuiltinType::Double:
5264 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5265 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5266 case BuiltinType::UInt128:
5267 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5268 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5269 case BuiltinType::Int128:
5270 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5271 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5275Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5276 llvm::CmpInst::Predicate UICmpOpc,
5277 llvm::CmpInst::Predicate SICmpOpc,
5278 llvm::CmpInst::Predicate FCmpOpc,
5280 TestAndClearIgnoreResultAssign();
5284 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5290 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5292 BinOpInfo BOInfo = EmitBinOps(E);
5293 Value *LHS = BOInfo.LHS;
5294 Value *RHS = BOInfo.RHS;
5300 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5302 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5305 Value *FirstVecArg = LHS,
5306 *SecondVecArg = RHS;
5308 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5312 default: llvm_unreachable(
"is not a comparison operation");
5324 std::swap(FirstVecArg, SecondVecArg);
5331 if (ElementKind == BuiltinType::Float) {
5333 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5334 std::swap(FirstVecArg, SecondVecArg);
5342 if (ElementKind == BuiltinType::Float) {
5344 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5349 std::swap(FirstVecArg, SecondVecArg);
5354 Value *CR6Param = Builder.getInt32(CR6);
5356 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5364 if (ResultTy->getBitWidth() > 1 &&
5366 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5371 if (BOInfo.isFixedPointOp()) {
5372 Result = EmitFixedPointBinOp(BOInfo);
5373 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5374 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5376 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5378 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5380 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5395 LHS = Builder.CreateStripInvariantGroup(LHS);
5397 RHS = Builder.CreateStripInvariantGroup(RHS);
5400 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5406 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5415 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5417 CETy = CTy->getElementType();
5419 LHS.first = Visit(E->
getLHS());
5420 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5423 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5426 CTy->getElementType()) &&
5427 "The element types must always match.");
5430 RHS.first = Visit(E->
getRHS());
5431 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5433 "The element types must always match.");
5436 Value *ResultR, *ResultI;
5440 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5441 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5445 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5446 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5450 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5453 "Complex comparison other than == or != ?");
5454 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5466 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5467 CastKind Kind = ICE->getCastKind();
5468 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5469 *SrcType = ICE->getSubExpr()->getType();
5482 bool Ignore = TestAndClearIgnoreResultAssign();
5516 RHS = Visit(E->
getRHS());
5532 RHS = Visit(E->
getRHS());
5572 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5575Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5586 if (LHS->
getType()->isFPOrFPVectorTy()) {
5587 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5589 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5590 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5592 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5593 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5595 Value *
And = Builder.CreateAnd(LHS, RHS);
5596 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5600 llvm::Type *ResTy = ConvertType(E->
getType());
5619 if (InstrumentRegions &&
5623 llvm::BasicBlock *RHSSkip =
5626 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
5643 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5654 return llvm::Constant::getNullValue(ResTy);
5665 llvm::BasicBlock *LHSFalseBlock =
5668 CodeGenFunction::ConditionalEvaluation eval(CGF);
5683 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5685 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5687 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5696 RHSBlock = Builder.GetInsertBlock();
5701 llvm::BasicBlock *ContIncoming = RHSBlock;
5702 if (InstrumentRegions &&
5706 llvm::BasicBlock *RHSBlockSkip =
5708 Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
5712 PN->addIncoming(RHSCond, RHSBlockCnt);
5717 ContIncoming = RHSBlockSkip;
5728 PN->addIncoming(RHSCond, ContIncoming);
5737 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5741 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5744Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5755 if (LHS->
getType()->isFPOrFPVectorTy()) {
5756 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5758 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5759 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5761 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5762 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5764 Value *
Or = Builder.CreateOr(LHS, RHS);
5765 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5769 llvm::Type *ResTy = ConvertType(E->
getType());
5788 if (InstrumentRegions &&
5792 llvm::BasicBlock *RHSSkip =
5795 Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt);
5812 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5823 return llvm::ConstantInt::get(ResTy, 1);
5833 llvm::BasicBlock *LHSTrueBlock =
5836 CodeGenFunction::ConditionalEvaluation eval(CGF);
5852 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5854 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5856 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5868 RHSBlock = Builder.GetInsertBlock();
5873 llvm::BasicBlock *ContIncoming = RHSBlock;
5874 if (InstrumentRegions &&
5878 llvm::BasicBlock *RHSTrueBlock =
5880 Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt);
5884 PN->addIncoming(RHSCond, RHSBlockCnt);
5889 ContIncoming = RHSTrueBlock;
5896 PN->addIncoming(RHSCond, ContIncoming);
5903 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5906Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5909 return Visit(E->
getRHS());
5934Value *ScalarExprEmitter::
5935VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5936 TestAndClearIgnoreResultAssign();
5939 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5941 Expr *condExpr = E->
getCond();
5949 Expr *live = lhsExpr, *dead = rhsExpr;
5950 if (!CondExprBool) std::swap(live, dead);
5977 llvm::Value *LHS = Visit(lhsExpr);
5978 llvm::Value *RHS = Visit(rhsExpr);
5980 llvm::Type *condType = ConvertType(condExpr->
getType());
5983 unsigned numElem = vecTy->getNumElements();
5984 llvm::Type *elemType = vecTy->getElementType();
5986 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5987 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5988 llvm::Value *tmp = Builder.CreateSExt(
5989 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5990 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5993 llvm::Value *RHSTmp = RHS;
5994 llvm::Value *LHSTmp = LHS;
5995 bool wasCast =
false;
5997 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5998 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5999 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
6003 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
6004 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
6005 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
6007 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
6017 llvm::Value *LHS = Visit(lhsExpr);
6018 llvm::Value *RHS = Visit(rhsExpr);
6020 llvm::Type *CondType = ConvertType(condExpr->
getType());
6023 if (VecTy->getElementType()->isIntegerTy(1))
6024 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
6027 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
6029 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
6031 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
6032 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
6042 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
6046 llvm::Value *LHS = Visit(lhsExpr);
6047 llvm::Value *RHS = Visit(rhsExpr);
6050 assert(!RHS &&
"LHS and RHS types must match");
6053 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
6064 CodeGenFunction::ConditionalEvaluation eval(CGF);
6078 Value *LHS = Visit(lhsExpr);
6081 LHSBlock = Builder.GetInsertBlock();
6082 Builder.CreateBr(ContBlock);
6094 Value *RHS = Visit(rhsExpr);
6097 RHSBlock = Builder.GetInsertBlock();
6107 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
6108 PN->addIncoming(LHS, LHSBlock);
6109 PN->addIncoming(RHS, RHSBlock);
6114Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
6118Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
6120 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
6125Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
6131 Value *Src,
unsigned NumElementsDst) {
6132 static constexpr int Mask[] = {0, 1, 2, -1};
6133 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
6153 const llvm::DataLayout &DL,
6154 Value *Src, llvm::Type *DstTy,
6155 StringRef Name =
"") {
6159 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
6160 return Builder.CreateBitCast(Src, DstTy, Name);
6163 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
6164 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
6167 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
6169 if (!DstTy->isIntegerTy())
6170 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
6172 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
6176 if (!SrcTy->isIntegerTy())
6177 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
6179 return Builder.CreateIntToPtr(Src, DstTy, Name);
6182Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
6184 llvm::Type *DstTy = ConvertType(E->
getType());
6186 llvm::Type *SrcTy = Src->
getType();
6187 unsigned NumElementsSrc =
6191 unsigned NumElementsDst =
6202 if (NumElementsSrc == 3 && NumElementsDst != 3) {
6207 Src->setName(
"astype");
6214 if (NumElementsSrc != 3 && NumElementsDst == 3) {
6215 auto *Vec4Ty = llvm::FixedVectorType::get(
6221 Src->setName(
"astype");
6226 Src, DstTy,
"astype");
6229Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
6241 "Invalid scalar expression to emit");
6243 return ScalarExprEmitter(*
this, IgnoreResultAssign)
6244 .Visit(
const_cast<Expr *
>(E));
6253 "Invalid scalar expression to emit");
6254 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6264 "Invalid complex -> scalar conversion");
6265 return ScalarExprEmitter(*
this)
6266 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6273 if (!PromotionType.
isNull())
6274 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6276 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6282 bool isInc,
bool isPre) {
6283 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6293 llvm::Type *BaseTy =
6309 ScalarExprEmitter Scalar(*
this);
6312#define COMPOUND_OP(Op) \
6313 case BO_##Op##Assign: \
6314 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6351 llvm_unreachable(
"Not valid compound assignment operators");
6354 llvm_unreachable(
"Unhandled compound assignment operator");
6369 llvm::LLVMContext &VMContext,
6375 llvm::Value *TotalOffset =
nullptr;
6381 Value *BasePtr_int =
6382 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6384 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6385 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6386 return {TotalOffset, Builder.getFalse()};
6390 assert(GEP->getPointerOperand() == BasePtr &&
6391 "BasePtr must be the base of the GEP.");
6392 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6394 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6397 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6398 auto *SAddIntrinsic =
6399 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6400 auto *SMulIntrinsic =
6401 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6404 llvm::Value *OffsetOverflows = Builder.getFalse();
6408 llvm::Value *RHS) -> llvm::Value * {
6409 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6412 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6413 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6415 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6418 OffsetOverflows = Builder.getTrue();
6419 return llvm::ConstantInt::get(VMContext, N);
6424 auto *ResultAndOverflow = Builder.CreateCall(
6425 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6426 OffsetOverflows = Builder.CreateOr(
6427 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6428 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6432 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6433 GTI != GTE; ++GTI) {
6434 llvm::Value *LocalOffset;
6435 auto *Index = GTI.getOperand();
6437 if (
auto *STy = GTI.getStructTypeOrNull()) {
6441 LocalOffset = llvm::ConstantInt::get(
6442 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6447 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6448 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6449 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6454 if (!TotalOffset || TotalOffset ==
Zero)
6455 TotalOffset = LocalOffset;
6457 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6460 return {TotalOffset, OffsetOverflows};
6465 ArrayRef<Value *> IdxList,
6466 bool SignedIndices,
bool IsSubtraction,
6467 SourceLocation Loc,
const Twine &Name) {
6468 llvm::Type *PtrTy =
Ptr->getType();
6470 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6471 if (!SignedIndices && !IsSubtraction)
6472 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6474 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6477 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6481 bool PerformNullCheck = !NullPointerIsDefined(
6482 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6485 bool PerformOverflowCheck =
6488 if (!(PerformNullCheck || PerformOverflowCheck))
6491 const auto &DL = CGM.getDataLayout();
6493 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6494 auto CheckHandler = SanitizerHandler::PointerOverflow;
6495 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6496 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6498 GEPOffsetAndOverflow EvaluatedGEP =
6501 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6511 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6512 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6514 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6518 if (PerformNullCheck) {
6526 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6527 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6528 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6529 Checks.emplace_back(
Valid, CheckOrdinal);
6532 if (PerformOverflowCheck) {
6537 llvm::Value *ValidGEP;
6538 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6539 if (SignedIndices) {
6545 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6546 auto *PosOrZeroOffset =
6548 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6550 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6551 }
else if (!IsSubtraction) {
6556 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6562 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6564 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6565 Checks.emplace_back(ValidGEP, CheckOrdinal);
6568 assert(!Checks.empty() &&
"Should have produced some checks.");
6570 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6572 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6573 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6579 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6580 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6581 const Twine &Name) {
6582 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6583 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6584 if (!SignedIndices && !IsSubtraction)
6585 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6587 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6591 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6592 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6593 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static mlir::Value tryEmitFMulAdd(mlir::Location loc, const BinOpInfo &op, CIRGenBuilderTy &builder, bool isSub=false)
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static mlir::Value buildFMulAdd(mlir::Location addLoc, cir::FMulOp mulOp, mlir::Value addend, CIRGenBuilderTy &builder, bool negMul, bool negAdd)
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
Result
Implement __builtin_bit_cast and related operations.
Defines AST-level helper utilities for matrix types.
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
bool isNullPointer() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isUnaryOverflowPatternExcluded(const UnaryOperator *UO)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
@ UseSkipPath
Skip (false)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
bool hasSkipCounter(const Stmt *S) const
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
void markStmtAsUsed(bool Skipped, const Stmt *S)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isMCDCDecisionExpr(const Expr *E) const
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
const Qualifiers & getQuals() const
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned mapRowMajorToColumnMajorFlattenedIndex(unsigned RowMajorIdx) const
Given a row-major flattened index RowMajorIdx, return the equivalent column-major flattened index.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
bool isSignedOverflowDefined() const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
PRESERVE_NONE bool Ret(InterpState &S)
@ Address
A pointer to a ValueDecl.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::Type * HalfTy
half, bfloat, float, double
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool HasSideEffects
Whether the evaluated expression has side effects.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.