35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/IR/Argument.h"
37#include "llvm/IR/CFG.h"
38#include "llvm/IR/Constants.h"
39#include "llvm/IR/DataLayout.h"
40#include "llvm/IR/DerivedTypes.h"
41#include "llvm/IR/FixedPointBuilder.h"
42#include "llvm/IR/Function.h"
43#include "llvm/IR/GEPNoWrapFlags.h"
44#include "llvm/IR/GetElementPtrTypeIterator.h"
45#include "llvm/IR/GlobalVariable.h"
46#include "llvm/IR/Intrinsics.h"
47#include "llvm/IR/IntrinsicsPowerPC.h"
48#include "llvm/IR/MatrixBuilder.h"
49#include "llvm/IR/Module.h"
50#include "llvm/Support/TypeSize.h"
55using namespace CodeGen;
73bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
75 llvm::APInt &Result) {
78 const auto &LHSAP = LHS->getValue();
79 const auto &RHSAP = RHS->getValue();
80 if (Opcode == BO_Add) {
81 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
82 : LHSAP.uadd_ov(RHSAP, Overflow);
83 }
else if (Opcode == BO_Sub) {
84 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
85 : LHSAP.usub_ov(RHSAP, Overflow);
86 }
else if (Opcode == BO_Mul) {
87 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
88 : LHSAP.umul_ov(RHSAP, Overflow);
89 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
90 if (
Signed && !RHS->isZero())
91 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
107 bool mayHaveIntegerOverflow()
const {
109 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
110 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
111 if (!LHSCI || !RHSCI)
115 return ::mayHaveIntegerOverflow(
120 bool isDivremOp()
const {
126 bool mayHaveIntegerDivisionByZero()
const {
128 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
134 bool mayHaveFloatDivisionByZero()
const {
136 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
137 return CFP->isZero();
144 bool isFixedPointOp()
const {
147 if (
const auto *BinOp = dyn_cast<BinaryOperator>(
E)) {
148 QualType LHSType = BinOp->getLHS()->getType();
149 QualType RHSType = BinOp->getRHS()->getType();
152 if (
const auto *UnOp = dyn_cast<UnaryOperator>(
E))
153 return UnOp->getSubExpr()->getType()->isFixedPointType();
158 bool rhsHasSignedIntegerRepresentation()
const {
159 if (
const auto *BinOp = dyn_cast<BinaryOperator>(
E)) {
160 QualType RHSType = BinOp->getRHS()->getType();
167static bool MustVisitNullValue(
const Expr *
E) {
195static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
196 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
197 "Expected a unary or binary operator");
201 if (!Op.mayHaveIntegerOverflow())
204 if (Op.Ty->isSignedIntegerType() &&
210 if (Op.Ty->isUnsignedIntegerType() &&
220 LangOptions::OverflowPatternExclusionKind::NegUnsignedConst) &&
230 const auto *BO = cast<BinaryOperator>(Op.E);
231 if (BO->hasExcludedOverflowPattern())
247 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
253 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
254 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
258class ScalarExprEmitter
262 bool IgnoreResultAssign;
263 llvm::LLVMContext &VMContext;
267 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
268 VMContext(cgf.getLLVMContext()) {
275 bool TestAndClearIgnoreResultAssign() {
276 bool I = IgnoreResultAssign;
277 IgnoreResultAssign =
false;
288 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
289 const BinOpInfo &Info);
295 void EmitLValueAlignmentAssumption(
const Expr *
E,
Value *
V) {
296 const AlignValueAttr *AVAttr =
nullptr;
297 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
301 if (
const auto *TTy =
303 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
310 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
313 AVAttr = VD->
getAttr<AlignValueAttr>();
319 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
325 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
336 EmitLValueAlignmentAssumption(
E,
V);
346 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
353 enum ImplicitConversionCheckKind :
unsigned char {
354 ICCK_IntegerTruncation = 0,
355 ICCK_UnsignedIntegerTruncation = 1,
356 ICCK_SignedIntegerTruncation = 2,
357 ICCK_IntegerSignChange = 3,
358 ICCK_SignedIntegerTruncationOrSignChange = 4,
374 struct ScalarConversionOpts {
375 bool TreatBooleanAsSigned;
376 bool EmitImplicitIntegerTruncationChecks;
377 bool EmitImplicitIntegerSignChangeChecks;
379 ScalarConversionOpts()
380 : TreatBooleanAsSigned(
false),
381 EmitImplicitIntegerTruncationChecks(
false),
382 EmitImplicitIntegerSignChangeChecks(
false) {}
385 : TreatBooleanAsSigned(
false),
386 EmitImplicitIntegerTruncationChecks(
388 EmitImplicitIntegerSignChangeChecks(
392 llvm::Type *SrcTy, llvm::Type *DstTy,
393 ScalarConversionOpts Opts);
397 ScalarConversionOpts Opts = ScalarConversionOpts());
416 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
417 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
424 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
431 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
432 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
433 Value *Result = ZI->getOperand(0);
438 ZI->eraseFromParent();
443 return Builder.CreateIsNotNull(
V,
"tobool");
457 llvm_unreachable(
"Stmt can't have complex result type!");
475 return Visit(
E->getSubExpr());
481 return Visit(
E->getReplacement());
484 return Visit(
GE->getResultExpr());
493 return Visit(
E->getSubExpr());
498 return Builder.getInt(
E->getValue());
501 return Builder.getInt(
E->getValue());
504 return llvm::ConstantFP::get(VMContext,
E->getValue());
507 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
510 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
513 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
528 return Builder.CreateBitCast(
V, ConvertType(
E->
getType()));
532 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getPackLength());
552 llvm_unreachable(
"Codegen for this isn't defined/implemented");
559 return EmitLoadOfLValue(
E);
569 return EmitLoadOfLValue(
E);
572 if (
E->getMethodDecl() &&
573 E->getMethodDecl()->getReturnType()->isReferenceType())
574 return EmitLoadOfLValue(
E);
585 VersionTuple Version =
E->getVersion();
590 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
600 Value *VisitExtVectorElementExpr(
Expr *
E) {
return EmitLoadOfLValue(
E); }
607 return EmitLoadOfLValue(
E);
614 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
623 return VisitCastExpr(
E);
628 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
629 return EmitLoadOfLValue(
E);
633 EmitLValueAlignmentAssumption(
E,
V);
641 LValue LV = EmitLValue(
E->getSubExpr());
642 return EmitScalarPrePostIncDec(
E, LV,
false,
false);
645 LValue LV = EmitLValue(
E->getSubExpr());
646 return EmitScalarPrePostIncDec(
E, LV,
true,
false);
649 LValue LV = EmitLValue(
E->getSubExpr());
650 return EmitScalarPrePostIncDec(
E, LV,
false,
true);
653 LValue LV = EmitLValue(
E->getSubExpr());
654 return EmitScalarPrePostIncDec(
E, LV,
true,
true);
657 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *
E,
662 bool isInc,
bool isPre);
666 if (isa<MemberPointerType>(
E->
getType()))
669 return EmitLValue(
E->getSubExpr()).getPointer(CGF);
673 return Visit(
E->getSubExpr());
674 return EmitLoadOfLValue(
E);
693 return Visit(
E->getSubExpr());
698 return EmitLoadOfLValue(
E);
730 if (
E->isStoredAsBoolean())
731 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
733 assert(
E->getAPValue().isInt() &&
"APValue type not supported");
734 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
735 E->getAPValue().getInt());
739 return Builder.getInt1(
E->isSatisfied());
743 return Builder.getInt1(
E->isSatisfied());
747 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
751 return llvm::ConstantInt::get(Builder.getInt1Ty(),
E->getValue());
774 return Builder.getInt1(
E->getValue());
778 Value *EmitMul(
const BinOpInfo &Ops) {
779 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
780 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
782 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
783 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
786 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
787 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
790 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
791 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
792 return EmitOverflowCheckedBinOp(Ops);
796 if (Ops.Ty->isConstantMatrixType()) {
797 llvm::MatrixBuilder MB(Builder);
800 auto *BO = cast<BinaryOperator>(Ops.E);
801 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
802 BO->getLHS()->getType().getCanonicalType());
803 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
804 BO->getRHS()->getType().getCanonicalType());
806 if (LHSMatTy && RHSMatTy)
807 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
808 LHSMatTy->getNumColumns(),
809 RHSMatTy->getNumColumns());
810 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
813 if (Ops.Ty->isUnsignedIntegerType() &&
814 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
815 !CanElideOverflowCheck(CGF.
getContext(), Ops))
816 return EmitOverflowCheckedBinOp(Ops);
818 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
821 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
823 if (Ops.isFixedPointOp())
824 return EmitFixedPointBinOp(Ops);
825 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
829 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
832 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
833 llvm::Value *
Zero,
bool isDiv);
835 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
841 Value *EmitDiv(
const BinOpInfo &Ops);
842 Value *EmitRem(
const BinOpInfo &Ops);
843 Value *EmitAdd(
const BinOpInfo &Ops);
844 Value *EmitSub(
const BinOpInfo &Ops);
845 Value *EmitShl(
const BinOpInfo &Ops);
846 Value *EmitShr(
const BinOpInfo &Ops);
847 Value *EmitAnd(
const BinOpInfo &Ops) {
848 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
850 Value *EmitXor(
const BinOpInfo &Ops) {
851 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
853 Value *EmitOr (
const BinOpInfo &Ops) {
854 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
858 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
868 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
872 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
877 QualType ElementType = CT->getElementType();
884 unsigned NumElements = VT->getNumElements();
894#define HANDLEBINOP(OP) \
895 Value *VisitBin##OP(const BinaryOperator *E) { \
896 QualType promotionTy = getPromotionType(E->getType()); \
897 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
898 if (result && !promotionTy.isNull()) \
899 result = EmitUnPromotedValue(result, E->getType()); \
902 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
903 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
904 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
920 llvm::CmpInst::Predicate SICmpOpc,
921 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
922#define VISITCOMP(CODE, UI, SI, FP, SIG) \
923 Value *VisitBin##CODE(const BinaryOperator *E) { \
924 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
925 llvm::FCmpInst::FP, SIG); }
940 Value *VisitBinPtrMemD(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
941 Value *VisitBinPtrMemI(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
944 return Visit(
E->getSemanticForm());
967 return Visit(
E->getSelectedExpr());
979 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
982 return EmitFloatToBoolConversion(Src);
988 "Unknown scalar type to convert");
990 if (isa<llvm::IntegerType>(Src->
getType()))
991 return EmitIntToBoolConversion(Src);
993 assert(isa<llvm::PointerType>(Src->
getType()));
994 return EmitPointerToBoolConversion(Src, SrcType);
997void ScalarExprEmitter::EmitFloatConversionCheck(
1000 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1001 if (!isa<llvm::IntegerType>(DstTy))
1004 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1005 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1007 using llvm::APFloat;
1010 llvm::Value *Check =
nullptr;
1011 const llvm::fltSemantics &SrcSema =
1021 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1022 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1023 APFloat::opOverflow)
1026 MinSrc = APFloat::getInf(SrcSema,
true);
1030 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1033 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1034 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1035 APFloat::opOverflow)
1038 MaxSrc = APFloat::getInf(SrcSema,
false);
1042 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1047 const llvm::fltSemantics &
Sema =
1050 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1051 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1055 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1057 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1058 Check = Builder.CreateAnd(GE, LE);
1063 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1069static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1070 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1073 llvm::Type *SrcTy = Src->
getType();
1074 llvm::Type *DstTy = Dst->
getType();
1079 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1080 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1081 "non-integer llvm type");
1088 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1090 if (!SrcSigned && !DstSigned) {
1091 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1092 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1094 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1095 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1098 llvm::Value *Check =
nullptr;
1100 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1102 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1104 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1112void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1124 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1125 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1127 if (SrcBits <= DstBits)
1130 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1137 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1138 (!SrcSigned && DstSigned))
1141 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1142 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1145 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1152 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1153 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1171 llvm::Constant *StaticArgs[] = {
1174 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1175 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1177 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1184 llvm::Type *VTy =
V->getType();
1187 return llvm::ConstantInt::getFalse(VTy->getContext());
1189 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1190 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1191 llvm::Twine(Name) +
"." +
V->getName() +
1192 ".negativitycheck");
1197static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1198 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1201 llvm::Type *SrcTy = Src->
getType();
1202 llvm::Type *DstTy = Dst->
getType();
1204 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1205 "non-integer llvm type");
1211 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1212 unsigned DstBits = DstTy->getScalarSizeInBits();
1216 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1217 "either the widths should be different, or the signednesses.");
1220 llvm::Value *SrcIsNegative =
1223 llvm::Value *DstIsNegative =
1229 llvm::Value *Check =
nullptr;
1230 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1232 return std::make_pair(
1233 ScalarExprEmitter::ICCK_IntegerSignChange,
1234 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1237void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1240 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1243 llvm::Type *SrcTy = Src->
getType();
1244 llvm::Type *DstTy = Dst->
getType();
1254 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1255 unsigned DstBits = DstTy->getScalarSizeInBits();
1262 if (SrcSigned == DstSigned && SrcBits == DstBits)
1266 if (!SrcSigned && !DstSigned)
1271 if ((DstBits > SrcBits) && DstSigned)
1273 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1274 (SrcBits > DstBits) && SrcSigned) {
1283 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1287 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1291 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1294 {SanitizerKind::SO_ImplicitIntegerSignChange,
1295 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1296 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1299 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1300 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1304 ImplicitConversionCheckKind CheckKind;
1312 CheckKind = Check.first;
1313 Checks.emplace_back(Check.second);
1315 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1316 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1322 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1323 Checks.emplace_back(Check.second);
1327 llvm::Constant *StaticArgs[] = {
1330 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1331 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1333 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1338static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1339 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1345 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1346 if (!SrcSigned && !DstSigned)
1347 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1349 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1351 llvm::Value *Check =
nullptr;
1353 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1355 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1358 return std::make_pair(
1360 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1365static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1366 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1370 llvm::Value *SrcIsNegative =
1373 llvm::Value *DstIsNegative =
1379 llvm::Value *Check =
nullptr;
1381 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1383 return std::make_pair(
1384 ScalarExprEmitter::ICCK_IntegerSignChange,
1385 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1393 if (!
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion))
1406 assert(isa<llvm::IntegerType>(Src->
getType()) &&
1407 isa<llvm::IntegerType>(Dst->
getType()) &&
"non-integer llvm type");
1411 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1412 unsigned DstBits = Info.
Size;
1417 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1419 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1421 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1422 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1426 bool EmitTruncation = DstBits < SrcBits;
1430 bool EmitTruncationFromUnsignedToSigned =
1431 EmitTruncation && DstSigned && !SrcSigned;
1433 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1434 bool BothUnsigned = !SrcSigned && !DstSigned;
1435 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1442 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1447 else if (EmitSignChange) {
1448 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1449 "either the widths should be different, or the signednesses.");
1455 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1456 if (EmitTruncationFromUnsignedToSigned)
1457 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1459 llvm::Constant *StaticArgs[] = {
1462 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1463 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1465 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1469 QualType DstType, llvm::Type *SrcTy,
1471 ScalarConversionOpts Opts) {
1473 llvm::Type *SrcElementTy;
1474 llvm::Type *DstElementTy;
1478 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1479 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1484 "cannot cast between matrix and non-matrix types");
1485 SrcElementTy = SrcTy;
1486 DstElementTy = DstTy;
1487 SrcElementType = SrcType;
1488 DstElementType = DstType;
1491 if (isa<llvm::IntegerType>(SrcElementTy)) {
1493 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1497 if (isa<llvm::IntegerType>(DstElementTy))
1498 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1500 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1501 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1504 if (isa<llvm::IntegerType>(DstElementTy)) {
1505 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1512 llvm::Intrinsic::ID IID =
1513 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1514 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1518 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1519 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1522 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1523 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1524 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1526 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1527 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1528 return Builder.CreateFPExt(Src, DstTy,
"conv");
1536 ScalarConversionOpts Opts) {
1551 return Builder.CreateIsNotNull(Src,
"tobool");
1554 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1557 "Unhandled scalar conversion from a fixed point type to another type.");
1561 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1564 "Unhandled scalar conversion to a fixed point type from another type.");
1567 QualType NoncanonicalSrcType = SrcType;
1568 QualType NoncanonicalDstType = DstType;
1572 if (SrcType == DstType)
return Src;
1576 llvm::Value *OrigSrc = Src;
1578 llvm::Type *SrcTy = Src->
getType();
1582 return EmitConversionToBool(Src, SrcType);
1584 llvm::Type *DstTy = ConvertType(DstType);
1589 if (DstTy->isFloatingPointTy()) {
1591 return Builder.CreateCall(
1599 Src = Builder.CreateCall(
1604 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1612 if (SrcTy == DstTy) {
1613 if (Opts.EmitImplicitIntegerSignChangeChecks)
1614 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1615 NoncanonicalDstType,
Loc);
1623 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1625 if (isa<llvm::PointerType>(SrcTy))
1628 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1633 llvm::Value* IntResult =
1634 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1636 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1639 if (isa<llvm::PointerType>(SrcTy)) {
1641 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1642 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1651 "Splatted expr doesn't match with vector element type?");
1654 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1655 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1659 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1661 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1663 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1664 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1665 if (SrcSize == DstSize)
1666 return Builder.CreateBitCast(Src, DstTy,
"conv");
1675 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1676 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1679 assert(((SrcElementTy->isIntegerTy() &&
1680 DstElementTy->isIntegerTy()) ||
1681 (SrcElementTy->isFloatingPointTy() &&
1682 DstElementTy->isFloatingPointTy())) &&
1683 "unexpected conversion between a floating-point vector and an "
1687 if (SrcElementTy->isIntegerTy())
1688 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1691 if (SrcSize > DstSize)
1692 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1695 return Builder.CreateFPExt(Src, DstTy,
"conv");
1699 Value *Res =
nullptr;
1700 llvm::Type *ResTy = DstTy;
1707 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1709 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1715 if (SrcTy->isFloatingPointTy()) {
1719 return Builder.CreateCall(
1722 return Builder.CreateFPTrunc(Src, DstTy);
1727 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1729 if (DstTy != ResTy) {
1731 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1732 Res = Builder.CreateCall(
1736 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1740 if (Opts.EmitImplicitIntegerTruncationChecks)
1741 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1742 NoncanonicalDstType,
Loc);
1744 if (Opts.EmitImplicitIntegerSignChangeChecks)
1745 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1746 NoncanonicalDstType,
Loc);
1754 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1757 Result = FPBuilder.CreateFloatingToFixed(Src,
1760 Result = FPBuilder.CreateFixedToFloating(Src,
1762 ConvertType(DstTy));
1768 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1769 DstFPSema.getWidth(),
1770 DstFPSema.isSigned());
1772 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1775 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1782Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1791 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1792 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy,
Loc);
1793 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1800 return EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1811void ScalarExprEmitter::EmitBinOpCheck(
1812 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1813 const BinOpInfo &Info) {
1826 if (UO && UO->
getOpcode() == UO_Minus) {
1827 Check = SanitizerHandler::NegateOverflow;
1829 DynamicData.push_back(Info.RHS);
1833 Check = SanitizerHandler::ShiftOutOfBounds;
1835 StaticData.push_back(
1837 StaticData.push_back(
1839 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1841 Check = SanitizerHandler::DivremOverflow;
1845 int ArithOverflowKind = 0;
1848 Check = SanitizerHandler::AddOverflow;
1849 ArithOverflowKind = diag::UBSanArithKind::Add;
1853 Check = SanitizerHandler::SubOverflow;
1854 ArithOverflowKind = diag::UBSanArithKind::Sub;
1858 Check = SanitizerHandler::MulOverflow;
1859 ArithOverflowKind = diag::UBSanArithKind::Mul;
1863 llvm_unreachable(
"unexpected opcode for bin op check");
1867 SanitizerKind::UnsignedIntegerOverflow) ||
1869 SanitizerKind::SignedIntegerOverflow)) {
1873 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1877 DynamicData.push_back(Info.LHS);
1878 DynamicData.push_back(Info.RHS);
1881 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1888Value *ScalarExprEmitter::VisitExpr(
Expr *
E) {
1898 unsigned AddrSpace =
1900 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1901 E->ComputeName(Context),
"__usn_str", AddrSpace);
1903 llvm::Type *ExprTy = ConvertType(
E->
getType());
1904 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1909 assert(
E->getDataElementCount() == 1);
1910 auto It =
E->begin();
1911 return Builder.getInt((*It)->getValue());
1916 if (
E->getNumSubExprs() == 2) {
1921 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1922 unsigned LHSElts = LTy->getNumElements();
1926 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1930 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1931 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1939 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1940 MTy->getNumElements());
1941 Value* NewV = llvm::PoisonValue::get(RTy);
1942 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1943 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1944 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1946 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1947 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1956 for (
unsigned i = 2; i <
E->getNumSubExprs(); ++i) {
1957 llvm::APSInt Idx =
E->getShuffleMaskIdx(i - 2);
1959 if (Idx.isSigned() && Idx.isAllOnes())
1960 Indices.push_back(-1);
1962 Indices.push_back(Idx.getZExtValue());
1965 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1976 if (SrcType == DstType)
return Src;
1979 "ConvertVector source type must be a vector");
1981 "ConvertVector destination type must be a vector");
1983 llvm::Type *SrcTy = Src->
getType();
1984 llvm::Type *DstTy = ConvertType(DstType);
1993 assert(SrcTy->isVectorTy() &&
1994 "ConvertVector source IR type must be a vector");
1995 assert(DstTy->isVectorTy() &&
1996 "ConvertVector destination IR type must be a vector");
1998 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1999 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
2001 if (DstEltType->isBooleanType()) {
2002 assert((SrcEltTy->isFloatingPointTy() ||
2003 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
2005 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2006 if (SrcEltTy->isFloatingPointTy()) {
2008 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2010 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2015 Value *Res =
nullptr;
2017 if (isa<llvm::IntegerType>(SrcEltTy)) {
2019 if (isa<llvm::IntegerType>(DstEltTy))
2020 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2024 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2026 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2028 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
2029 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2031 if (DstEltType->isSignedIntegerOrEnumerationType())
2032 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2034 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2036 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2037 "Unknown real conversion");
2039 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2040 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2042 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2057 return Builder.getInt(
Value);
2061 llvm::Value *
Result = EmitLoadOfLValue(
E);
2067 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2068 if (llvm::GetElementPtrInst *GEP =
2069 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2070 if (llvm::Instruction *
Pointer =
2071 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2084 TestAndClearIgnoreResultAssign();
2092 return EmitLoadOfLValue(
E);
2097 Value *Idx = Visit(
E->getIdx());
2100 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2103 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
2107 TestAndClearIgnoreResultAssign();
2116 llvm::MatrixBuilder MB(Builder);
2117 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2119 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2121 Value *Matrix = Visit(
E->getBase());
2124 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2129 int MV = SVI->getMaskValue(Idx);
2136 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2137 "Index operand too large for shufflevector mask!");
2138 return C->getZExtValue();
2142 bool Ignore = TestAndClearIgnoreResultAssign();
2144 unsigned NumInitElements =
E->getNumInits();
2145 assert(Ignore ==
false ||
2147 "init list ignored");
2161 if (
E->hadArrayRangeDesignator())
2164 llvm::VectorType *VType =
2165 dyn_cast<llvm::VectorType>(ConvertType(
E->
getType()));
2168 if (NumInitElements == 0) {
2170 return EmitNullValue(
E->
getType());
2173 return Visit(
E->getInit(0));
2176 if (isa<llvm::ScalableVectorType>(VType)) {
2177 if (NumInitElements == 0) {
2179 return EmitNullValue(
E->
getType());
2182 if (NumInitElements == 1) {
2183 Expr *InitVector =
E->getInit(0);
2188 return Visit(InitVector);
2191 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2194 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
2201 unsigned CurIdx = 0;
2202 bool VIsPoisonShuffle =
false;
2203 llvm::Value *
V = llvm::PoisonValue::get(VType);
2204 for (
unsigned i = 0; i != NumInitElements; ++i) {
2205 Expr *IE =
E->getInit(i);
2209 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2215 if (isa<ExtVectorElementExpr>(IE)) {
2216 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
2218 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2219 ->getNumElements() == ResElts) {
2220 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
2221 Value *LHS =
nullptr, *RHS =
nullptr;
2226 Args.resize(ResElts, -1);
2228 LHS = EI->getVectorOperand();
2230 VIsPoisonShuffle =
true;
2231 }
else if (VIsPoisonShuffle) {
2233 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
2234 for (
unsigned j = 0; j != CurIdx; ++j)
2236 Args.push_back(ResElts +
C->getZExtValue());
2237 Args.resize(ResElts, -1);
2239 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2240 RHS = EI->getVectorOperand();
2241 VIsPoisonShuffle =
false;
2243 if (!Args.empty()) {
2244 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2250 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2252 VIsPoisonShuffle =
false;
2257 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
2262 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2263 if (isa<ExtVectorElementExpr>(IE)) {
2264 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
2265 Value *SVOp = SVI->getOperand(0);
2266 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
2268 if (OpTy->getNumElements() == ResElts) {
2269 for (
unsigned j = 0; j != CurIdx; ++j) {
2272 if (VIsPoisonShuffle) {
2273 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
2278 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2280 Args.resize(ResElts, -1);
2282 if (VIsPoisonShuffle)
2283 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2292 for (
unsigned j = 0; j != InitElts; ++j)
2294 Args.resize(ResElts, -1);
2295 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2298 for (
unsigned j = 0; j != CurIdx; ++j)
2300 for (
unsigned j = 0; j != InitElts; ++j)
2301 Args.push_back(j + Offset);
2302 Args.resize(ResElts, -1);
2309 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2310 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2316 llvm::Type *EltTy = VType->getElementType();
2319 for (; CurIdx < ResElts; ++CurIdx) {
2320 Value *Idx = Builder.getInt32(CurIdx);
2321 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2322 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2328 return !
D->isWeak();
2334 if (
const auto *UO = dyn_cast<UnaryOperator>(
E))
2338 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E))
2341 if (
const auto *ME = dyn_cast<MemberExpr>(
E)) {
2342 if (isa<FieldDecl>(ME->getMemberDecl()))
2357 if (isa<CXXThisExpr>(
E))
2360 if (
const auto *UO = dyn_cast<UnaryOperator>(
E))
2364 if (
const auto *CE = dyn_cast<CastExpr>(
E))
2365 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2366 CE->getCastKind() == CK_ArrayToPointerDecay)
2377 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2387 if (ICE->isGLValue())
2404 assert(SrcTypes.size() >= VecTy->getNumElements() &&
2405 "Flattened type on RHS must have more elements than vector on LHS.");
2409 for (
unsigned I = 0,
E = VecTy->getNumElements(); I <
E; I++) {
2411 llvm::Value *Idx = LoadGEPList[I].second;
2412 Load = Idx ? CGF.
Builder.CreateExtractElement(Load, Idx,
"vec.extract")
2415 Load, SrcTypes[I], VecTy->getElementType(),
Loc);
2416 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2422 "Destination type must be a vector or builtin type.");
2424 llvm::Value *Idx = LoadGEPList[0].second;
2426 Idx ? CGF.
Builder.CreateExtractElement(Load, Idx,
"vec.extract") : Load;
2441 bool Ignored = TestAndClearIgnoreResultAssign();
2447 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2448 case CK_BuiltinFnToFnPtr:
2449 llvm_unreachable(
"builtin functions are handled elsewhere");
2451 case CK_LValueBitCast:
2452 case CK_ObjCObjectLValueCast: {
2456 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2459 case CK_LValueToRValueBitCast: {
2465 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2468 case CK_CPointerToObjCPointerCast:
2469 case CK_BlockPointerToObjCPointerCast:
2470 case CK_AnyPointerToBlockPointerCast:
2473 llvm::Type *SrcTy = Src->
getType();
2474 llvm::Type *DstTy = ConvertType(DestTy);
2485 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2490 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2491 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2492 "Address-space cast must be used to convert address spaces");
2494 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2497 PT->getPointeeType(),
2513 Src = Builder.CreateLaunderInvariantGroup(Src);
2521 Src = Builder.CreateStripInvariantGroup(Src);
2526 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2527 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2528 !isa<CastExpr>(
E)) {
2530 if (!PointeeType.
isNull())
2539 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2540 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2543 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2544 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2545 ScalableDstTy = llvm::ScalableVectorType::get(
2546 FixedSrcTy->getElementType(),
2548 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2550 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2551 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2552 llvm::Value *
Result = Builder.CreateInsertVector(
2553 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2554 ScalableDstTy = cast<llvm::ScalableVectorType>(
2555 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2556 if (
Result->getType() != ScalableDstTy)
2558 if (
Result->getType() != DstTy)
2568 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2569 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2572 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2573 FixedDstTy->getElementType()->isIntegerTy(8)) {
2574 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2575 ScalableSrcTy = llvm::ScalableVectorType::get(
2576 ScalableSrcTy->getElementType(),
2578 ScalableSrcTy->getElementCount().getKnownMinValue()));
2579 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2580 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2584 ScalableSrcTy = llvm::ScalableVectorType::get(
2585 FixedDstTy->getElementType(),
2586 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2587 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2589 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2590 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2601 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2602 isa<llvm::ScalableVectorType>(DstTy)) ||
2603 (isa<llvm::ScalableVectorType>(SrcTy) &&
2604 isa<llvm::FixedVectorType>(DstTy))) {
2611 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2614 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2617 case CK_AddressSpaceConversion: {
2620 Result.Val.isNullPointer()) {
2624 if (
Result.HasSideEffects)
2627 ConvertType(DestTy)), DestTy);
2633 ConvertType(DestTy));
2635 case CK_AtomicToNonAtomic:
2636 case CK_NonAtomicToAtomic:
2637 case CK_UserDefinedConversion:
2644 case CK_BaseToDerived: {
2646 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2660 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2668 case CK_UncheckedDerivedToBase:
2669 case CK_DerivedToBase: {
2682 case CK_ArrayToPointerDecay:
2685 case CK_FunctionToPointerDecay:
2686 return EmitLValue(
E).getPointer(CGF);
2688 case CK_NullToPointer:
2689 if (MustVisitNullValue(
E))
2695 case CK_NullToMemberPointer: {
2696 if (MustVisitNullValue(
E))
2703 case CK_ReinterpretMemberPointer:
2704 case CK_BaseToDerivedMemberPointer:
2705 case CK_DerivedToBaseMemberPointer: {
2717 case CK_ARCProduceObject:
2719 case CK_ARCConsumeObject:
2721 case CK_ARCReclaimReturnedObject:
2723 case CK_ARCExtendBlockObject:
2726 case CK_CopyAndAutoreleaseBlockObject:
2729 case CK_FloatingRealToComplex:
2730 case CK_FloatingComplexCast:
2731 case CK_IntegralRealToComplex:
2732 case CK_IntegralComplexCast:
2733 case CK_IntegralComplexToFloatingComplex:
2734 case CK_FloatingComplexToIntegralComplex:
2735 case CK_ConstructorConversion:
2737 case CK_HLSLArrayRValue:
2738 llvm_unreachable(
"scalar cast to non-scalar value");
2740 case CK_LValueToRValue:
2742 assert(
E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2745 case CK_IntegralToPointer: {
2750 auto DestLLVMTy = ConvertType(DestTy);
2753 llvm::Value* IntResult =
2754 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2756 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2762 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2768 case CK_PointerToIntegral: {
2769 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2770 auto *PtrExpr = Visit(
E);
2778 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2782 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2788 case CK_MatrixCast: {
2789 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2796 case CK_HLSLAggregateSplatCast:
2797 case CK_VectorSplat: {
2798 llvm::Type *DstTy = ConvertType(DestTy);
2801 llvm::ElementCount NumElements =
2802 cast<llvm::VectorType>(DstTy)->getElementCount();
2803 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2806 case CK_FixedPointCast:
2807 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2810 case CK_FixedPointToBoolean:
2812 "Expected src type to be fixed point type");
2813 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2814 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2817 case CK_FixedPointToIntegral:
2819 "Expected src type to be fixed point type");
2820 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2821 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2824 case CK_IntegralToFixedPoint:
2826 "Expected src type to be an integer");
2828 "Expected dest type to be fixed point type");
2829 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2832 case CK_IntegralCast: {
2835 return Builder.CreateIntCast(Visit(
E), ConvertType(DestTy),
2839 ScalarConversionOpts Opts;
2840 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2841 if (!ICE->isPartOfExplicitCast())
2842 Opts = ScalarConversionOpts(CGF.
SanOpts);
2844 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2847 case CK_IntegralToFloating: {
2852 return Builder.CreateSIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2853 return Builder.CreateUIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2856 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2859 case CK_FloatingToIntegral: {
2864 return Builder.CreateFPToSI(Visit(
E), ConvertType(DestTy),
"conv");
2865 return Builder.CreateFPToUI(Visit(
E), ConvertType(DestTy),
"conv");
2868 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2871 case CK_FloatingCast: {
2878 return Builder.CreateFPTrunc(Visit(
E), ConvertType(DestTy),
"conv");
2879 return Builder.CreateFPExt(Visit(
E), ConvertType(DestTy),
"conv");
2882 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2885 case CK_FixedPointToFloating:
2886 case CK_FloatingToFixedPoint: {
2888 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2891 case CK_BooleanToSignedIntegral: {
2892 ScalarConversionOpts Opts;
2893 Opts.TreatBooleanAsSigned =
true;
2894 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2897 case CK_IntegralToBoolean:
2898 return EmitIntToBoolConversion(Visit(
E));
2899 case CK_PointerToBoolean:
2900 return EmitPointerToBoolConversion(Visit(
E),
E->
getType());
2901 case CK_FloatingToBoolean: {
2903 return EmitFloatToBoolConversion(Visit(
E));
2905 case CK_MemberPointerToBoolean: {
2906 llvm::Value *MemPtr = Visit(
E);
2911 case CK_FloatingComplexToReal:
2912 case CK_IntegralComplexToReal:
2915 case CK_FloatingComplexToBoolean:
2916 case CK_IntegralComplexToBoolean: {
2920 return EmitComplexToScalarConversion(
V,
E->
getType(), DestTy,
2924 case CK_ZeroToOCLOpaqueType: {
2927 "CK_ZeroToOCLEvent cast on non-event type");
2928 return llvm::Constant::getNullValue(ConvertType(DestTy));
2931 case CK_IntToOCLSampler:
2934 case CK_HLSLVectorTruncation: {
2936 "Destination type must be a vector or builtin type.");
2940 unsigned NumElts = VecTy->getNumElements();
2941 for (
unsigned I = 0; I != NumElts; ++I)
2944 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2946 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
2947 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
2949 case CK_HLSLElementwiseCast: {
2954 assert(RV.
isAggregate() &&
"Not a valid HLSL Elementwise Cast.");
2961 llvm_unreachable(
"unknown scalar cast");
2976 Value *
V = Visit(
E->getSubExpr());
2979 Scope.ForceCleanup({&
V});
2988 llvm::Value *InVal,
bool IsInc,
2992 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2994 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2995 BinOp.FPFeatures = FPFeatures;
3000llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3002 llvm::Value *Amount =
3003 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3004 StringRef Name = IsInc ?
"inc" :
"dec";
3005 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3007 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3008 return Builder.CreateAdd(InVal, Amount, Name);
3011 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3012 return Builder.CreateNSWAdd(InVal, Amount, Name);
3017 if (!
E->canOverflow() || CanElideOverflowCheck(CGF.
getContext(), Info))
3018 return Builder.CreateNSWAdd(InVal, Amount, Name);
3019 return EmitOverflowCheckedBinOp(Info);
3021 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3046class OMPLastprivateConditionalUpdateRAII {
3055 ~OMPLastprivateConditionalUpdateRAII() {
3058 CGF,
E->getSubExpr());
3065 bool isInc,
bool isPre) {
3067 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF,
E);
3069 llvm::PHINode *atomicPHI =
nullptr;
3075 int amount = (isInc ? 1 : -1);
3076 bool isSubtraction = !isInc;
3079 type = atomicTy->getValueType();
3080 if (isInc &&
type->isBooleanType()) {
3084 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3085 return Builder.getTrue();
3089 return Builder.CreateAtomicRMW(
3091 llvm::AtomicOrdering::SequentiallyConsistent);
3096 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3097 !(
type->isUnsignedIntegerType() &&
3098 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3101 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3102 llvm::AtomicRMWInst::Sub;
3103 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3104 llvm::Instruction::Sub;
3106 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3108 Builder.CreateAtomicRMW(aop, LV.
getAddress(), amt,
3109 llvm::AtomicOrdering::SequentiallyConsistent);
3110 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3114 if (
type->isFloatingType()) {
3115 llvm::Type *Ty = ConvertType(
type);
3116 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3117 llvm::AtomicRMWInst::BinOp aop =
3118 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3119 llvm::Instruction::BinaryOps op =
3120 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3121 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3122 llvm::AtomicRMWInst *old =
3124 llvm::AtomicOrdering::SequentiallyConsistent);
3126 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3132 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3135 Builder.CreateBr(opBB);
3136 Builder.SetInsertPoint(opBB);
3137 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3138 atomicPHI->addIncoming(value, startBB);
3152 if (isInc &&
type->isBooleanType()) {
3153 value = Builder.getTrue();
3156 }
else if (
type->isIntegerType()) {
3158 bool canPerformLossyDemotionCheck =
false;
3160 bool excludeOverflowPattern =
3165 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3166 canPerformLossyDemotionCheck =
true;
3167 canPerformLossyDemotionCheck &=
3170 canPerformLossyDemotionCheck &=
3172 type, promotedType);
3173 assert((!canPerformLossyDemotionCheck ||
3174 type->isSignedIntegerOrEnumerationType() ||
3176 ConvertType(
type)->getScalarSizeInBits() ==
3177 ConvertType(promotedType)->getScalarSizeInBits()) &&
3178 "The following check expects that if we do promotion to different "
3179 "underlying canonical type, at least one of the types (either "
3180 "base or promoted) will be signed, or the bitwidths will match.");
3183 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3184 SanitizerKind::ImplicitBitfieldConversion) &&
3185 canPerformLossyDemotionCheck) {
3199 value = EmitScalarConversion(value,
type, promotedType,
E->
getExprLoc());
3200 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3201 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3205 ScalarConversionOpts Opts;
3207 Opts = ScalarConversionOpts(CGF.
SanOpts);
3208 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3210 SrcType = promotedType;
3213 value = EmitScalarConversion(value, promotedType,
type,
E->
getExprLoc(),
3219 }
else if (
E->canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3220 value = EmitIncDecConsiderOverflowBehavior(
E, value, isInc);
3221 }
else if (
E->canOverflow() &&
type->isUnsignedIntegerType() &&
3222 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3223 !excludeOverflowPattern &&
3225 SanitizerKind::UnsignedIntegerOverflow,
E->
getType())) {
3229 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3230 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3241 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3244 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3247 elemTy, value, numElts,
false, isSubtraction,
3251 }
else if (
type->isFunctionType()) {
3252 llvm::Value *amt = Builder.getInt32(amount);
3255 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3259 false, isSubtraction,
3264 llvm::Value *amt = Builder.getInt32(amount);
3267 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3270 elemTy, value, amt,
false, isSubtraction,
3275 }
else if (
type->isVectorType()) {
3276 if (
type->hasIntegerRepresentation()) {
3277 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
3279 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3281 value = Builder.CreateFAdd(
3283 llvm::ConstantFP::get(value->getType(), amount),
3284 isInc ?
"inc" :
"dec");
3288 }
else if (
type->isRealFloatingType()) {
3296 value = Builder.CreateCall(
3299 input,
"incdec.conv");
3301 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3305 if (value->getType()->isFloatTy())
3306 amt = llvm::ConstantFP::get(VMContext,
3307 llvm::APFloat(
static_cast<float>(amount)));
3308 else if (value->getType()->isDoubleTy())
3309 amt = llvm::ConstantFP::get(VMContext,
3310 llvm::APFloat(
static_cast<double>(amount)));
3314 llvm::APFloat F(
static_cast<float>(amount));
3316 const llvm::fltSemantics *FS;
3319 if (value->getType()->isFP128Ty())
3321 else if (value->getType()->isHalfTy())
3323 else if (value->getType()->isBFloatTy())
3325 else if (value->getType()->isPPC_FP128Ty())
3329 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3330 amt = llvm::ConstantFP::get(VMContext, F);
3332 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3336 value = Builder.CreateCall(
3339 value,
"incdec.conv");
3341 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3346 }
else if (
type->isFixedPointType()) {
3353 Info.Opcode = isInc ? BO_Add : BO_Sub;
3355 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3358 if (
type->isSignedFixedPointType()) {
3359 Info.Opcode = isInc ? BO_Sub : BO_Add;
3360 Info.RHS = Builder.CreateNeg(Info.RHS);
3365 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3367 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3368 value = EmitFixedPointBinOp(Info);
3375 if (!isInc) size = -size;
3376 llvm::Value *sizeValue =
3377 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3380 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3383 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3385 value = Builder.CreateBitCast(value, input->getType());
3389 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3394 llvm::Value *
success = Pair.second;
3395 atomicPHI->addIncoming(old, curBlock);
3396 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3397 Builder.SetInsertPoint(contBB);
3398 return isPre ? value : input;
3412 return isPre ? value : input;
3419 ? getPromotionType(
E->getSubExpr()->
getType())
3421 Value *result = VisitPlus(
E, promotionTy);
3422 if (result && !promotionTy.
isNull())
3423 result = EmitUnPromotedValue(result,
E->
getType());
3430 TestAndClearIgnoreResultAssign();
3431 if (!PromotionType.
isNull())
3433 return Visit(
E->getSubExpr());
3439 ? getPromotionType(
E->getSubExpr()->
getType())
3441 Value *result = VisitMinus(
E, promotionTy);
3442 if (result && !promotionTy.
isNull())
3443 result = EmitUnPromotedValue(result,
E->
getType());
3449 TestAndClearIgnoreResultAssign();
3451 if (!PromotionType.
isNull())
3454 Op = Visit(
E->getSubExpr());
3457 if (Op->
getType()->isFPOrFPVectorTy())
3458 return Builder.CreateFNeg(Op,
"fneg");
3463 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3465 BinOp.Opcode = BO_Sub;
3468 return EmitSub(BinOp);
3472 TestAndClearIgnoreResultAssign();
3473 Value *Op = Visit(
E->getSubExpr());
3474 return Builder.CreateNot(Op,
"not");
3482 Value *Oper = Visit(
E->getSubExpr());
3485 if (Oper->
getType()->isFPOrFPVectorTy()) {
3488 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3490 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3491 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
3500 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3503 return Builder.CreateZExt(BoolVal, ConvertType(
E->
getType()),
"lnot.ext");
3511 return Builder.getInt(
Value);
3515 unsigned n =
E->getNumComponents();
3516 llvm::Type* ResultType = ConvertType(
E->
getType());
3517 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3519 for (
unsigned i = 0; i != n; ++i) {
3521 llvm::Value *Offset =
nullptr;
3528 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3535 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3539 Offset = Builder.CreateMul(Idx, ElemSize);
3552 FieldEnd = RD->field_end();
3553 Field != FieldEnd; ++Field, ++i) {
3554 if (*Field == MemberDecl)
3557 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3562 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3565 CurrentType = MemberDecl->
getType();
3570 llvm_unreachable(
"dependent __builtin_offsetof");
3587 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3599ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3601 QualType TypeToSize =
E->getTypeOfArgument();
3602 if (
auto Kind =
E->getKind();
3603 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3609 bool EvaluateExtent =
true;
3610 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3614 if (EvaluateExtent) {
3615 if (
E->isArgumentType()) {
3625 if (Kind == UETT_CountOf)
3634 if (!eltSize.
isOne())
3637 return VlaSize.NumElts;
3640 }
else if (
E->getKind() == UETT_OpenMPRequiredSimdAlign) {
3644 E->getTypeOfArgument()->getPointeeType()))
3646 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3647 }
else if (
E->getKind() == UETT_VectorElements) {
3648 auto *VecTy = cast<llvm::VectorType>(ConvertType(
E->getTypeOfArgument()));
3649 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3660 ? getPromotionType(
E->getSubExpr()->
getType())
3662 Value *result = VisitReal(
E, promotionTy);
3663 if (result && !promotionTy.
isNull())
3664 result = EmitUnPromotedValue(result,
E->
getType());
3670 Expr *Op =
E->getSubExpr();
3676 if (!PromotionType.
isNull()) {
3678 Op, IgnoreResultAssign,
true);
3681 return result.first;
3691 if (!PromotionType.
isNull())
3699 ? getPromotionType(
E->getSubExpr()->
getType())
3701 Value *result = VisitImag(
E, promotionTy);
3702 if (result && !promotionTy.
isNull())
3703 result = EmitUnPromotedValue(result,
E->
getType());
3709 Expr *Op =
E->getSubExpr();
3715 if (!PromotionType.
isNull()) {
3717 Op,
true, IgnoreResultAssign);
3720 return result.second;
3734 else if (!PromotionType.
isNull())
3738 if (!PromotionType.
isNull())
3739 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3740 return llvm::Constant::getNullValue(ConvertType(
E->
getType()));
3747Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3749 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3752Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3754 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3759 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
3761#define HANDLE_BINOP(OP) \
3763 return Emit##OP(EmitBinOps(BO, PromotionType));
3772 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
3775 return VisitImag(UO, PromotionType);
3777 return VisitReal(UO, PromotionType);
3779 return VisitMinus(UO, PromotionType);
3781 return VisitPlus(UO, PromotionType);
3786 auto result = Visit(
const_cast<Expr *
>(
E));
3788 if (!PromotionType.
isNull())
3789 return EmitPromotedValue(result, PromotionType);
3791 return EmitUnPromotedValue(result,
E->
getType());
3798 TestAndClearIgnoreResultAssign();
3802 if (!PromotionType.
isNull())
3803 Result.Ty = PromotionType;
3806 Result.Opcode =
E->getOpcode();
3812LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3814 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3819 if (
E->getComputationResultType()->isAnyComplexType())
3826 PromotionTypeCR = getPromotionType(
E->getComputationResultType());
3827 if (PromotionTypeCR.
isNull())
3828 PromotionTypeCR =
E->getComputationResultType();
3829 QualType PromotionTypeLHS = getPromotionType(
E->getComputationLHSType());
3831 if (!PromotionTypeRHS.
isNull())
3834 OpInfo.RHS = Visit(
E->getRHS());
3835 OpInfo.Ty = PromotionTypeCR;
3836 OpInfo.Opcode =
E->getOpcode();
3842 llvm::PHINode *atomicPHI =
nullptr;
3845 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3846 !(
type->isUnsignedIntegerType() &&
3847 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3850 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3851 llvm::Instruction::BinaryOps Op;
3852 switch (OpInfo.Opcode) {
3854 case BO_MulAssign:
case BO_DivAssign:
3860 AtomicOp = llvm::AtomicRMWInst::Add;
3861 Op = llvm::Instruction::Add;
3864 AtomicOp = llvm::AtomicRMWInst::Sub;
3865 Op = llvm::Instruction::Sub;
3868 AtomicOp = llvm::AtomicRMWInst::And;
3869 Op = llvm::Instruction::And;
3872 AtomicOp = llvm::AtomicRMWInst::Xor;
3873 Op = llvm::Instruction::Xor;
3876 AtomicOp = llvm::AtomicRMWInst::Or;
3877 Op = llvm::Instruction::Or;
3880 llvm_unreachable(
"Invalid compound assignment type");
3882 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3884 EmitScalarConversion(OpInfo.RHS,
E->getRHS()->
getType(), LHSTy,
3888 llvm::AtomicRMWInst *OldVal =
3893 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3899 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3901 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3903 Builder.CreateBr(opBB);
3904 Builder.SetInsertPoint(opBB);
3905 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3906 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3907 OpInfo.LHS = atomicPHI;
3910 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3914 if (!PromotionTypeLHS.
isNull())
3915 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3918 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3919 E->getComputationLHSType(),
Loc);
3934 ScalarConversionOpts(CGF.
SanOpts));
3937 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3941 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3942 llvm::Value *
success = Pair.second;
3943 atomicPHI->addIncoming(old, curBlock);
3944 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3945 Builder.SetInsertPoint(contBB);
3970 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3971 bool Ignore = TestAndClearIgnoreResultAssign();
3972 Value *RHS =
nullptr;
3973 LValue LHS = EmitCompoundAssignLValue(
E,
Func, RHS);
3991void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3992 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
3996 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3997 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
3998 SanitizerKind::SO_IntegerDivideByZero));
4001 const auto *BO = cast<BinaryOperator>(Ops.E);
4002 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4003 Ops.Ty->hasSignedIntegerRepresentation() &&
4005 Ops.mayHaveIntegerOverflow()) {
4006 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
4008 llvm::Value *IntMin =
4009 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4010 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4012 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4013 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4014 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4016 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4019 if (Checks.size() > 0)
4020 EmitBinOpCheck(Checks, Ops);
4023Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4026 {SanitizerKind::SO_IntegerDivideByZero,
4027 SanitizerKind::SO_SignedIntegerOverflow,
4028 SanitizerKind::SO_FloatDivideByZero},
4029 SanitizerHandler::DivremOverflow);
4030 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4031 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4032 Ops.Ty->isIntegerType() &&
4033 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4034 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4035 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4036 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4037 Ops.Ty->isRealFloatingType() &&
4038 Ops.mayHaveFloatDivisionByZero()) {
4039 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4040 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4042 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4046 if (Ops.Ty->isConstantMatrixType()) {
4047 llvm::MatrixBuilder MB(Builder);
4050 auto *BO = cast<BinaryOperator>(Ops.E);
4054 "first operand must be a matrix");
4056 "second operand must be an arithmetic type");
4058 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4059 Ops.Ty->hasUnsignedIntegerRepresentation());
4062 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4065 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4069 else if (Ops.isFixedPointOp())
4070 return EmitFixedPointBinOp(Ops);
4071 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4072 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4074 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4077Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4079 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4080 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4081 Ops.Ty->isIntegerType() &&
4082 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4084 {SanitizerKind::SO_IntegerDivideByZero,
4085 SanitizerKind::SO_SignedIntegerOverflow},
4086 SanitizerHandler::DivremOverflow);
4087 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4088 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4091 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4092 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4094 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4095 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4097 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4100Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4105 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4106 switch (Ops.Opcode) {
4110 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4111 llvm::Intrinsic::uadd_with_overflow;
4112 OverflowKind = SanitizerHandler::AddOverflow;
4117 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4118 llvm::Intrinsic::usub_with_overflow;
4119 OverflowKind = SanitizerHandler::SubOverflow;
4124 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4125 llvm::Intrinsic::umul_with_overflow;
4126 OverflowKind = SanitizerHandler::MulOverflow;
4129 llvm_unreachable(
"Unsupported operation for overflow detection");
4136 {SanitizerKind::SO_SignedIntegerOverflow,
4137 SanitizerKind::SO_UnsignedIntegerOverflow},
4143 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4144 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4145 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4148 const std::string *handlerName =
4150 if (handlerName->empty()) {
4153 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4154 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4156 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4157 : SanitizerKind::SO_UnsignedIntegerOverflow;
4158 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4160 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4165 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4166 llvm::BasicBlock *continueBB =
4170 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4174 Builder.SetInsertPoint(overflowBB);
4177 llvm::Type *Int8Ty = CGF.
Int8Ty;
4178 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4179 llvm::FunctionType *handlerTy =
4180 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4181 llvm::FunctionCallee handler =
4186 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4187 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4191 llvm::Value *handlerArgs[] = {
4194 Builder.getInt8(OpID),
4195 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
4197 llvm::Value *handlerResult =
4201 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4202 Builder.CreateBr(continueBB);
4204 Builder.SetInsertPoint(continueBB);
4205 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4206 phi->addIncoming(result, initialBB);
4207 phi->addIncoming(handlerResult, overflowBB);
4216 bool isSubtraction) {
4221 Value *pointer = op.LHS;
4222 Expr *pointerOperand =
expr->getLHS();
4223 Value *index = op.RHS;
4224 Expr *indexOperand =
expr->getRHS();
4227 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4228 std::swap(pointer, index);
4229 std::swap(pointerOperand, indexOperand);
4233 index, isSubtraction);
4239 Expr *indexOperand, llvm::Value *index,
bool isSubtraction) {
4242 unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
4244 auto *PtrTy = cast<llvm::PointerType>(pointer->getType());
4266 llvm::Value *Ptr =
Builder.CreateIntToPtr(index, pointer->getType());
4268 !
SanOpts.
has(SanitizerKind::PointerOverflow) ||
4269 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4270 PtrTy->getPointerAddressSpace()))
4273 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4274 auto CheckHandler = SanitizerHandler::PointerOverflow;
4278 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4279 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4280 llvm::Value *ComputedGEP =
Builder.CreateZExtOrTrunc(index,
IntPtrTy);
4281 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4282 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4287 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4290 index =
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
4296 index =
Builder.CreateNeg(index,
"idx.neg");
4308 llvm::Value *objectSize =
4311 index =
Builder.CreateMul(index, objectSize);
4314 return Builder.CreateBitCast(result, pointer->getType());
4319 getContext().getAsVariableArrayType(elementType)) {
4329 index =
Builder.CreateMul(index, numElements,
"vla.index");
4332 index =
Builder.CreateNSWMul(index, numElements,
"vla.index");
4363 bool negMul,
bool negAdd) {
4364 Value *MulOp0 = MulOp->getOperand(0);
4365 Value *MulOp1 = MulOp->getOperand(1);
4367 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4369 Addend = Builder.CreateFNeg(Addend,
"neg");
4371 Value *FMulAdd =
nullptr;
4372 if (Builder.getIsFPConstrained()) {
4373 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4374 "Only constrained operation should be created when Builder is in FP "
4375 "constrained mode");
4376 FMulAdd = Builder.CreateConstrainedFPCall(
4377 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4379 {MulOp0, MulOp1, Addend});
4381 FMulAdd = Builder.CreateCall(
4383 {MulOp0, MulOp1, Addend});
4385 MulOp->eraseFromParent();
4400 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4401 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4402 "Only fadd/fsub can be the root of an fmuladd.");
4405 if (!op.FPFeatures.allowFPContractWithinStatement())
4408 Value *LHS = op.LHS;
4409 Value *RHS = op.RHS;
4413 bool NegLHS =
false;
4414 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4415 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4416 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4417 LHS = LHSUnOp->getOperand(0);
4422 bool NegRHS =
false;
4423 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4424 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4425 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4426 RHS = RHSUnOp->getOperand(0);
4434 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4435 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4436 (LHSBinOp->use_empty() || NegLHS)) {
4439 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4440 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4443 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4444 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4445 (RHSBinOp->use_empty() || NegRHS)) {
4448 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4449 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4453 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4454 if (LHSBinOp->getIntrinsicID() ==
4455 llvm::Intrinsic::experimental_constrained_fmul &&
4456 (LHSBinOp->use_empty() || NegLHS)) {
4459 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4460 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4463 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4464 if (RHSBinOp->getIntrinsicID() ==
4465 llvm::Intrinsic::experimental_constrained_fmul &&
4466 (RHSBinOp->use_empty() || NegRHS)) {
4469 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4470 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4477Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4478 if (op.LHS->getType()->isPointerTy() ||
4479 op.RHS->getType()->isPointerTy())
4482 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4483 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4485 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4486 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4489 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4490 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4493 if (CanElideOverflowCheck(CGF.
getContext(), op))
4494 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4495 return EmitOverflowCheckedBinOp(op);
4500 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4507 if (op.Ty->isConstantMatrixType()) {
4508 llvm::MatrixBuilder MB(Builder);
4510 return MB.CreateAdd(op.LHS, op.RHS);
4513 if (op.Ty->isUnsignedIntegerType() &&
4514 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4515 !CanElideOverflowCheck(CGF.
getContext(), op))
4516 return EmitOverflowCheckedBinOp(op);
4518 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4520 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4523 if (op.isFixedPointOp())
4524 return EmitFixedPointBinOp(op);
4526 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4531Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4533 using llvm::ConstantInt;
4541 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4542 RHSTy = BinOp->getRHS()->getType();
4543 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4548 LHSTy = CAO->getComputationLHSType();
4549 ResultTy = CAO->getComputationResultType();
4551 LHSTy = BinOp->getLHS()->getType();
4552 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4553 LHSTy = UnOp->getSubExpr()->getType();
4554 RHSTy = UnOp->getSubExpr()->getType();
4557 Value *LHS = op.LHS;
4558 Value *RHS = op.RHS;
4563 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4567 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4568 switch (op.Opcode) {
4571 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4575 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4579 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4583 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4587 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4591 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4594 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4596 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4598 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4600 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4605 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4607 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4611 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4624 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4630 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4635Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4637 if (!op.LHS->getType()->isPointerTy()) {
4638 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4639 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4641 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4642 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4645 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4646 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4649 if (CanElideOverflowCheck(CGF.
getContext(), op))
4650 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4651 return EmitOverflowCheckedBinOp(op);
4656 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4663 if (op.Ty->isConstantMatrixType()) {
4664 llvm::MatrixBuilder MB(Builder);
4666 return MB.CreateSub(op.LHS, op.RHS);
4669 if (op.Ty->isUnsignedIntegerType() &&
4670 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4671 !CanElideOverflowCheck(CGF.
getContext(), op))
4672 return EmitOverflowCheckedBinOp(op);
4674 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4676 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4679 if (op.isFixedPointOp())
4680 return EmitFixedPointBinOp(op);
4682 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4687 if (!op.RHS->getType()->isPointerTy())
4694 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4696 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4697 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4701 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4703 llvm::Value *divisor =
nullptr;
4709 elementType = VlaSize.Type;
4710 divisor = VlaSize.NumElts;
4714 if (!eltSize.
isOne())
4730 if (elementSize.
isOne())
4739 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4742Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4744 llvm::IntegerType *Ty;
4745 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4746 Ty = cast<llvm::IntegerType>(VT->getElementType());
4748 Ty = cast<llvm::IntegerType>(LHS->
getType());
4753 llvm::Type *RHSTy = RHS->
getType();
4754 llvm::APInt RHSMax =
4755 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4756 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4757 if (RHSMax.ult(Ty->getBitWidth()))
4758 return llvm::ConstantInt::get(RHSTy, RHSMax);
4759 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4763 const Twine &Name) {
4764 llvm::IntegerType *Ty;
4765 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4766 Ty = cast<llvm::IntegerType>(VT->getElementType());
4768 Ty = cast<llvm::IntegerType>(LHS->
getType());
4770 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4771 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4773 return Builder.CreateURem(
4774 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4777Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4779 if (Ops.isFixedPointOp())
4780 return EmitFixedPointBinOp(Ops);
4784 Value *RHS = Ops.RHS;
4785 if (Ops.LHS->getType() != RHS->
getType())
4786 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4788 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4789 Ops.Ty->hasSignedIntegerRepresentation() &&
4792 bool SanitizeUnsignedBase =
4793 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4794 Ops.Ty->hasUnsignedIntegerRepresentation();
4795 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4796 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4799 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4800 else if ((SanitizeBase || SanitizeExponent) &&
4801 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4803 if (SanitizeSignedBase)
4804 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4805 if (SanitizeUnsignedBase)
4806 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4807 if (SanitizeExponent)
4808 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4811 SanitizerHandler::ShiftOutOfBounds);
4813 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4814 llvm::Value *WidthMinusOne =
4815 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4816 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4818 if (SanitizeExponent) {
4820 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4827 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4830 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4831 llvm::Value *PromotedWidthMinusOne =
4832 (RHS == Ops.RHS) ? WidthMinusOne
4833 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4835 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4836 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4839 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4845 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4846 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4848 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4849 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4851 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4852 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4853 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4854 Checks.push_back(std::make_pair(
4855 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4856 : SanitizerKind::SO_UnsignedShiftBase));
4859 assert(!Checks.empty());
4860 EmitBinOpCheck(Checks, Ops);
4863 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4866Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4868 if (Ops.isFixedPointOp())
4869 return EmitFixedPointBinOp(Ops);
4873 Value *RHS = Ops.RHS;
4874 if (Ops.LHS->getType() != RHS->
getType())
4875 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4879 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4880 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4881 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4883 SanitizerHandler::ShiftOutOfBounds);
4884 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4885 llvm::Value *
Valid = Builder.CreateICmpULE(
4886 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4887 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
4890 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4891 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4892 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4900 default: llvm_unreachable(
"unexpected element type");
4901 case BuiltinType::Char_U:
4902 case BuiltinType::UChar:
4903 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4904 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4905 case BuiltinType::Char_S:
4906 case BuiltinType::SChar:
4907 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4908 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4909 case BuiltinType::UShort:
4910 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4911 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4912 case BuiltinType::Short:
4913 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4914 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4915 case BuiltinType::UInt:
4916 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4917 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4918 case BuiltinType::Int:
4919 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4920 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4921 case BuiltinType::ULong:
4922 case BuiltinType::ULongLong:
4923 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4924 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4925 case BuiltinType::Long:
4926 case BuiltinType::LongLong:
4927 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4928 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4929 case BuiltinType::Float:
4930 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4931 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4932 case BuiltinType::Double:
4933 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4934 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4935 case BuiltinType::UInt128:
4936 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4937 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4938 case BuiltinType::Int128:
4939 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4940 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4945 llvm::CmpInst::Predicate UICmpOpc,
4946 llvm::CmpInst::Predicate SICmpOpc,
4947 llvm::CmpInst::Predicate FCmpOpc,
4949 TestAndClearIgnoreResultAssign();
4954 assert(
E->getOpcode() == BO_EQ ||
4955 E->getOpcode() == BO_NE);
4959 CGF, LHS, RHS, MPT,
E->getOpcode() == BO_NE);
4961 BinOpInfo BOInfo = EmitBinOps(
E);
4962 Value *LHS = BOInfo.LHS;
4963 Value *RHS = BOInfo.RHS;
4969 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4971 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4974 Value *FirstVecArg = LHS,
4975 *SecondVecArg = RHS;
4980 switch(
E->getOpcode()) {
4981 default: llvm_unreachable(
"is not a comparison operation");
4993 std::swap(FirstVecArg, SecondVecArg);
5000 if (ElementKind == BuiltinType::Float) {
5002 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5003 std::swap(FirstVecArg, SecondVecArg);
5011 if (ElementKind == BuiltinType::Float) {
5013 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5018 std::swap(FirstVecArg, SecondVecArg);
5023 Value *CR6Param = Builder.getInt32(CR6);
5025 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5032 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
5033 if (ResultTy->getBitWidth() > 1 &&
5035 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5040 if (BOInfo.isFixedPointOp()) {
5041 Result = EmitFixedPointBinOp(BOInfo);
5042 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5045 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5047 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5049 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5054 !isa<llvm::ConstantPointerNull>(LHS) &&
5055 !isa<llvm::ConstantPointerNull>(RHS)) {
5064 LHS = Builder.CreateStripInvariantGroup(LHS);
5066 RHS = Builder.CreateStripInvariantGroup(RHS);
5069 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5075 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
5083 CETy = CTy->getElementType();
5085 LHS.first = Visit(
E->getLHS());
5086 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5092 CTy->getElementType()) &&
5093 "The element types must always match.");
5096 RHS.first = Visit(
E->getRHS());
5097 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5099 "The element types must always match.");
5102 Value *ResultR, *ResultI;
5106 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5107 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5111 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5112 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5115 if (
E->getOpcode() == BO_EQ) {
5116 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5118 assert(
E->getOpcode() == BO_NE &&
5119 "Complex comparison other than == or != ?");
5120 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5132 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E->getRHS())) {
5133 CastKind Kind = ICE->getCastKind();
5134 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5135 *SrcType = ICE->getSubExpr()->getType();
5148 bool Ignore = TestAndClearIgnoreResultAssign();
5182 RHS = Visit(
E->getRHS());
5198 RHS = Visit(
E->getRHS());
5241 Value *LHS = Visit(
E->getLHS());
5242 Value *RHS = Visit(
E->getRHS());
5244 if (LHS->
getType()->isFPOrFPVectorTy()) {
5247 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5248 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5250 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5251 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5253 Value *
And = Builder.CreateAnd(LHS, RHS);
5254 return Builder.CreateSExt(
And, ConvertType(
E->
getType()),
"sext");
5258 llvm::Type *ResTy = ConvertType(
E->
getType());
5279 if (InstrumentRegions &&
5284 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5298 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5304 return llvm::Constant::getNullValue(ResTy);
5326 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5328 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5330 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5339 RHSBlock = Builder.GetInsertBlock();
5344 if (InstrumentRegions &&
5348 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5352 PN->addIncoming(RHSCond, RHSBlockCnt);
5362 PN->addIncoming(RHSCond, RHSBlock);
5372 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5376 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5384 Value *LHS = Visit(
E->getLHS());
5385 Value *RHS = Visit(
E->getRHS());
5387 if (LHS->
getType()->isFPOrFPVectorTy()) {
5390 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5391 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5393 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5394 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5396 Value *
Or = Builder.CreateOr(LHS, RHS);
5397 return Builder.CreateSExt(
Or, ConvertType(
E->
getType()),
"sext");
5401 llvm::Type *ResTy = ConvertType(
E->
getType());
5422 if (InstrumentRegions &&
5427 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5441 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5447 return llvm::ConstantInt::get(ResTy, 1);
5470 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5472 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5474 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5486 RHSBlock = Builder.GetInsertBlock();
5491 if (InstrumentRegions &&
5495 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5499 PN->addIncoming(RHSCond, RHSBlockCnt);
5505 PN->addIncoming(RHSCond, RHSBlock);
5513 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5519 return Visit(
E->getRHS());
5544Value *ScalarExprEmitter::
5546 TestAndClearIgnoreResultAssign();
5551 Expr *condExpr =
E->getCond();
5552 Expr *lhsExpr =
E->getTrueExpr();
5553 Expr *rhsExpr =
E->getFalseExpr();
5559 Expr *live = lhsExpr, *dead = rhsExpr;
5560 if (!CondExprBool) std::swap(live, dead);
5591 llvm::Value *LHS = Visit(lhsExpr);
5592 llvm::Value *RHS = Visit(rhsExpr);
5594 llvm::Type *condType = ConvertType(condExpr->
getType());
5595 auto *vecTy = cast<llvm::FixedVectorType>(condType);
5597 unsigned numElem = vecTy->getNumElements();
5598 llvm::Type *elemType = vecTy->getElementType();
5600 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5601 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5602 llvm::Value *tmp = Builder.CreateSExt(
5603 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5604 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5607 llvm::Value *RHSTmp = RHS;
5608 llvm::Value *LHSTmp = LHS;
5609 bool wasCast =
false;
5610 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
5611 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5612 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5613 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5617 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5618 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5619 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5621 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5631 llvm::Value *LHS = Visit(lhsExpr);
5632 llvm::Value *RHS = Visit(rhsExpr);
5634 llvm::Type *CondType = ConvertType(condExpr->
getType());
5635 auto *VecTy = cast<llvm::VectorType>(CondType);
5637 if (VecTy->getElementType()->isIntegerTy(1))
5638 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5641 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5643 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5645 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5646 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5655 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5664 llvm::Value *LHS = Visit(lhsExpr);
5665 llvm::Value *RHS = Visit(rhsExpr);
5668 assert(!RHS &&
"LHS and RHS types must match");
5671 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5700 Value *LHS = Visit(lhsExpr);
5703 LHSBlock = Builder.GetInsertBlock();
5704 Builder.CreateBr(ContBlock);
5718 Value *RHS = Visit(rhsExpr);
5721 RHSBlock = Builder.GetInsertBlock();
5731 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5732 PN->addIncoming(LHS, LHSBlock);
5733 PN->addIncoming(RHS, RHSBlock);
5744 return Visit(
E->getChosenSubExpr());
5754Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5760 Value *Src,
unsigned NumElementsDst) {
5761 static constexpr int Mask[] = {0, 1, 2, -1};
5762 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5782 const llvm::DataLayout &DL,
5783 Value *Src, llvm::Type *DstTy,
5784 StringRef Name =
"") {
5788 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5789 return Builder.CreateBitCast(Src, DstTy, Name);
5792 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5793 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5796 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5798 if (!DstTy->isIntegerTy())
5799 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5801 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5805 if (!SrcTy->isIntegerTy())
5806 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5808 return Builder.CreateIntToPtr(Src, DstTy, Name);
5813 llvm::Type *DstTy = ConvertType(
E->
getType());
5815 llvm::Type *SrcTy = Src->
getType();
5816 unsigned NumElementsSrc =
5817 isa<llvm::VectorType>(SrcTy)
5818 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5820 unsigned NumElementsDst =
5821 isa<llvm::VectorType>(DstTy)
5822 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5831 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5836 Src->setName(
"astype");
5843 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5844 auto *Vec4Ty = llvm::FixedVectorType::get(
5845 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5850 Src->setName(
"astype");
5855 Src, DstTy,
"astype");
5870 "Invalid scalar expression to emit");
5872 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5873 .Visit(
const_cast<Expr *
>(
E));
5882 "Invalid scalar expression to emit");
5883 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy,
Loc);
5893 "Invalid complex -> scalar conversion");
5894 return ScalarExprEmitter(*
this)
5895 .EmitComplexToScalarConversion(Src, SrcTy, DstTy,
Loc);
5902 if (!PromotionType.
isNull())
5903 return ScalarExprEmitter(*this).EmitPromoted(
E, PromotionType);
5905 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(
E));
5911 bool isInc,
bool isPre) {
5912 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(
E, LV, isInc, isPre);
5919 Expr *BaseExpr =
E->getBase();
5922 llvm::Type *BaseTy =
5938 ScalarExprEmitter Scalar(*
this);
5940 switch (
E->getOpcode()) {
5941#define COMPOUND_OP(Op) \
5942 case BO_##Op##Assign: \
5943 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5980 llvm_unreachable(
"Not valid compound assignment operators");
5983 llvm_unreachable(
"Unhandled compound assignment operator");
5998 llvm::LLVMContext &VMContext,
6004 llvm::Value *TotalOffset =
nullptr;
6007 if (isa<llvm::Constant>(GEPVal)) {
6010 Value *BasePtr_int =
6011 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6013 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6014 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6015 return {TotalOffset, Builder.getFalse()};
6018 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
6019 assert(GEP->getPointerOperand() == BasePtr &&
6020 "BasePtr must be the base of the GEP.");
6021 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6023 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6026 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6027 auto *SAddIntrinsic =
6028 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6029 auto *SMulIntrinsic =
6030 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6033 llvm::Value *OffsetOverflows = Builder.getFalse();
6037 llvm::Value *RHS) -> llvm::Value * {
6038 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6041 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6042 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6044 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6047 OffsetOverflows = Builder.getTrue();
6048 return llvm::ConstantInt::get(VMContext, N);
6053 auto *ResultAndOverflow = Builder.CreateCall(
6054 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6055 OffsetOverflows = Builder.CreateOr(
6056 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6057 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6061 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6062 GTI != GTE; ++GTI) {
6063 llvm::Value *LocalOffset;
6064 auto *Index = GTI.getOperand();
6066 if (
auto *STy = GTI.getStructTypeOrNull()) {
6069 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
6070 LocalOffset = llvm::ConstantInt::get(
6071 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6076 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6077 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6078 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6083 if (!TotalOffset || TotalOffset ==
Zero)
6084 TotalOffset = LocalOffset;
6086 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6089 return {TotalOffset, OffsetOverflows};
6095 bool SignedIndices,
bool IsSubtraction,
6097 llvm::Type *PtrTy = Ptr->
getType();
6099 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6101 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6106 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
6110 bool PerformNullCheck = !NullPointerIsDefined(
6111 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6114 bool PerformOverflowCheck =
6115 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
6117 if (!(PerformNullCheck || PerformOverflowCheck))
6122 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6123 auto CheckHandler = SanitizerHandler::PointerOverflow;
6125 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
6130 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
6132 "If the offset got constant-folded, we don't expect that there was an "
6135 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
6150 if (PerformNullCheck) {
6158 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
6159 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
6160 auto *
Valid =
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6161 Checks.emplace_back(
Valid, CheckOrdinal);
6164 if (PerformOverflowCheck) {
6169 llvm::Value *ValidGEP;
6171 if (SignedIndices) {
6177 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6178 auto *PosOrZeroOffset =
6180 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
6182 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6188 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6194 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
6196 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6197 Checks.emplace_back(ValidGEP, CheckOrdinal);
6200 assert(!Checks.empty() &&
"Should have produced some checks.");
6204 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6205 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6213 const Twine &Name) {
6214 if (!
SanOpts.
has(SanitizerKind::PointerOverflow)) {
6215 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6217 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6225 elementType, Align);
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, Address DestVal, QualType DestTy, Address SrcVal, QualType SrcTy, SourceLocation Loc)
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc, bool isPre, ASTContext &Ctx)
For the purposes of overflow pattern exclusion, does this match the "while(i--)" pattern?
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
ParentMapContext & getParentMapContext()
Returns the dynamic AST node parent map context.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AddrLabelExpr - The GNU address of label extension, representing &&label.
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
QualType getElementType() const
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
This class is used for builtin types like 'int'.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
A boolean literal, per ([C++ lex.bool] Boolean literals).
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Represents a C++ struct/union/class.
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Represents the this expression in C++.
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Represents a 'co_await' expression.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
The scope of a CXXDefaultInitExpr.
An object to manage conditionally-evaluated expressions.
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
An RAII object to record that we're evaluating a statement expression.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
void FlattenAccessAndType(Address Addr, QualType AddrTy, SmallVectorImpl< std::pair< Address, llvm::Value * > > &AccessList, SmallVectorImpl< QualType > &FlatTypes)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
void setTBAAInfo(TBAAAccessInfo Info)
const Qualifiers & getQuals() const
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
CompoundLiteralExpr - [C99 6.5.2.5].
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumRows() const
Returns the number of rows in the matrix.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents a 'co_yield' expression.
const Expr * getDefaultExpr() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
A reference to a declared variable, function, enum, etc.
Represents a reference to #emded data.
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
An expression trait intrinsic.
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
@ PostDecrInWhile
while (count–)
bool isSignedOverflowDefined() const
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Represents a matrix type, as defined in the Matrix Types clang extensions.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a reference to a non-type template parameter that has been substituted with a template arg...
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represents a call to the builtin function __builtin_va_arg.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
VectorKind getVectorKind() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
@ Generic
not a target-specific vector type
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.