28 #include "llvm/ADT/Optional.h" 29 #include "llvm/IR/CFG.h" 30 #include "llvm/IR/Constants.h" 31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/Function.h" 33 #include "llvm/IR/GetElementPtrTypeIterator.h" 34 #include "llvm/IR/GlobalVariable.h" 35 #include "llvm/IR/Intrinsics.h" 36 #include "llvm/IR/Module.h" 39 using namespace clang;
40 using namespace CodeGen;
54 bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
56 llvm::APInt &Result) {
59 const auto &LHSAP = LHS->getValue();
60 const auto &RHSAP = RHS->getValue();
61 if (Opcode == BO_Add) {
63 Result = LHSAP.sadd_ov(RHSAP, Overflow);
65 Result = LHSAP.uadd_ov(RHSAP, Overflow);
66 }
else if (Opcode == BO_Sub) {
68 Result = LHSAP.ssub_ov(RHSAP, Overflow);
70 Result = LHSAP.usub_ov(RHSAP, Overflow);
71 }
else if (Opcode == BO_Mul) {
73 Result = LHSAP.smul_ov(RHSAP, Overflow);
75 Result = LHSAP.umul_ov(RHSAP, Overflow);
76 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
77 if (Signed && !RHS->isZero())
78 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
94 bool mayHaveIntegerOverflow()
const {
96 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
97 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
102 return ::mayHaveIntegerOverflow(
107 bool isDivremOp()
const {
108 return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
109 Opcode == BO_RemAssign;
113 bool mayHaveIntegerDivisionByZero()
const {
115 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
121 bool mayHaveFloatDivisionByZero()
const {
123 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
124 return CFP->isZero();
129 static bool MustVisitNullValue(
const Expr *E) {
152 static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
153 return getUnwidenedIntegerType(Ctx, E).hasValue();
157 static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
158 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
159 "Expected a unary or binary operator");
163 if (!Op.mayHaveIntegerOverflow())
167 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
168 return IsWidenedIntegerOp(Ctx, UO->getSubExpr());
172 const auto *BO = cast<BinaryOperator>(Op.E);
173 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
177 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
186 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
192 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
193 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
198 static void updateFastMathFlags(llvm::FastMathFlags &FMF,
204 static Value *propagateFMFlags(
Value *V,
const BinOpInfo &Op) {
205 if (
auto *I = dyn_cast<llvm::Instruction>(V)) {
206 llvm::FastMathFlags FMF = I->getFastMathFlags();
207 updateFastMathFlags(FMF, Op.FPFeatures);
208 I->setFastMathFlags(FMF);
213 class ScalarExprEmitter
217 bool IgnoreResultAssign;
218 llvm::LLVMContext &VMContext;
222 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
223 VMContext(cgf.getLLVMContext()) {
230 bool TestAndClearIgnoreResultAssign() {
231 bool I = IgnoreResultAssign;
232 IgnoreResultAssign =
false;
242 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
243 const BinOpInfo &Info);
249 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *V) {
250 const AlignValueAttr *AVAttr =
nullptr;
251 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
255 if (
const auto *TTy =
257 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
261 if (isa<ParmVarDecl>(VD))
264 AVAttr = VD->
getAttr<AlignValueAttr>();
269 if (
const auto *TTy =
270 dyn_cast<TypedefType>(E->
getType()))
271 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
277 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
288 EmitLValueAlignmentAssumption(E, V);
298 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
322 llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
323 return Builder.CreateFCmpUNE(V, Zero,
"tobool");
330 return Builder.CreateICmpNE(V, Zero,
"tobool");
337 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
338 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
339 Value *Result = ZI->getOperand(0);
344 ZI->eraseFromParent();
349 return Builder.CreateIsNotNull(V,
"tobool");
363 llvm_unreachable(
"Stmt can't have complex result type!");
388 return Builder.getInt(E->
getValue());
391 return llvm::ConstantFP::get(VMContext, E->
getValue());
394 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
397 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
400 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
403 return EmitNullValue(E->
getType());
406 return EmitNullValue(E->
getType());
433 assert(Constant &&
"not a constant");
443 return emitConstant(Constant, E);
444 return EmitLoadOfLValue(E);
454 return EmitLoadOfLValue(E);
459 return EmitLoadOfLValue(E);
475 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
480 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, Min ? *Min : 0),
481 llvm::ConstantInt::get(CGF.
CGM.
Int32Ty, SMin ? *SMin : 0),
491 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
493 return EmitLoadOfLValue(E);
500 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
505 return EmitNullValue(E->
getType());
509 return VisitCastExpr(E);
515 return EmitLoadOfLValue(E);
519 EmitLValueAlignmentAssumption(E, V);
528 return EmitScalarPrePostIncDec(E, LV,
false,
false);
532 return EmitScalarPrePostIncDec(E, LV,
true,
false);
536 return EmitScalarPrePostIncDec(E, LV,
false,
true);
540 return EmitScalarPrePostIncDec(E, LV,
true,
true);
548 bool isInc,
bool isPre);
552 if (isa<MemberPointerType>(E->
getType()))
555 return EmitLValue(E->
getSubExpr()).getPointer();
560 return EmitLoadOfLValue(E);
564 TestAndClearIgnoreResultAssign();
578 return EmitLoadOfLValue(E);
602 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
606 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
610 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
624 return EmitNullValue(E->
getType());
633 return Builder.getInt1(E->
getValue());
637 Value *EmitMul(
const BinOpInfo &Ops) {
638 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
639 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
641 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
643 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
644 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
647 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
648 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
649 return EmitOverflowCheckedBinOp(Ops);
653 if (Ops.Ty->isUnsignedIntegerType() &&
654 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
655 !CanElideOverflowCheck(CGF.
getContext(), Ops))
656 return EmitOverflowCheckedBinOp(Ops);
658 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
659 Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
660 return propagateFMFlags(V, Ops);
662 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
666 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
669 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
673 Value *EmitDiv(
const BinOpInfo &Ops);
674 Value *EmitRem(
const BinOpInfo &Ops);
675 Value *EmitAdd(
const BinOpInfo &Ops);
676 Value *EmitSub(
const BinOpInfo &Ops);
677 Value *EmitShl(
const BinOpInfo &Ops);
678 Value *EmitShr(
const BinOpInfo &Ops);
679 Value *EmitAnd(
const BinOpInfo &Ops) {
680 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
682 Value *EmitXor(
const BinOpInfo &Ops) {
683 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
685 Value *EmitOr (
const BinOpInfo &Ops) {
686 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
691 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
695 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
698 #define HANDLEBINOP(OP) \ 699 Value *VisitBin ## OP(const BinaryOperator *E) { \ 700 return Emit ## OP(EmitBinOps(E)); \ 702 Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \ 703 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \ 719 llvm::CmpInst::Predicate SICmpOpc,
720 llvm::CmpInst::Predicate FCmpOpc);
721 #define VISITCOMP(CODE, UI, SI, FP) \ 722 Value *VisitBin##CODE(const BinaryOperator *E) { \ 723 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ 724 llvm::FCmpInst::FP); } 725 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT)
726 VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT)
727 VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE)
728 VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE)
729 VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ)
730 VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE)
739 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
740 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
771 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
774 return EmitFloatToBoolConversion(Src);
779 assert((SrcType->
isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
780 "Unknown scalar type to convert");
782 if (isa<llvm::IntegerType>(Src->getType()))
783 return EmitIntToBoolConversion(Src);
785 assert(isa<llvm::PointerType>(Src->getType()));
786 return EmitPointerToBoolConversion(Src, SrcType);
789 void ScalarExprEmitter::EmitFloatConversionCheck(
799 if (llvm::IntegerType *IntTy = dyn_cast<llvm::IntegerType>(SrcTy)) {
805 APFloat LargestFloat =
807 APSInt LargestInt(IntTy->getBitWidth(), SrcIsUnsigned);
810 if (LargestFloat.convertToInteger(LargestInt, APFloat::rmTowardZero,
811 &IsExact) != APFloat::opOK)
816 llvm::Value *Max = llvm::ConstantInt::get(VMContext, LargestInt);
818 Check = Builder.CreateICmpULE(Src, Max);
820 llvm::Value *Min = llvm::ConstantInt::get(VMContext, -LargestInt);
823 Check = Builder.CreateAnd(GE, LE);
826 const llvm::fltSemantics &SrcSema =
828 if (isa<llvm::IntegerType>(DstTy)) {
835 APSInt Min = APSInt::getMinValue(Width, Unsigned);
836 APFloat MinSrc(SrcSema, APFloat::uninitialized);
837 if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
841 MinSrc = APFloat::getInf(SrcSema,
true);
845 MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
847 APSInt Max = APSInt::getMaxValue(Width, Unsigned);
848 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
849 if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
853 MaxSrc = APFloat::getInf(SrcSema,
false);
857 MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
862 const llvm::fltSemantics &
Sema =
865 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
866 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
870 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
872 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
873 Check = Builder.CreateAnd(GE, LE);
894 "should not check conversion from __half, it has the lowest rank");
896 const llvm::fltSemantics &DstSema =
898 APFloat MinBad = APFloat::getLargest(DstSema,
false);
899 APFloat MaxBad = APFloat::getInf(DstSema,
false);
902 MinBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
903 MaxBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
908 Builder.CreateFCmpOGT(AbsSrc, llvm::ConstantFP::get(VMContext, MinBad));
910 Builder.CreateFCmpOLT(AbsSrc, llvm::ConstantFP::get(VMContext, MaxBad));
911 Check = Builder.CreateNot(Builder.CreateAnd(GE, LE));
918 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
919 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
927 return EmitScalarConversion(Src, SrcType, DstType, Loc,
false);
933 bool TreatBooleanAsSigned) {
936 if (SrcType == DstType)
return Src;
946 return EmitConversionToBool(Src, SrcType);
953 if (DstTy->isFloatingPointTy()) {
955 return Builder.CreateCall(
963 Src = Builder.CreateCall(
968 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
982 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
984 if (isa<llvm::PointerType>(SrcTy))
987 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
993 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
995 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
998 if (isa<llvm::PointerType>(SrcTy)) {
1000 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1001 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1010 "Splatted expr doesn't match with vector element type?");
1013 unsigned NumElements = DstTy->getVectorNumElements();
1014 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1017 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1019 unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
1020 unsigned DstSize = DstTy->getPrimitiveSizeInBits();
1021 if (SrcSize == DstSize)
1031 llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
1032 llvm::Type *DstElementTy = DstTy->getVectorElementType();
1035 assert(((SrcElementTy->isIntegerTy() &&
1036 DstElementTy->isIntegerTy()) ||
1037 (SrcElementTy->isFloatingPointTy() &&
1038 DstElementTy->isFloatingPointTy())) &&
1039 "unexpected conversion between a floating-point vector and an " 1043 if (SrcElementTy->isIntegerTy())
1044 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1047 if (SrcSize > DstSize)
1048 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1051 return Builder.CreateFPExt(Src, DstTy,
"conv");
1055 Value *Res =
nullptr;
1060 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1062 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1068 if (SrcTy->isFloatingPointTy()) {
1072 return Builder.CreateCall(
1075 return Builder.CreateFPTrunc(Src, DstTy);
1080 if (isa<llvm::IntegerType>(SrcTy)) {
1085 if (isa<llvm::IntegerType>(DstTy))
1086 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1087 else if (InputSigned)
1088 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1090 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1091 }
else if (isa<llvm::IntegerType>(DstTy)) {
1092 assert(SrcTy->isFloatingPointTy() &&
"Unknown real conversion");
1094 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1096 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1098 assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() &&
1099 "Unknown real conversion");
1100 if (DstTy->getTypeID() < SrcTy->getTypeID())
1101 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1103 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1106 if (DstTy != ResTy) {
1108 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1109 Res = Builder.CreateCall(
1113 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1122 Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1131 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1132 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1133 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1140 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1151 void ScalarExprEmitter::EmitBinOpCheck(
1152 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1164 if (UO && UO->
getOpcode() == UO_Minus) {
1165 Check = SanitizerHandler::NegateOverflow;
1167 DynamicData.push_back(Info.RHS);
1171 Check = SanitizerHandler::ShiftOutOfBounds;
1173 StaticData.push_back(
1175 StaticData.push_back(
1177 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1179 Check = SanitizerHandler::DivremOverflow;
1184 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1185 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1186 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1187 default: llvm_unreachable(
"unexpected opcode for bin op check");
1191 DynamicData.push_back(Info.LHS);
1192 DynamicData.push_back(Info.RHS);
1195 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1202 Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1216 llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
1217 unsigned LHSElts = LTy->getNumElements();
1221 llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
1225 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1226 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1234 llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
1235 MTy->getNumElements());
1236 Value* NewV = llvm::UndefValue::get(RTy);
1237 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1238 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1239 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1241 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1242 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1254 if (Idx.isSigned() && Idx.isAllOnesValue())
1255 indices.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
1257 indices.push_back(Builder.getInt32(Idx.getZExtValue()));
1260 Value *SV = llvm::ConstantVector::get(indices);
1261 return Builder.CreateShuffleVector(V1, V2, SV,
"shuffle");
1272 if (SrcType == DstType)
return Src;
1275 "ConvertVector source type must be a vector");
1277 "ConvertVector destination type must be a vector");
1289 assert(SrcTy->isVectorTy() &&
1290 "ConvertVector source IR type must be a vector");
1291 assert(DstTy->isVectorTy() &&
1292 "ConvertVector destination IR type must be a vector");
1294 llvm::Type *SrcEltTy = SrcTy->getVectorElementType(),
1295 *DstEltTy = DstTy->getVectorElementType();
1297 if (DstEltType->isBooleanType()) {
1298 assert((SrcEltTy->isFloatingPointTy() ||
1299 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1301 llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1302 if (SrcEltTy->isFloatingPointTy()) {
1303 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1305 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1310 Value *Res =
nullptr;
1312 if (isa<llvm::IntegerType>(SrcEltTy)) {
1314 if (isa<llvm::IntegerType>(DstEltTy))
1315 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1316 else if (InputSigned)
1317 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1319 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1320 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1321 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1322 if (DstEltType->isSignedIntegerOrEnumerationType())
1323 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1325 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1327 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1328 "Unknown real conversion");
1329 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1330 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1332 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1341 return emitConstant(Constant, E);
1346 return Builder.getInt(Value);
1350 return EmitLoadOfLValue(E);
1354 TestAndClearIgnoreResultAssign();
1361 return EmitLoadOfLValue(E);
1365 Value *Base = Visit(E->
getBase());
1366 Value *Idx = Visit(E->
getIdx());
1369 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1372 return Builder.CreateExtractElement(Base, Idx,
"vecext");
1375 static llvm::Constant *
getMaskElt(llvm::ShuffleVectorInst *SVI,
unsigned Idx,
1377 int MV = SVI->getMaskValue(Idx);
1379 return llvm::UndefValue::get(I32Ty);
1380 return llvm::ConstantInt::get(I32Ty, Off+MV);
1384 if (C->getBitWidth() != 32) {
1385 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1386 C->getZExtValue()) &&
1387 "Index operand too large for shufflevector mask!");
1388 return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1393 Value *ScalarExprEmitter::VisitInitListExpr(
InitListExpr *E) {
1394 bool Ignore = TestAndClearIgnoreResultAssign();
1396 assert (Ignore ==
false &&
"init list ignored");
1402 llvm::VectorType *VType =
1403 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1406 if (NumInitElements == 0) {
1408 return EmitNullValue(E->
getType());
1414 unsigned ResElts = VType->getNumElements();
1421 unsigned CurIdx = 0;
1422 bool VIsUndefShuffle =
false;
1424 for (
unsigned i = 0; i != NumInitElements; ++i) {
1426 Value *Init = Visit(IE);
1429 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
1435 if (isa<ExtVectorElementExpr>(IE)) {
1436 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
1438 if (EI->getVectorOperandType()->getNumElements() == ResElts) {
1439 llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1440 Value *LHS =
nullptr, *RHS =
nullptr;
1445 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1447 LHS = EI->getVectorOperand();
1449 VIsUndefShuffle =
true;
1450 }
else if (VIsUndefShuffle) {
1452 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
1453 for (
unsigned j = 0; j != CurIdx; ++j)
1455 Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
1456 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1458 LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1459 RHS = EI->getVectorOperand();
1460 VIsUndefShuffle =
false;
1462 if (!Args.empty()) {
1463 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1464 V = Builder.CreateShuffleVector(LHS, RHS, Mask);
1470 V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
1472 VIsUndefShuffle =
false;
1477 unsigned InitElts = VVT->getNumElements();
1482 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1483 if (isa<ExtVectorElementExpr>(IE)) {
1484 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
1485 Value *SVOp = SVI->getOperand(0);
1486 llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
1488 if (OpTy->getNumElements() == ResElts) {
1489 for (
unsigned j = 0; j != CurIdx; ++j) {
1492 if (VIsUndefShuffle) {
1493 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
1496 Args.push_back(Builder.getInt32(j));
1499 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1501 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1503 if (VIsUndefShuffle)
1504 V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1513 for (
unsigned j = 0; j != InitElts; ++j)
1514 Args.push_back(Builder.getInt32(j));
1515 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1516 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1517 Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
1521 for (
unsigned j = 0; j != CurIdx; ++j)
1522 Args.push_back(Builder.getInt32(j));
1523 for (
unsigned j = 0; j != InitElts; ++j)
1524 Args.push_back(Builder.getInt32(j+Offset));
1525 Args.resize(ResElts, llvm::UndefValue::get(CGF.
Int32Ty));
1532 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1533 V = Builder.CreateShuffleVector(V, Init, Mask,
"vecinit");
1534 VIsUndefShuffle = isa<llvm::UndefValue>(Init);
1543 for (; CurIdx < ResElts; ++CurIdx) {
1544 Value *Idx = Builder.getInt32(CurIdx);
1545 llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
1546 V = Builder.CreateInsertElement(V, Init, Idx,
"vecinit");
1554 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
1574 Value *ScalarExprEmitter::VisitCastExpr(
CastExpr *CE) {
1581 bool Ignored = TestAndClearIgnoreResultAssign();
1587 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
1588 case CK_BuiltinFnToFnPtr:
1589 llvm_unreachable(
"builtin functions are handled elsewhere");
1591 case CK_LValueBitCast:
1592 case CK_ObjCObjectLValueCast: {
1593 Address Addr = EmitLValue(E).getAddress();
1596 return EmitLoadOfLValue(LV, CE->
getExprLoc());
1599 case CK_CPointerToObjCPointerCast:
1600 case CK_BlockPointerToObjCPointerCast:
1601 case CK_AnyPointerToBlockPointerCast:
1603 Value *Src = Visit(const_cast<Expr*>(E));
1606 if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
1607 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
1608 llvm_unreachable(
"wrong cast for pointers in different address spaces" 1609 "(must be an address space cast)!");
1612 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
1622 case CK_AddressSpaceConversion: {
1632 ConvertType(DestTy)), DestTy);
1640 case CK_AtomicToNonAtomic:
1641 case CK_NonAtomicToAtomic:
1643 case CK_UserDefinedConversion:
1644 return Visit(const_cast<Expr*>(E));
1646 case CK_BaseToDerived: {
1648 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
1662 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
1671 case CK_UncheckedDerivedToBase:
1672 case CK_DerivedToBase: {
1684 case CK_ArrayToPointerDecay:
1686 case CK_FunctionToPointerDecay:
1687 return EmitLValue(E).getPointer();
1689 case CK_NullToPointer:
1690 if (MustVisitNullValue(E))
1696 case CK_NullToMemberPointer: {
1697 if (MustVisitNullValue(E))
1704 case CK_ReinterpretMemberPointer:
1705 case CK_BaseToDerivedMemberPointer:
1706 case CK_DerivedToBaseMemberPointer: {
1707 Value *Src = Visit(E);
1718 case CK_ARCProduceObject:
1720 case CK_ARCConsumeObject:
1722 case CK_ARCReclaimReturnedObject:
1724 case CK_ARCExtendBlockObject:
1727 case CK_CopyAndAutoreleaseBlockObject:
1730 case CK_FloatingRealToComplex:
1731 case CK_FloatingComplexCast:
1732 case CK_IntegralRealToComplex:
1733 case CK_IntegralComplexCast:
1734 case CK_IntegralComplexToFloatingComplex:
1735 case CK_FloatingComplexToIntegralComplex:
1736 case CK_ConstructorConversion:
1738 llvm_unreachable(
"scalar cast to non-scalar value");
1740 case CK_LValueToRValue:
1742 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
1743 return Visit(const_cast<Expr*>(E));
1745 case CK_IntegralToPointer: {
1746 Value *Src = Visit(const_cast<Expr*>(E));
1750 auto DestLLVMTy = ConvertType(DestTy);
1754 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1756 return Builder.CreateIntToPtr(IntResult, DestLLVMTy);
1758 case CK_PointerToIntegral:
1759 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
1760 return Builder.CreatePtrToInt(Visit(E), ConvertType(DestTy));
1766 case CK_VectorSplat: {
1768 Value *Elt = Visit(const_cast<Expr*>(E));
1770 unsigned NumElements = DstTy->getVectorNumElements();
1771 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
1774 case CK_IntegralCast:
1775 case CK_IntegralToFloating:
1776 case CK_FloatingToIntegral:
1777 case CK_FloatingCast:
1778 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
1780 case CK_BooleanToSignedIntegral:
1781 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
1784 case CK_IntegralToBoolean:
1785 return EmitIntToBoolConversion(Visit(E));
1786 case CK_PointerToBoolean:
1787 return EmitPointerToBoolConversion(Visit(E), E->
getType());
1788 case CK_FloatingToBoolean:
1789 return EmitFloatToBoolConversion(Visit(E));
1790 case CK_MemberPointerToBoolean: {
1796 case CK_FloatingComplexToReal:
1797 case CK_IntegralComplexToReal:
1800 case CK_FloatingComplexToBoolean:
1801 case CK_IntegralComplexToBoolean: {
1805 return EmitComplexToScalarConversion(V, E->
getType(), DestTy,
1809 case CK_ZeroToOCLEvent: {
1810 assert(DestTy->
isEventT() &&
"CK_ZeroToOCLEvent cast on non-event type");
1811 return llvm::Constant::getNullValue(ConvertType(DestTy));
1814 case CK_ZeroToOCLQueue: {
1815 assert(DestTy->
isQueueT() &&
"CK_ZeroToOCLQueue cast on non queue_t type");
1816 return llvm::Constant::getNullValue(ConvertType(DestTy));
1819 case CK_IntToOCLSampler:
1824 llvm_unreachable(
"unknown scalar cast");
1827 Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
1855 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
1857 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
1863 llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
1866 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
1867 StringRef Name = IsInc ?
"inc" :
"dec";
1868 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
1870 return Builder.CreateAdd(InVal, Amount, Name);
1872 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
1873 return Builder.CreateNSWAdd(InVal, Amount, Name);
1877 return Builder.CreateNSWAdd(InVal, Amount, Name);
1880 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
1885 bool isInc,
bool isPre) {
1888 llvm::PHINode *atomicPHI =
nullptr;
1892 int amount = (isInc ? 1 : -1);
1893 bool isSubtraction = !isInc;
1896 type = atomicTy->getValueType();
1901 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
1902 return Builder.getTrue();
1906 return Builder.CreateAtomicRMW(
1907 llvm::AtomicRMWInst::Xchg, LV.
getPointer(), True,
1908 llvm::AtomicOrdering::SequentiallyConsistent);
1915 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
1918 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
1919 llvm::AtomicRMWInst::Sub;
1920 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
1921 llvm::Instruction::Sub;
1923 llvm::ConstantInt::get(ConvertType(type), 1,
true), type);
1925 LV.
getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent);
1926 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
1928 value = EmitLoadOfLValue(LV, E->
getExprLoc());
1931 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
1934 Builder.CreateBr(opBB);
1935 Builder.SetInsertPoint(opBB);
1936 atomicPHI = Builder.CreatePHI(value->getType(), 2);
1937 atomicPHI->addIncoming(value, startBB);
1940 value = EmitLoadOfLValue(LV, E->
getExprLoc());
1952 value = Builder.getTrue();
1958 bool CanOverflow = value->getType()->getIntegerBitWidth() >=
1959 CGF.
IntTy->getIntegerBitWidth();
1961 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
1963 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
1967 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
1968 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
1979 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
1981 value = Builder.CreateGEP(value, numElts,
"vla.inc");
1984 value, numElts,
false, isSubtraction,
1993 value = Builder.CreateGEP(value, amt,
"incdec.funcptr");
2004 value = Builder.CreateGEP(value, amt,
"incdec.ptr");
2014 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2016 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2018 value = Builder.CreateFAdd(
2020 llvm::ConstantFP::get(value->getType(), amount),
2021 isInc ?
"inc" :
"dec");
2032 value = Builder.CreateCall(
2035 input,
"incdec.conv");
2037 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2041 if (value->getType()->isFloatTy())
2042 amt = llvm::ConstantFP::get(VMContext,
2043 llvm::APFloat(static_cast<float>(amount)));
2044 else if (value->getType()->isDoubleTy())
2045 amt = llvm::ConstantFP::get(VMContext,
2046 llvm::APFloat(static_cast<double>(amount)));
2049 llvm::APFloat F(static_cast<float>(amount));
2051 const llvm::fltSemantics *FS;
2054 if (value->getType()->isFP128Ty())
2056 else if (value->getType()->isHalfTy())
2060 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2061 amt = llvm::ConstantFP::get(VMContext, F);
2063 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2067 value = Builder.CreateCall(
2070 value,
"incdec.conv");
2072 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2082 if (!isInc) size = -size;
2087 value = Builder.CreateGEP(value, sizeValue,
"incdec.objptr");
2090 false, isSubtraction,
2096 llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2102 atomicPHI->addIncoming(old, opBB);
2103 Builder.CreateCondBr(success, contBB, opBB);
2104 Builder.SetInsertPoint(contBB);
2105 return isPre ? value : input;
2116 return isPre ? value : input;
2121 Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E) {
2122 TestAndClearIgnoreResultAssign();
2127 if (BinOp.RHS->getType()->isFPOrFPVectorTy())
2128 BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType());
2130 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2132 BinOp.Opcode = BO_Sub;
2135 return EmitSub(BinOp);
2138 Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
2139 TestAndClearIgnoreResultAssign();
2141 return Builder.CreateNot(Op,
"neg");
2144 Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
2148 Value *Zero = llvm::Constant::getNullValue(Oper->getType());
2150 if (Oper->getType()->isFPOrFPVectorTy())
2151 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2153 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2154 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
2163 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
2166 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
2169 Value *ScalarExprEmitter::VisitOffsetOfExpr(
OffsetOfExpr *E) {
2173 return Builder.getInt(Value);
2178 llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
2180 for (
unsigned i = 0; i != n; ++i) {
2189 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
2196 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2200 Offset = Builder.CreateMul(Idx, ElemSize);
2214 Field != FieldEnd; ++Field, ++i) {
2215 if (*Field == MemberDecl)
2218 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
2223 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
2226 CurrentType = MemberDecl->
getType();
2231 llvm_unreachable(
"dependent __builtin_offsetof");
2249 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
2253 Result = Builder.CreateAdd(Result, Offset);
2261 ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
2278 std::tie(numElts, eltType) = CGF.
getVLASize(VAT);
2284 if (!eltSize.
isOne())
2295 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
2303 Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E) {
2320 Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E) {
2340 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
2347 BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E) {
2348 TestAndClearIgnoreResultAssign();
2350 Result.LHS = Visit(E->
getLHS());
2351 Result.RHS = Visit(E->
getRHS());
2359 LValue ScalarExprEmitter::EmitCompoundAssignLValue(
2361 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &),
2371 OpInfo.RHS = Visit(E->
getRHS());
2379 llvm::PHINode *atomicPHI =
nullptr;
2384 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2387 llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP;
2388 switch (OpInfo.Opcode) {
2390 case BO_MulAssign:
case BO_DivAssign:
2396 aop = llvm::AtomicRMWInst::Add;
2399 aop = llvm::AtomicRMWInst::Sub;
2405 aop = llvm::AtomicRMWInst::Xor;
2408 aop = llvm::AtomicRMWInst::Or;
2411 llvm_unreachable(
"Invalid compound assignment type");
2413 if (aop != llvm::AtomicRMWInst::BAD_BINOP) {
2415 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
2418 Builder.CreateAtomicRMW(aop, LHSLV.
getPointer(), amt,
2419 llvm::AtomicOrdering::SequentiallyConsistent);
2425 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2427 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2429 Builder.CreateBr(opBB);
2430 Builder.SetInsertPoint(opBB);
2431 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
2432 atomicPHI->addIncoming(OpInfo.LHS, startBB);
2433 OpInfo.LHS = atomicPHI;
2436 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
2443 Result = (this->*Func)(OpInfo);
2450 llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2456 atomicPHI->addIncoming(old, opBB);
2457 Builder.CreateCondBr(success, contBB, opBB);
2458 Builder.SetInsertPoint(contBB);
2475 Value *(ScalarExprEmitter::*Func)(
const BinOpInfo &)) {
2476 bool Ignore = TestAndClearIgnoreResultAssign();
2478 LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
2493 return EmitLoadOfLValue(LHS, E->
getExprLoc());
2496 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
2497 const BinOpInfo &Ops,
llvm::Value *Zero,
bool isDiv) {
2500 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
2501 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
2502 SanitizerKind::IntegerDivideByZero));
2505 const auto *BO = cast<BinaryOperator>(Ops.E);
2506 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
2507 Ops.Ty->hasSignedIntegerRepresentation() &&
2509 Ops.mayHaveIntegerOverflow()) {
2510 llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
2513 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
2514 llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
2516 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
2517 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
2518 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
2520 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
2523 if (Checks.size() > 0)
2524 EmitBinOpCheck(Checks, Ops);
2527 Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
2530 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
2531 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
2532 Ops.Ty->isIntegerType() &&
2533 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
2534 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2535 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
2536 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
2537 Ops.Ty->isRealFloatingType() &&
2538 Ops.mayHaveFloatDivisionByZero()) {
2539 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2540 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
2541 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
2546 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
2547 llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
2556 if (ValTy->isFloatTy() ||
2557 (isa<llvm::VectorType>(ValTy) &&
2558 cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
2563 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
2564 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
2566 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
2569 Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
2571 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
2572 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
2573 Ops.Ty->isIntegerType() &&
2574 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
2576 llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
2577 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
2580 if (Ops.Ty->hasUnsignedIntegerRepresentation())
2581 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
2583 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
2586 Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
2590 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
2591 switch (Ops.Opcode) {
2595 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
2596 llvm::Intrinsic::uadd_with_overflow;
2601 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
2602 llvm::Intrinsic::usub_with_overflow;
2607 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
2608 llvm::Intrinsic::umul_with_overflow;
2611 llvm_unreachable(
"Unsupported operation for overflow detection");
2622 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
2623 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
2624 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
2627 const std::string *handlerName =
2629 if (handlerName->empty()) {
2632 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
2633 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
2635 : SanitizerKind::UnsignedIntegerOverflow;
2636 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
2643 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
2644 llvm::BasicBlock *continueBB =
2648 Builder.CreateCondBr(overflow, overflowBB, continueBB);
2652 Builder.SetInsertPoint(overflowBB);
2657 llvm::FunctionType *handlerTy =
2658 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
2671 Builder.getInt8(OpID),
2672 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
2678 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
2679 Builder.CreateBr(continueBB);
2681 Builder.SetInsertPoint(continueBB);
2682 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
2683 phi->addIncoming(result, initialBB);
2684 phi->addIncoming(handlerResult, overflowBB);
2691 const BinOpInfo &op,
2692 bool isSubtraction) {
2697 Value *pointer = op.LHS;
2699 Value *index = op.RHS;
2703 if (!isSubtraction && !pointer->getType()->isPointerTy()) {
2704 std::swap(pointer, index);
2705 std::swap(pointerOperand, indexOperand);
2710 unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
2712 auto PtrTy = cast<llvm::PointerType>(pointer->getType());
2735 return CGF.
Builder.CreateIntToPtr(index, pointer->getType());
2737 if (width != DL.getTypeSizeInBits(PtrTy)) {
2740 index = CGF.
Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned,
2746 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
2748 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2761 index = CGF.
Builder.CreateMul(index, objectSize);
2764 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
2779 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
2780 pointer = CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
2782 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
2785 op.E->getExprLoc(),
"add.ptr");
2795 result = CGF.
Builder.CreateGEP(result, index,
"add.ptr");
2800 return CGF.
Builder.CreateGEP(pointer, index,
"add.ptr");
2803 op.E->getExprLoc(),
"add.ptr");
2813 bool negMul,
bool negAdd) {
2814 assert(!(negMul && negAdd) &&
"Only one of negMul and negAdd should be set.");
2816 Value *MulOp0 = MulOp->getOperand(0);
2817 Value *MulOp1 = MulOp->getOperand(1);
2821 llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0,
2823 }
else if (negAdd) {
2826 llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend,
2830 Value *FMulAdd = Builder.CreateCall(
2832 {MulOp0, MulOp1, Addend});
2833 MulOp->eraseFromParent();
2848 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
2849 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
2850 "Only fadd/fsub can be the root of an fmuladd.");
2853 if (!op.FPFeatures.allowFPContractWithinStatement())
2859 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
2860 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
2861 LHSBinOp->use_empty())
2862 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder,
false, isSub);
2864 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
2865 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
2866 RHSBinOp->use_empty())
2867 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub,
false);
2873 Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
2874 if (op.LHS->getType()->isPointerTy() ||
2875 op.RHS->getType()->isPointerTy())
2878 if (op.Ty->isSignedIntegerOrEnumerationType()) {
2879 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2881 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
2883 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2884 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
2887 if (CanElideOverflowCheck(CGF.
getContext(), op))
2888 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
2889 return EmitOverflowCheckedBinOp(op);
2893 if (op.Ty->isUnsignedIntegerType() &&
2894 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
2895 !CanElideOverflowCheck(CGF.
getContext(), op))
2896 return EmitOverflowCheckedBinOp(op);
2898 if (op.LHS->getType()->isFPOrFPVectorTy()) {
2903 Value *V = Builder.CreateFAdd(op.LHS, op.RHS,
"add");
2904 return propagateFMFlags(V, op);
2907 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
2910 Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
2912 if (!op.LHS->getType()->isPointerTy()) {
2913 if (op.Ty->isSignedIntegerOrEnumerationType()) {
2914 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2916 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
2918 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2919 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
2922 if (CanElideOverflowCheck(CGF.
getContext(), op))
2923 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
2924 return EmitOverflowCheckedBinOp(op);
2928 if (op.Ty->isUnsignedIntegerType() &&
2929 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
2930 !CanElideOverflowCheck(CGF.
getContext(), op))
2931 return EmitOverflowCheckedBinOp(op);
2933 if (op.LHS->getType()->isFPOrFPVectorTy()) {
2937 Value *V = Builder.CreateFSub(op.LHS, op.RHS,
"sub");
2938 return propagateFMFlags(V, op);
2941 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
2946 if (!op.RHS->getType()->isPointerTy())
2953 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
2955 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
2956 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
2968 std::tie(numElements, elementType) = CGF.
getVLASize(vla);
2970 divisor = numElements;
2974 if (!eltSize.
isOne())
2984 if (elementType->isVoidType() || elementType->isFunctionType())
2990 if (elementSize.
isOne())
2999 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
3002 Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) {
3003 llvm::IntegerType *Ty;
3004 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
3005 Ty = cast<llvm::IntegerType>(VT->getElementType());
3007 Ty = cast<llvm::IntegerType>(LHS->getType());
3008 return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
3011 Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
3014 Value *RHS = Ops.RHS;
3015 if (Ops.LHS->getType() != RHS->getType())
3016 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3018 bool SanitizeBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
3019 Ops.Ty->hasSignedIntegerRepresentation() &&
3021 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
3025 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shl.mask");
3026 else if ((SanitizeBase || SanitizeExponent) &&
3027 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3030 llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
3031 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
3033 if (SanitizeExponent) {
3035 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
3042 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
3045 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
3047 (RHS == Ops.RHS) ? WidthMinusOne
3048 : GetWidthMinusOneValue(Ops.LHS, RHS);
3051 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
3059 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
3060 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
3062 llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
3063 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
3065 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
3066 BaseCheck->addIncoming(Builder.getTrue(), Orig);
3067 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
3068 Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase));
3071 assert(!Checks.empty());
3072 EmitBinOpCheck(Checks, Ops);
3075 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
3078 Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
3081 Value *RHS = Ops.RHS;
3082 if (Ops.LHS->getType() != RHS->getType())
3083 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
3088 Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS),
"shr.mask");
3089 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
3090 isa<llvm::IntegerType>(Ops.LHS->getType())) {
3093 Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
3094 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
3097 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3098 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
3099 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
3107 default: llvm_unreachable(
"unexpected element type");
3108 case BuiltinType::Char_U:
3109 case BuiltinType::UChar:
3110 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3111 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
3112 case BuiltinType::Char_S:
3113 case BuiltinType::SChar:
3114 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
3115 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
3116 case BuiltinType::UShort:
3117 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3118 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
3119 case BuiltinType::Short:
3120 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
3121 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
3122 case BuiltinType::UInt:
3123 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3124 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
3125 case BuiltinType::Int:
3126 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
3127 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
3128 case BuiltinType::ULong:
3129 case BuiltinType::ULongLong:
3130 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3131 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
3132 case BuiltinType::Long:
3133 case BuiltinType::LongLong:
3134 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
3135 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
3136 case BuiltinType::Float:
3137 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
3138 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
3139 case BuiltinType::Double:
3140 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
3141 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
3146 llvm::CmpInst::Predicate UICmpOpc,
3147 llvm::CmpInst::Predicate SICmpOpc,
3148 llvm::CmpInst::Predicate FCmpOpc) {
3149 TestAndClearIgnoreResultAssign();
3159 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
3161 Value *LHS = Visit(E->
getLHS());
3162 Value *RHS = Visit(E->
getRHS());
3168 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
3173 Value *FirstVecArg = LHS,
3174 *SecondVecArg = RHS;
3181 default: llvm_unreachable(
"is not a comparison operation");
3193 std::swap(FirstVecArg, SecondVecArg);
3200 if (ElementKind == BuiltinType::Float) {
3202 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3203 std::swap(FirstVecArg, SecondVecArg);
3211 if (ElementKind == BuiltinType::Float) {
3213 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
3218 std::swap(FirstVecArg, SecondVecArg);
3223 Value *CR6Param = Builder.getInt32(CR6);
3225 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
3232 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
3233 if (ResultTy->getBitWidth() > 1 &&
3235 Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
3240 if (LHS->getType()->isFPOrFPVectorTy()) {
3241 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
3243 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
3246 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
3252 return Builder.CreateSExt(Result, ConvertType(E->
getType()),
"sext");
3260 CETy = CTy->getElementType();
3262 LHS.first = Visit(E->
getLHS());
3263 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
3269 CTy->getElementType()) &&
3270 "The element types must always match.");
3273 RHS.first = Visit(E->
getRHS());
3274 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
3276 "The element types must always match.");
3279 Value *ResultR, *ResultI;
3281 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
3282 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
3286 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
3287 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
3291 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
3294 "Complex comparison other than == or != ?");
3295 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
3303 Value *ScalarExprEmitter::VisitBinAssign(
const BinaryOperator *E) {
3304 bool Ignore = TestAndClearIgnoreResultAssign();
3323 RHS = Visit(E->
getRHS());
3331 RHS = Visit(E->
getRHS());
3338 if (LHS.isBitField()) {
3359 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3362 Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
3367 Value *LHS = Visit(E->
getLHS());
3368 Value *RHS = Visit(E->
getRHS());
3369 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3370 if (LHS->getType()->isFPOrFPVectorTy()) {
3371 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3372 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3374 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3375 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3377 Value *
And = Builder.CreateAnd(LHS, RHS);
3378 return Builder.CreateSExt(And, ConvertType(E->
getType()),
"sext");
3392 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
3397 return llvm::Constant::getNullValue(ResTy);
3414 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3416 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
3425 RHSBlock = Builder.GetInsertBlock();
3434 PN->addIncoming(RHSCond, RHSBlock);
3437 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
3445 Value *LHS = Visit(E->
getLHS());
3446 Value *RHS = Visit(E->
getRHS());
3447 Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3448 if (LHS->getType()->isFPOrFPVectorTy()) {
3449 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
3450 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
3452 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
3453 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
3455 Value *Or = Builder.CreateOr(LHS, RHS);
3456 return Builder.CreateSExt(Or, ConvertType(E->
getType()),
"sext");
3470 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
3475 return llvm::ConstantInt::get(ResTy, 1);
3493 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3495 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
3507 RHSBlock = Builder.GetInsertBlock();
3512 PN->addIncoming(RHSCond, RHSBlock);
3515 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
3518 Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
3521 return Visit(E->
getRHS());
3546 Value *ScalarExprEmitter::
3548 TestAndClearIgnoreResultAssign();
3561 Expr *live = lhsExpr, *dead = rhsExpr;
3562 if (!CondExprBool) std::swap(live, dead);
3568 Value *Result = Visit(live);
3591 llvm::VectorType *vecTy = cast<llvm::VectorType>(condType);
3593 unsigned numElem = vecTy->getNumElements();
3594 llvm::Type *elemType = vecTy->getElementType();
3596 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
3597 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
3599 llvm::VectorType::get(elemType,
3607 bool wasCast =
false;
3608 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
3609 if (rhsVTy->getElementType()->isFloatingPointTy()) {
3615 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
3616 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
3617 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
3638 assert(!RHS &&
"LHS and RHS types must match");
3641 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
3655 Value *LHS = Visit(lhsExpr);
3658 LHSBlock = Builder.GetInsertBlock();
3659 Builder.CreateBr(ContBlock);
3663 Value *RHS = Visit(rhsExpr);
3666 RHSBlock = Builder.GetInsertBlock();
3676 llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2,
"cond");
3677 PN->addIncoming(LHS, LHSBlock);
3678 PN->addIncoming(RHS, RHSBlock);
3682 Value *ScalarExprEmitter::VisitChooseExpr(
ChooseExpr *E) {
3686 Value *ScalarExprEmitter::VisitVAArgExpr(
VAArgExpr *VE) {
3700 return llvm::UndefValue::get(ArgTy);
3707 if (ArgTy != Val->getType()) {
3708 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
3709 Val = Builder.CreateIntToPtr(Val, ArgTy);
3711 Val = Builder.CreateTrunc(Val, ArgTy);
3717 Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
3723 Value *Src,
unsigned NumElementsDst) {
3724 llvm::Value *UnV = llvm::UndefValue::get(Src->getType());
3726 Args.push_back(Builder.getInt32(0));
3727 Args.push_back(Builder.getInt32(1));
3728 Args.push_back(Builder.getInt32(2));
3729 if (NumElementsDst == 4)
3730 Args.push_back(llvm::UndefValue::get(CGF.
Int32Ty));
3731 llvm::Constant *Mask = llvm::ConstantVector::get(Args);
3732 return Builder.CreateShuffleVector(Src, UnV, Mask);
3752 const llvm::DataLayout &DL,
3754 StringRef Name =
"") {
3755 auto SrcTy = Src->getType();
3758 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
3762 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
3766 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
3768 if (!DstTy->isIntegerTy())
3769 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
3771 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
3775 if (!SrcTy->isIntegerTy())
3778 return Builder.CreateIntToPtr(Src, DstTy, Name);
3781 Value *ScalarExprEmitter::VisitAsTypeExpr(
AsTypeExpr *E) {
3786 unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ?
3787 cast<llvm::VectorType>(SrcTy)->getNumElements() : 0;
3788 unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ?
3789 cast<llvm::VectorType>(DstTy)->getNumElements() : 0;
3793 if (NumElementsSrc == 3 && NumElementsDst != 3) {
3801 Src->setName(
"astype");
3808 if (NumElementsSrc != 3 && NumElementsDst == 3) {
3810 auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4);
3816 Src->setName(
"astype");
3821 Src, DstTy,
"astype");
3824 Value *ScalarExprEmitter::VisitAtomicExpr(
AtomicExpr *E) {
3835 assert(E && hasScalarEvaluationKind(E->
getType()) &&
3836 "Invalid scalar expression to emit");
3838 return ScalarExprEmitter(*
this, IgnoreResultAssign)
3839 .Visit(const_cast<Expr *>(E));
3847 assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
3848 "Invalid scalar expression to emit");
3849 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
3859 "Invalid complex -> scalar conversion");
3860 return ScalarExprEmitter(*
this)
3861 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
3867 bool isInc,
bool isPre) {
3868 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
3878 Addr =
Address(EmitScalarExpr(BaseExpr), getPointerAlign());
3880 Addr = EmitLValue(BaseExpr).getAddress();
3885 return MakeAddrLValue(Addr, E->
getType());
3891 ScalarExprEmitter Scalar(*
this);
3892 Value *Result =
nullptr;
3894 #define COMPOUND_OP(Op) \ 3895 case BO_##Op##Assign: \ 3896 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ 3933 llvm_unreachable(
"Not valid compound assignment operators");
3936 llvm_unreachable(
"Unhandled compound assignment operator");
3944 const Twine &Name) {
3945 Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
3948 if (!SanOpts.has(SanitizerKind::PointerOverflow))
3952 if (isa<llvm::Constant>(GEPVal))
3956 if (GEPVal->getType()->getPointerAddressSpace())
3959 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
3960 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
3963 auto &VMContext = getLLVMContext();
3964 const auto &DL = CGM.getDataLayout();
3965 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
3968 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
3969 auto *SAddIntrinsic =
3970 CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
3971 auto *SMulIntrinsic =
3972 CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
3977 llvm::Value *OffsetOverflows = Builder.getFalse();
3982 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
3985 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
3986 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
3988 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
3991 OffsetOverflows = Builder.getTrue();
3992 return llvm::ConstantInt::get(VMContext, N);
3997 auto *ResultAndOverflow = Builder.CreateCall(
3998 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
3999 OffsetOverflows = Builder.CreateOr(
4000 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
4001 return Builder.CreateExtractValue(ResultAndOverflow, 0);
4005 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
4006 GTI != GTE; ++GTI) {
4008 auto *Index = GTI.getOperand();
4010 if (
auto *STy = GTI.getStructTypeOrNull()) {
4013 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
4014 LocalOffset = llvm::ConstantInt::get(
4015 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
4019 auto *ElementSize = llvm::ConstantInt::get(
4020 IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
4021 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
4022 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
4027 if (!TotalOffset || TotalOffset == Zero)
4028 TotalOffset = LocalOffset;
4030 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
4034 if (TotalOffset == Zero)
4039 auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy);
4040 auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset);
4047 auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
4048 if (SignedIndices) {
4049 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4050 auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
4051 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
4052 ValidGEP = Builder.CreateAnd(
4053 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
4055 }
else if (!SignedIndices && !IsSubtraction) {
4056 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4057 ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
4059 auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
4060 ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
4063 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
4065 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4066 EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow),
4067 SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
const llvm::DataLayout & getDataLayout() const
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Defines the clang::ASTContext interface.
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.
The null pointer literal (C++11 [lex.nullptr])
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
llvm::IntegerType * IntTy
int
void end(CodeGenFunction &CGF)
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc)
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled...
LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const
bool isSignedOverflowDefined() const
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
llvm::Constant * getValue() const
A (possibly-)qualified type.
uint64_t getValue() const
CodeGenTypes & getTypes()
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
static Opcode getOpForCompoundAssignment(Opcode Opc)
Represents a version number in the form major[.minor[.subminor[.build]]].
const CodeGenOptions & getCodeGenOpts() const
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler...
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
CompoundStmt * getSubStmt()
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
const Expr * getInit(unsigned Init) const
static llvm::Constant * getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
bool isRealFloatingType() const
Floating point categories.
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::APFloat getValue() const
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet())
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
bool isExtVectorType() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask >> Checked, SanitizerHandler Check, ArrayRef< llvm::Constant *> StaticArgs, ArrayRef< llvm::Value *> DynamicArgs)
Create a basic block that will call a handler function in a sanitizer runtime with the provided argum...
ParenExpr - This represents a parethesized expression, e.g.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Expr * getFalseExpr() const
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
FPOptions getFPFeatures() const
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
const TargetInfo & getTargetInfo() const
Floating point control options.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
const Expr * getResultExpr() const
The generic selection's result expression.
static Value * buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant, or if it does but contains a label, return false.
QualType getElementType() const
Expr * getIndexExpr(unsigned Idx)
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
CompoundLiteralExpr - [C99 6.5.2.5].
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
const llvm::fltSemantics & getHalfFormat() const
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::Value * getPointer() const
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
A C++ throw-expression (C++ [except.throw]).
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
RecordDecl - Represents a struct/union/class.
const TargetInfo & getTarget() const
An object to manage conditionally-evaluated expressions.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
FieldDecl * getField() const
For a field offsetof node, returns the field.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Address getAddress() const
QualType getComputationResultType() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
llvm::IntegerType * Int64Ty
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
bool isVolatileQualified() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isReferenceType() const
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method...
bool hadArrayRangeDesignator() const
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
const RValue & getOpaqueRValueMapping(const OpaqueValueExpr *e)
getOpaqueRValueMapping - Given an opaque value expression (which must be mapped to an r-value)...
Describes an C or C++ initializer list.
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
APValue Val
Val - This is the value the expression can be folded to.
bool isOne() const
isOne - Test whether the quantity equals one.
path_iterator path_begin()
llvm::PointerType * VoidPtrTy
A builtin binary operation expression such as "x + y" or "x <= y".
Optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
ObjCStringLiteral, used for Objective-C string literals i.e.
static llvm::Constant * getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off, llvm::Type *I32Ty)
Scope - A scope is a transient data structure that is used while parsing the program.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
field_iterator field_begin() const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a best-effort attempt to peephole expressions that naturally produce retained objects.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Helper class for OffsetOfExpr.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
RValue EmitAtomicExpr(AtomicExpr *E)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
QualType getReturnType() const
llvm::Value * EmitBlockLiteral(const BlockExpr *, llvm::Function **InvokeF=nullptr)
Emit block literal.
A default argument (C++ [dcl.fct.default]).
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void begin(CodeGenFunction &CGF)
Checking the operand of a load. Must be suitably sized and aligned.
This object can be modified without requiring retains or releases.
Represents the this expression in C++.
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, Expr *LHS, Expr *RHS)
const Expr * getExpr() const
Get the initialization expression that will be used.
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...
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
VersionTuple getVersion()
Sema - This implements semantic analysis and AST building for C.
bool isPromotableIntegerType() const
More type predicates useful for type checking/promotion.
static CharUnits One()
One - Construct a CharUnits quantity of one.
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ASTContext & getContext() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const TargetCodeGenInfo & getTargetCodeGenInfo()
QualType getComputationLHSType() const
CastKind
CastKind - The kind of operation required for a conversion.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Represents a call to the builtin function __builtin_va_arg.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
const llvm::fltSemantics & getLongDoubleFormat() const
unsigned getValue() const
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
Allow any unmodeled side effect.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const FunctionProtoType * T
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type, where the destination type is an LLVM scalar type.
SourceLocation getExprLoc() const LLVM_READONLY
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that that type refers to...
unsigned getPackLength() const
Retrieve the length of the parameter pack.
const T * castAs() const
Member-template castAs<specific type>.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
unsigned getNumInits() const
bool isNullPtrType() const
void SetFPAccuracy(llvm::Value *Val, float Accuracy)
SetFPAccuracy - Set the minimum required accuracy of the given floating point operation, expressed as the maximum relative error in ulp.
field_iterator field_end() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation...
bool isAnyComplexType() const
ObjCSelectorExpr used for @selector in Objective-C.
TypeSourceInfo * getTypeSourceInfo() const
Represents an expression that computes the length of a parameter pack.
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
llvm::IntegerType * Int32Ty
Kind getKind() const
Determine what kind of offsetof node this is.
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...
An RAII object to record that we're evaluating a statement expression.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
An expression that sends a message to the given Objective-C object or class.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Represents a GCC generic vector type.
bool isNullPointer() const
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
The scope of a CXXDefaultInitExpr.
const OffsetOfNode & getComponent(unsigned Idx) const
const TargetInfo & getTarget() const
Expr * getTrueExpr() const
const Expr * getSubExpr() const
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment, llvm::Value *OffsetValue=nullptr)
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
There is no lifetime qualification on this type.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
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. ...
Assigning into this object requires the old value to be released and the new value to be retained...
A field in a dependent type, known only by its name.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Encodes a location in the source.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go...
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
LangAS getAddressSpace() const
Return the address space of this type.
bool allowFPContractAcrossStatement() const
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
Expr * getSubExpr() const
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
SourceLocation getExprLoc() const LLVM_READONLY
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior...
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation...
CastKind getCastKind() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
QualType getElementType() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SanitizerSet SanOpts
Sanitizers enabled for this function.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, and corresponding __opencl_atomic_* for OpenCL 2.0.
UnaryExprOrTypeTrait getKind() const
ObjCProtocolExpr used for protocol expression in Objective-C.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
An expression trait intrinsic.
const ObjCMethodDecl * getMethodDecl() const
bool isVectorType() const
Assigning into this object requires a lifetime extension.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
ObjCBoxedExpr - used for generalized expression boxing.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
bool isArgumentType() const
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
void enterFullExpression(const ExprWithCleanups *E)
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
CompoundAssignOperator - For compound assignments (e.g.
const llvm::fltSemantics & getFloat128Format() const
Represents a C11 generic selection.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
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.
AddrLabelExpr - The GNU address of label extension, representing &&label.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
SourceLocation getExprLoc() const LLVM_READONLY
Dataflow Directional Tag Classes.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i...
Optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
void EmitVTablePtrCheckForCast(QualType T, llvm::Value *Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
EvalResult is a struct with detailed info about an evaluated expression.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
A runtime availability query.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Represents a 'co_yield' expression.
unsigned getMajor() const
Retrieve the major version number.
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
bool isBooleanType() const
const Expr * getExpr() const
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Checking the destination of a store. Must be suitably sized and aligned.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type *> Tys=None)
A pointer to member type per C++ 8.3.3 - Pointers to members.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
ExplicitCastExpr - An explicit cast written in the source code.
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
llvm::APInt getValue() const
LabelDecl * getLabel() const
#define VISITCOMP(CODE, UI, SI, FP)
Represents a pointer to an Objective C object.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
unsigned getIntWidth(QualType T) const
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
bool HasSideEffects
Whether the evaluated expression has side effects.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
const LValue & getOpaqueLValueMapping(const OpaqueValueExpr *e)
getOpaqueLValueMapping - Given an opaque value expression (which must be mapped to an l-value)...
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Checking the operand of a static_cast to a derived pointer type.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
An implicit indirection through a C++ base class, when the field found is in a base class...
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool isFunctionType() const
llvm::Value * EmitCheckedInBoundsGEP(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...
Represents a 'co_await' expression.
Expr * getReplacement() const
ExtVectorType - Extended vector type.
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
SourceLocation getExprLoc() const LLVM_READONLY
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type, returning the result.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet...
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Represents a C++ struct/union/class.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
llvm::Type * ConvertType(QualType T)
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
void EmitTrapCheck(llvm::Value *Checked)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it...
This class is used for builtin types like 'int'.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
std::pair< llvm::Value *, QualType > getVLASize(const VariableArrayType *vla)
getVLASize - Returns an LLVM value that corresponds to the size, in non-variably-sized elements...
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
RetTy Visit(PTR(Stmt) S, ParamTys... P)
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...
CGCXXABI & getCXXABI() const
const VariableArrayType * getAsVariableArrayType(QualType T) const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
unsigned getNumComponents() const
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...
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
bool isFloatingType() const
LValue - This represents an lvalue references.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
A boolean literal, per ([C++ lex.bool] Boolean literals).
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
Represents a C array with a specified size that is not an integer-constant-expression.
const LangOptions & getLangOpts() const
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
SourceLocation getLocStart() const LLVM_READONLY
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
const LangOptions & getLangOpts() const
llvm::Value * getPointer() const
Represents an implicitly-generated value initialization of an object of a given type.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
QualType getType() const
Return the type wrapped by this type source info.
llvm::Value * EmitBuiltinAvailable(ArrayRef< llvm::Value *> Args)
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
bool isCompoundAssignmentOp() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
QualType getType() const
Retrieves the type of the base class.