32#include "llvm/ADT/APFixedPoint.h"
33#include "llvm/IR/CFG.h"
34#include "llvm/IR/Constants.h"
35#include "llvm/IR/DataLayout.h"
36#include "llvm/IR/DerivedTypes.h"
37#include "llvm/IR/FixedPointBuilder.h"
38#include "llvm/IR/Function.h"
39#include "llvm/IR/GetElementPtrTypeIterator.h"
40#include "llvm/IR/GlobalVariable.h"
41#include "llvm/IR/Intrinsics.h"
42#include "llvm/IR/IntrinsicsPowerPC.h"
43#include "llvm/IR/MatrixBuilder.h"
44#include "llvm/IR/Module.h"
45#include "llvm/Support/TypeSize.h"
50using namespace CodeGen;
68bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
70 llvm::APInt &Result) {
73 const auto &LHSAP = LHS->getValue();
74 const auto &RHSAP = RHS->getValue();
75 if (Opcode == BO_Add) {
76 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
77 : LHSAP.uadd_ov(RHSAP, Overflow);
78 }
else if (Opcode == BO_Sub) {
79 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
80 : LHSAP.usub_ov(RHSAP, Overflow);
81 }
else if (Opcode == BO_Mul) {
82 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
83 : LHSAP.umul_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
85 if (
Signed && !RHS->isZero())
86 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
102 bool mayHaveIntegerOverflow()
const {
104 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
105 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
106 if (!LHSCI || !RHSCI)
110 return ::mayHaveIntegerOverflow(
115 bool isDivremOp()
const {
121 bool mayHaveIntegerDivisionByZero()
const {
123 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
129 bool mayHaveFloatDivisionByZero()
const {
131 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
132 return CFP->isZero();
139 bool isFixedPointOp()
const {
142 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
143 QualType LHSType = BinOp->getLHS()->getType();
144 QualType RHSType = BinOp->getRHS()->getType();
147 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
148 return UnOp->getSubExpr()->getType()->isFixedPointType();
153 bool rhsHasSignedIntegerRepresentation()
const {
154 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
155 QualType RHSType = BinOp->getRHS()->getType();
162static bool MustVisitNullValue(
const Expr *
E) {
170static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
186 return getUnwidenedIntegerType(Ctx,
E).has_value();
190static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
191 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
192 "Expected a unary or binary operator");
196 if (!Op.mayHaveIntegerOverflow())
203 LangOptions::OverflowPatternExclusionKind::NegUnsignedConst) &&
213 const auto *BO = cast<BinaryOperator>(Op.E);
214 if (BO->hasExcludedOverflowPattern())
217 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
221 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
230 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
236 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
237 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
241class ScalarExprEmitter
245 bool IgnoreResultAssign;
246 llvm::LLVMContext &VMContext;
250 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
251 VMContext(cgf.getLLVMContext()) {
258 bool TestAndClearIgnoreResultAssign() {
259 bool I = IgnoreResultAssign;
260 IgnoreResultAssign =
false;
266 LValue EmitCheckedLValue(
const Expr *
E, CodeGenFunction::TypeCheckKind TCK) {
270 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
271 const BinOpInfo &Info);
277 void EmitLValueAlignmentAssumption(
const Expr *
E,
Value *
V) {
278 const AlignValueAttr *AVAttr =
nullptr;
279 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
283 if (
const auto *TTy =
285 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
292 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
295 AVAttr = VD->
getAttr<AlignValueAttr>();
301 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
307 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
315 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(
E, CodeGenFunction::TCK_Load),
318 EmitLValueAlignmentAssumption(
E,
V);
328 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
335 enum ImplicitConversionCheckKind :
unsigned char {
336 ICCK_IntegerTruncation = 0,
337 ICCK_UnsignedIntegerTruncation = 1,
338 ICCK_SignedIntegerTruncation = 2,
339 ICCK_IntegerSignChange = 3,
340 ICCK_SignedIntegerTruncationOrSignChange = 4,
356 struct ScalarConversionOpts {
357 bool TreatBooleanAsSigned;
358 bool EmitImplicitIntegerTruncationChecks;
359 bool EmitImplicitIntegerSignChangeChecks;
361 ScalarConversionOpts()
362 : TreatBooleanAsSigned(
false),
363 EmitImplicitIntegerTruncationChecks(
false),
364 EmitImplicitIntegerSignChangeChecks(
false) {}
367 : TreatBooleanAsSigned(
false),
368 EmitImplicitIntegerTruncationChecks(
370 EmitImplicitIntegerSignChangeChecks(
374 llvm::Type *SrcTy, llvm::Type *DstTy,
375 ScalarConversionOpts Opts);
379 ScalarConversionOpts Opts = ScalarConversionOpts());
388 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
398 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
399 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
406 return Builder.CreateICmpNE(
V, Zero,
"tobool");
413 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
414 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
415 Value *Result = ZI->getOperand(0);
420 ZI->eraseFromParent();
425 return Builder.CreateIsNotNull(
V,
"tobool");
439 llvm_unreachable(
"Stmt can't have complex result type!");
457 return Visit(
E->getSubExpr());
463 return Visit(
E->getReplacement());
466 return Visit(
GE->getResultExpr());
475 return Visit(
E->getSubExpr());
480 return Builder.getInt(
E->getValue());
483 return Builder.getInt(
E->getValue());
486 return llvm::ConstantFP::get(VMContext,
E->getValue());
489 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
492 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
495 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
510 return Builder.CreateBitCast(
V, ConvertType(
E->
getType()));
514 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getPackLength());
537 return EmitLoadOfLValue(
E);
547 return EmitLoadOfLValue(
E);
550 if (
E->getMethodDecl() &&
551 E->getMethodDecl()->getReturnType()->isReferenceType())
552 return EmitLoadOfLValue(
E);
563 VersionTuple Version =
E->getVersion();
568 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
578 Value *VisitExtVectorElementExpr(
Expr *
E) {
return EmitLoadOfLValue(
E); }
585 return EmitLoadOfLValue(
E);
592 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
601 return VisitCastExpr(
E);
606 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
607 return EmitLoadOfLValue(
E);
611 EmitLValueAlignmentAssumption(
E,
V);
619 LValue LV = EmitLValue(
E->getSubExpr());
620 return EmitScalarPrePostIncDec(
E, LV,
false,
false);
623 LValue LV = EmitLValue(
E->getSubExpr());
624 return EmitScalarPrePostIncDec(
E, LV,
true,
false);
627 LValue LV = EmitLValue(
E->getSubExpr());
628 return EmitScalarPrePostIncDec(
E, LV,
false,
true);
631 LValue LV = EmitLValue(
E->getSubExpr());
632 return EmitScalarPrePostIncDec(
E, LV,
true,
true);
635 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *
E,
640 bool isInc,
bool isPre);
644 if (isa<MemberPointerType>(
E->
getType()))
647 return EmitLValue(
E->getSubExpr()).getPointer(CGF);
651 return Visit(
E->getSubExpr());
652 return EmitLoadOfLValue(
E);
671 return Visit(
E->getSubExpr());
676 return EmitLoadOfLValue(
E);
687 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
691 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
708 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
712 return Builder.getInt1(
E->isSatisfied());
716 return Builder.getInt1(
E->isSatisfied());
720 return llvm::ConstantInt::get(Builder.getInt32Ty(),
E->getValue());
724 return llvm::ConstantInt::get(Builder.getInt1Ty(),
E->getValue());
747 return Builder.getInt1(
E->getValue());
751 Value *EmitMul(
const BinOpInfo &Ops) {
752 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
753 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
755 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
756 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
759 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
760 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
763 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
764 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
765 return EmitOverflowCheckedBinOp(Ops);
769 if (Ops.Ty->isConstantMatrixType()) {
770 llvm::MatrixBuilder MB(Builder);
773 auto *BO = cast<BinaryOperator>(Ops.E);
774 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
775 BO->getLHS()->getType().getCanonicalType());
776 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
777 BO->getRHS()->getType().getCanonicalType());
778 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
779 if (LHSMatTy && RHSMatTy)
780 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
781 LHSMatTy->getNumColumns(),
782 RHSMatTy->getNumColumns());
783 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
786 if (Ops.Ty->isUnsignedIntegerType() &&
787 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
788 !CanElideOverflowCheck(CGF.
getContext(), Ops))
789 return EmitOverflowCheckedBinOp(Ops);
791 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
793 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
794 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
796 if (Ops.isFixedPointOp())
797 return EmitFixedPointBinOp(Ops);
798 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
802 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
805 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
806 llvm::Value *Zero,
bool isDiv);
808 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
814 Value *EmitDiv(
const BinOpInfo &Ops);
815 Value *EmitRem(
const BinOpInfo &Ops);
816 Value *EmitAdd(
const BinOpInfo &Ops);
817 Value *EmitSub(
const BinOpInfo &Ops);
818 Value *EmitShl(
const BinOpInfo &Ops);
819 Value *EmitShr(
const BinOpInfo &Ops);
820 Value *EmitAnd(
const BinOpInfo &Ops) {
821 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
823 Value *EmitXor(
const BinOpInfo &Ops) {
824 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
826 Value *EmitOr (
const BinOpInfo &Ops) {
827 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
831 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
841 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
845 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
850 QualType ElementType = CT->getElementType();
857 unsigned NumElements = VT->getNumElements();
867#define HANDLEBINOP(OP) \
868 Value *VisitBin##OP(const BinaryOperator *E) { \
869 QualType promotionTy = getPromotionType(E->getType()); \
870 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
871 if (result && !promotionTy.isNull()) \
872 result = EmitUnPromotedValue(result, E->getType()); \
875 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
876 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
892 llvm::CmpInst::Predicate SICmpOpc,
893 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
894#define VISITCOMP(CODE, UI, SI, FP, SIG) \
895 Value *VisitBin##CODE(const BinaryOperator *E) { \
896 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
897 llvm::FCmpInst::FP, SIG); }
912 Value *VisitBinPtrMemD(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
913 Value *VisitBinPtrMemI(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
916 return Visit(
E->getSemanticForm());
939 return Visit(
E->getSelectedExpr());
951 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
954 return EmitFloatToBoolConversion(Src);
960 "Unknown scalar type to convert");
962 if (isa<llvm::IntegerType>(Src->
getType()))
963 return EmitIntToBoolConversion(Src);
965 assert(isa<llvm::PointerType>(Src->
getType()));
966 return EmitPointerToBoolConversion(Src, SrcType);
969void ScalarExprEmitter::EmitFloatConversionCheck(
972 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
973 if (!isa<llvm::IntegerType>(DstTy))
976 CodeGenFunction::SanitizerScope SanScope(&CGF);
980 llvm::Value *Check =
nullptr;
981 const llvm::fltSemantics &SrcSema =
991 APFloat MinSrc(SrcSema, APFloat::uninitialized);
992 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
996 MinSrc = APFloat::getInf(SrcSema,
true);
1000 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1003 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1004 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1005 APFloat::opOverflow)
1008 MaxSrc = APFloat::getInf(SrcSema,
false);
1012 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1017 const llvm::fltSemantics &
Sema =
1020 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1021 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1025 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1027 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1028 Check = Builder.CreateAnd(GE, LE);
1033 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1034 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1039static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1040 std::pair<llvm::Value *, SanitizerMask>>
1043 llvm::Type *SrcTy = Src->
getType();
1044 llvm::Type *DstTy = Dst->
getType();
1049 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1050 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1051 "non-integer llvm type");
1058 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1060 if (!SrcSigned && !DstSigned) {
1061 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1062 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1064 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1065 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1068 llvm::Value *Check =
nullptr;
1070 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1072 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1074 return std::make_pair(Kind, std::make_pair(Check, Mask));
1082void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1094 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1095 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1097 if (SrcBits <= DstBits)
1100 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1107 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1108 (!SrcSigned && DstSigned))
1111 CodeGenFunction::SanitizerScope SanScope(&CGF);
1113 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1114 std::pair<llvm::Value *, SanitizerMask>>
1123 llvm::Constant *StaticArgs[] = {
1126 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1127 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1129 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1137 llvm::Type *VTy =
V->getType();
1140 return llvm::ConstantInt::getFalse(VTy->getContext());
1142 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1143 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1144 llvm::Twine(Name) +
"." +
V->getName() +
1145 ".negativitycheck");
1150static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1151 std::pair<llvm::Value *, SanitizerMask>>
1154 llvm::Type *SrcTy = Src->
getType();
1155 llvm::Type *DstTy = Dst->
getType();
1157 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1158 "non-integer llvm type");
1164 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1165 unsigned DstBits = DstTy->getScalarSizeInBits();
1169 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1170 "either the widths should be different, or the signednesses.");
1173 llvm::Value *SrcIsNegative =
1176 llvm::Value *DstIsNegative =
1182 llvm::Value *Check =
nullptr;
1183 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1185 return std::make_pair(
1186 ScalarExprEmitter::ICCK_IntegerSignChange,
1187 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1190void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1193 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1196 llvm::Type *SrcTy = Src->
getType();
1197 llvm::Type *DstTy = Dst->
getType();
1207 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1208 unsigned DstBits = DstTy->getScalarSizeInBits();
1215 if (SrcSigned == DstSigned && SrcBits == DstBits)
1219 if (!SrcSigned && !DstSigned)
1224 if ((DstBits > SrcBits) && DstSigned)
1226 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1227 (SrcBits > DstBits) && SrcSigned) {
1235 CodeGenFunction::SanitizerScope SanScope(&CGF);
1237 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1238 std::pair<llvm::Value *, SanitizerMask>>
1242 ImplicitConversionCheckKind CheckKind;
1248 CheckKind = Check.first;
1249 Checks.emplace_back(Check.second);
1251 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1252 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1258 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1259 Checks.emplace_back(Check.second);
1263 llvm::Constant *StaticArgs[] = {
1266 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1267 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1269 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1275static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1276 std::pair<llvm::Value *, SanitizerMask>>
1282 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1283 if (!SrcSigned && !DstSigned)
1284 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1286 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1288 llvm::Value *Check =
nullptr;
1290 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1292 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1295 return std::make_pair(
1296 Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1301static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1302 std::pair<llvm::Value *, SanitizerMask>>
1306 llvm::Value *SrcIsNegative =
1309 llvm::Value *DstIsNegative =
1315 llvm::Value *Check =
nullptr;
1317 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1319 return std::make_pair(
1320 ScalarExprEmitter::ICCK_IntegerSignChange,
1321 std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1324void CodeGenFunction::EmitBitfieldConversionCheck(
Value *Src,
QualType SrcType,
1329 if (!
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion))
1342 assert(isa<llvm::IntegerType>(Src->
getType()) &&
1343 isa<llvm::IntegerType>(Dst->
getType()) &&
"non-integer llvm type");
1347 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1348 unsigned DstBits = Info.
Size;
1353 CodeGenFunction::SanitizerScope SanScope(
this);
1355 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1356 std::pair<llvm::Value *, SanitizerMask>>
1360 bool EmitTruncation = DstBits < SrcBits;
1364 bool EmitTruncationFromUnsignedToSigned =
1365 EmitTruncation && DstSigned && !SrcSigned;
1367 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1368 bool BothUnsigned = !SrcSigned && !DstSigned;
1369 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1376 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1381 else if (EmitSignChange) {
1382 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1383 "either the widths should be different, or the signednesses.");
1389 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1390 if (EmitTruncationFromUnsignedToSigned)
1391 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1393 llvm::Constant *StaticArgs[] = {
1396 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1397 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1399 EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1404 QualType DstType, llvm::Type *SrcTy,
1406 ScalarConversionOpts Opts) {
1408 llvm::Type *SrcElementTy;
1409 llvm::Type *DstElementTy;
1413 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1414 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1419 "cannot cast between matrix and non-matrix types");
1420 SrcElementTy = SrcTy;
1421 DstElementTy = DstTy;
1422 SrcElementType = SrcType;
1423 DstElementType = DstType;
1426 if (isa<llvm::IntegerType>(SrcElementTy)) {
1428 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1432 if (isa<llvm::IntegerType>(DstElementTy))
1433 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1435 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1436 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1439 if (isa<llvm::IntegerType>(DstElementTy)) {
1440 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1447 llvm::Intrinsic::ID IID =
1448 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1449 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1453 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1454 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1457 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1458 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1459 return Builder.CreateFPExt(Src, DstTy,
"conv");
1467 ScalarConversionOpts Opts) {
1482 return Builder.CreateIsNotNull(Src,
"tobool");
1485 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1488 "Unhandled scalar conversion from a fixed point type to another type.");
1492 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1495 "Unhandled scalar conversion to a fixed point type from another type.");
1498 QualType NoncanonicalSrcType = SrcType;
1499 QualType NoncanonicalDstType = DstType;
1503 if (SrcType == DstType)
return Src;
1507 llvm::Value *OrigSrc = Src;
1509 llvm::Type *SrcTy = Src->
getType();
1513 return EmitConversionToBool(Src, SrcType);
1515 llvm::Type *DstTy = ConvertType(DstType);
1520 if (DstTy->isFloatingPointTy()) {
1522 return Builder.CreateCall(
1530 Src = Builder.CreateCall(
1535 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1543 if (SrcTy == DstTy) {
1544 if (Opts.EmitImplicitIntegerSignChangeChecks)
1545 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1546 NoncanonicalDstType,
Loc);
1554 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1556 if (isa<llvm::PointerType>(SrcTy))
1559 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1564 llvm::Value* IntResult =
1565 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1567 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1570 if (isa<llvm::PointerType>(SrcTy)) {
1572 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1573 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1582 "Splatted expr doesn't match with vector element type?");
1585 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1586 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1590 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1592 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1594 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1595 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1596 if (SrcSize == DstSize)
1597 return Builder.CreateBitCast(Src, DstTy,
"conv");
1606 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1607 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1610 assert(((SrcElementTy->isIntegerTy() &&
1611 DstElementTy->isIntegerTy()) ||
1612 (SrcElementTy->isFloatingPointTy() &&
1613 DstElementTy->isFloatingPointTy())) &&
1614 "unexpected conversion between a floating-point vector and an "
1618 if (SrcElementTy->isIntegerTy())
1619 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1622 if (SrcSize > DstSize)
1623 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1626 return Builder.CreateFPExt(Src, DstTy,
"conv");
1630 Value *Res =
nullptr;
1631 llvm::Type *ResTy = DstTy;
1638 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1640 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1646 if (SrcTy->isFloatingPointTy()) {
1650 return Builder.CreateCall(
1653 return Builder.CreateFPTrunc(Src, DstTy);
1658 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1660 if (DstTy != ResTy) {
1662 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1663 Res = Builder.CreateCall(
1667 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1671 if (Opts.EmitImplicitIntegerTruncationChecks)
1672 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1673 NoncanonicalDstType,
Loc);
1675 if (Opts.EmitImplicitIntegerSignChangeChecks)
1676 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1677 NoncanonicalDstType,
Loc);
1685 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1688 Result = FPBuilder.CreateFloatingToFixed(Src,
1691 Result = FPBuilder.CreateFixedToFloating(Src,
1693 ConvertType(DstTy));
1699 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1700 DstFPSema.getWidth(),
1701 DstFPSema.isSigned());
1703 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1706 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1713Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1722 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1723 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy,
Loc);
1724 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1731 return EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1742void ScalarExprEmitter::EmitBinOpCheck(
1743 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1755 if (UO && UO->
getOpcode() == UO_Minus) {
1756 Check = SanitizerHandler::NegateOverflow;
1758 DynamicData.push_back(Info.RHS);
1762 Check = SanitizerHandler::ShiftOutOfBounds;
1764 StaticData.push_back(
1766 StaticData.push_back(
1768 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1770 Check = SanitizerHandler::DivremOverflow;
1775 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1776 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1777 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1778 default: llvm_unreachable(
"unexpected opcode for bin op check");
1782 DynamicData.push_back(Info.LHS);
1783 DynamicData.push_back(Info.RHS);
1786 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1793Value *ScalarExprEmitter::VisitExpr(
Expr *
E) {
1803 unsigned AddrSpace =
1805 llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1806 E->ComputeName(Context),
"__usn_str", AddrSpace);
1808 llvm::Type *ExprTy = ConvertType(
E->
getType());
1809 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1814 assert(
E->getDataElementCount() == 1);
1815 auto It =
E->begin();
1816 return Builder.getInt((*It)->getValue());
1821 if (
E->getNumSubExprs() == 2) {
1826 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1827 unsigned LHSElts = LTy->getNumElements();
1831 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1835 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1836 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1844 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1845 MTy->getNumElements());
1846 Value* NewV = llvm::PoisonValue::get(RTy);
1847 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1848 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1849 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1851 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1852 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1861 for (
unsigned i = 2; i <
E->getNumSubExprs(); ++i) {
1862 llvm::APSInt Idx =
E->getShuffleMaskIdx(CGF.
getContext(), i-2);
1864 if (Idx.isSigned() && Idx.isAllOnes())
1865 Indices.push_back(-1);
1867 Indices.push_back(Idx.getZExtValue());
1870 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1881 if (SrcType == DstType)
return Src;
1884 "ConvertVector source type must be a vector");
1886 "ConvertVector destination type must be a vector");
1888 llvm::Type *SrcTy = Src->
getType();
1889 llvm::Type *DstTy = ConvertType(DstType);
1898 assert(SrcTy->isVectorTy() &&
1899 "ConvertVector source IR type must be a vector");
1900 assert(DstTy->isVectorTy() &&
1901 "ConvertVector destination IR type must be a vector");
1903 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1904 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1906 if (DstEltType->isBooleanType()) {
1907 assert((SrcEltTy->isFloatingPointTy() ||
1908 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1910 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1911 if (SrcEltTy->isFloatingPointTy()) {
1912 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1914 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1919 Value *Res =
nullptr;
1921 if (isa<llvm::IntegerType>(SrcEltTy)) {
1923 if (isa<llvm::IntegerType>(DstEltTy))
1924 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1925 else if (InputSigned)
1926 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1928 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1929 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1930 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1931 if (DstEltType->isSignedIntegerOrEnumerationType())
1932 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1934 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1936 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1937 "Unknown real conversion");
1938 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1939 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1941 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1956 return Builder.getInt(
Value);
1960 llvm::Value *
Result = EmitLoadOfLValue(
E);
1966 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
1967 if (llvm::GetElementPtrInst *GEP =
1968 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
1969 if (llvm::Instruction *
Pointer =
1970 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
1983 TestAndClearIgnoreResultAssign();
1991 return EmitLoadOfLValue(
E);
1996 Value *Idx = Visit(
E->getIdx());
1999 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2002 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
2006 TestAndClearIgnoreResultAssign();
2010 Value *RowIdx = Visit(
E->getRowIdx());
2011 Value *ColumnIdx = Visit(
E->getColumnIdx());
2015 llvm::MatrixBuilder MB(Builder);
2016 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2018 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2020 Value *Matrix = Visit(
E->getBase());
2023 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2028 int MV = SVI->getMaskValue(Idx);
2035 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2036 "Index operand too large for shufflevector mask!");
2037 return C->getZExtValue();
2041 bool Ignore = TestAndClearIgnoreResultAssign();
2043 assert (Ignore ==
false &&
"init list ignored");
2044 unsigned NumInitElements =
E->getNumInits();
2046 if (
E->hadArrayRangeDesignator())
2049 llvm::VectorType *VType =
2050 dyn_cast<llvm::VectorType>(ConvertType(
E->
getType()));
2053 if (NumInitElements == 0) {
2055 return EmitNullValue(
E->
getType());
2058 return Visit(
E->getInit(0));
2061 if (isa<llvm::ScalableVectorType>(VType)) {
2062 if (NumInitElements == 0) {
2064 return EmitNullValue(
E->
getType());
2067 if (NumInitElements == 1) {
2068 Expr *InitVector =
E->getInit(0);
2072 return Visit(InitVector);
2075 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2078 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
2085 unsigned CurIdx = 0;
2086 bool VIsPoisonShuffle =
false;
2087 llvm::Value *
V = llvm::PoisonValue::get(VType);
2088 for (
unsigned i = 0; i != NumInitElements; ++i) {
2089 Expr *IE =
E->getInit(i);
2093 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2099 if (isa<ExtVectorElementExpr>(IE)) {
2100 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
2102 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2103 ->getNumElements() == ResElts) {
2104 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
2105 Value *LHS =
nullptr, *RHS =
nullptr;
2110 Args.resize(ResElts, -1);
2112 LHS = EI->getVectorOperand();
2114 VIsPoisonShuffle =
true;
2115 }
else if (VIsPoisonShuffle) {
2117 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
2118 for (
unsigned j = 0; j != CurIdx; ++j)
2120 Args.push_back(ResElts +
C->getZExtValue());
2121 Args.resize(ResElts, -1);
2123 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2124 RHS = EI->getVectorOperand();
2125 VIsPoisonShuffle =
false;
2127 if (!Args.empty()) {
2128 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2134 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2136 VIsPoisonShuffle =
false;
2141 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
2146 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2147 if (isa<ExtVectorElementExpr>(IE)) {
2148 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
2149 Value *SVOp = SVI->getOperand(0);
2150 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
2152 if (OpTy->getNumElements() == ResElts) {
2153 for (
unsigned j = 0; j != CurIdx; ++j) {
2156 if (VIsPoisonShuffle) {
2157 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
2162 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2164 Args.resize(ResElts, -1);
2166 if (VIsPoisonShuffle)
2167 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2176 for (
unsigned j = 0; j != InitElts; ++j)
2178 Args.resize(ResElts, -1);
2179 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2182 for (
unsigned j = 0; j != CurIdx; ++j)
2184 for (
unsigned j = 0; j != InitElts; ++j)
2185 Args.push_back(j + Offset);
2186 Args.resize(ResElts, -1);
2193 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2194 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2200 llvm::Type *EltTy = VType->getElementType();
2203 for (; CurIdx < ResElts; ++CurIdx) {
2204 Value *Idx = Builder.getInt32(CurIdx);
2205 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2206 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2214 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2224 if (ICE->isGLValue())
2238 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2242 bool Ignored = TestAndClearIgnoreResultAssign();
2248 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2249 case CK_BuiltinFnToFnPtr:
2250 llvm_unreachable(
"builtin functions are handled elsewhere");
2252 case CK_LValueBitCast:
2253 case CK_ObjCObjectLValueCast: {
2254 Address Addr = EmitLValue(
E).getAddress();
2257 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2260 case CK_LValueToRValueBitCast: {
2266 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2269 case CK_CPointerToObjCPointerCast:
2270 case CK_BlockPointerToObjCPointerCast:
2271 case CK_AnyPointerToBlockPointerCast:
2274 llvm::Type *SrcTy = Src->
getType();
2275 llvm::Type *DstTy = ConvertType(DestTy);
2277 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2278 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2279 "Address-space cast must be used to convert address spaces");
2281 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2284 PT->getPointeeType(),
2300 Src = Builder.CreateLaunderInvariantGroup(Src);
2308 Src = Builder.CreateStripInvariantGroup(Src);
2313 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2314 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2315 !isa<CastExpr>(
E)) {
2317 if (!PointeeType.
isNull())
2326 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2327 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2330 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2331 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2332 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2333 ScalableDstTy = llvm::ScalableVectorType::get(
2334 FixedSrcTy->getElementType(),
2335 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2337 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2338 llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2339 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2340 llvm::Value *
Result = Builder.CreateInsertVector(
2341 ScalableDstTy, UndefVec, Src, Zero,
"cast.scalable");
2342 if (
Result->getType() != DstTy)
2352 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2353 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2356 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2357 ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2358 FixedDstTy->getElementType()->isIntegerTy(8)) {
2359 ScalableSrcTy = llvm::ScalableVectorType::get(
2360 FixedDstTy->getElementType(),
2361 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2362 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2364 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2365 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2366 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2377 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2378 isa<llvm::ScalableVectorType>(DstTy)) ||
2379 (isa<llvm::ScalableVectorType>(SrcTy) &&
2380 isa<llvm::FixedVectorType>(DstTy))) {
2387 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2390 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2393 case CK_AddressSpaceConversion: {
2396 Result.Val.isNullPointer()) {
2400 if (
Result.HasSideEffects)
2403 ConvertType(DestTy)), DestTy);
2411 case CK_AtomicToNonAtomic:
2412 case CK_NonAtomicToAtomic:
2413 case CK_UserDefinedConversion:
2414 return Visit(
const_cast<Expr*
>(
E));
2418 : Visit(const_cast<
Expr *>(
E));
2421 case CK_BaseToDerived: {
2423 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2437 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2445 case CK_UncheckedDerivedToBase:
2446 case CK_DerivedToBase: {
2459 case CK_ArrayToPointerDecay:
2462 case CK_FunctionToPointerDecay:
2463 return EmitLValue(
E).getPointer(CGF);
2465 case CK_NullToPointer:
2466 if (MustVisitNullValue(
E))
2472 case CK_NullToMemberPointer: {
2473 if (MustVisitNullValue(
E))
2480 case CK_ReinterpretMemberPointer:
2481 case CK_BaseToDerivedMemberPointer:
2482 case CK_DerivedToBaseMemberPointer: {
2494 case CK_ARCProduceObject:
2496 case CK_ARCConsumeObject:
2498 case CK_ARCReclaimReturnedObject:
2500 case CK_ARCExtendBlockObject:
2503 case CK_CopyAndAutoreleaseBlockObject:
2506 case CK_FloatingRealToComplex:
2507 case CK_FloatingComplexCast:
2508 case CK_IntegralRealToComplex:
2509 case CK_IntegralComplexCast:
2510 case CK_IntegralComplexToFloatingComplex:
2511 case CK_FloatingComplexToIntegralComplex:
2512 case CK_ConstructorConversion:
2514 case CK_HLSLArrayRValue:
2515 llvm_unreachable(
"scalar cast to non-scalar value");
2517 case CK_LValueToRValue:
2519 assert(
E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2520 return Visit(
const_cast<Expr*
>(
E));
2522 case CK_IntegralToPointer: {
2527 auto DestLLVMTy = ConvertType(DestTy);
2530 llvm::Value* IntResult =
2531 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2533 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2539 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2545 case CK_PointerToIntegral: {
2546 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2547 auto *PtrExpr = Visit(
E);
2555 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2559 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2565 case CK_MatrixCast: {
2566 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2569 case CK_VectorSplat: {
2570 llvm::Type *DstTy = ConvertType(DestTy);
2573 llvm::ElementCount NumElements =
2574 cast<llvm::VectorType>(DstTy)->getElementCount();
2575 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2578 case CK_FixedPointCast:
2579 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2582 case CK_FixedPointToBoolean:
2584 "Expected src type to be fixed point type");
2585 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2586 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2589 case CK_FixedPointToIntegral:
2591 "Expected src type to be fixed point type");
2592 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2593 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2596 case CK_IntegralToFixedPoint:
2598 "Expected src type to be an integer");
2600 "Expected dest type to be fixed point type");
2601 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2604 case CK_IntegralCast: {
2607 return Builder.CreateIntCast(Visit(
E), ConvertType(DestTy),
2611 ScalarConversionOpts Opts;
2612 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2613 if (!ICE->isPartOfExplicitCast())
2614 Opts = ScalarConversionOpts(CGF.
SanOpts);
2616 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2619 case CK_IntegralToFloating: {
2624 return Builder.CreateSIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2625 return Builder.CreateUIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2627 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2628 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2631 case CK_FloatingToIntegral: {
2636 return Builder.CreateFPToSI(Visit(
E), ConvertType(DestTy),
"conv");
2637 return Builder.CreateFPToUI(Visit(
E), ConvertType(DestTy),
"conv");
2639 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2640 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2643 case CK_FloatingCast: {
2650 return Builder.CreateFPTrunc(Visit(
E), ConvertType(DestTy),
"conv");
2651 return Builder.CreateFPExt(Visit(
E), ConvertType(DestTy),
"conv");
2653 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2654 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2657 case CK_FixedPointToFloating:
2658 case CK_FloatingToFixedPoint: {
2659 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2660 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2663 case CK_BooleanToSignedIntegral: {
2664 ScalarConversionOpts Opts;
2665 Opts.TreatBooleanAsSigned =
true;
2666 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2669 case CK_IntegralToBoolean:
2670 return EmitIntToBoolConversion(Visit(
E));
2671 case CK_PointerToBoolean:
2672 return EmitPointerToBoolConversion(Visit(
E),
E->
getType());
2673 case CK_FloatingToBoolean: {
2674 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2675 return EmitFloatToBoolConversion(Visit(
E));
2677 case CK_MemberPointerToBoolean: {
2678 llvm::Value *MemPtr = Visit(
E);
2683 case CK_FloatingComplexToReal:
2684 case CK_IntegralComplexToReal:
2687 case CK_FloatingComplexToBoolean:
2688 case CK_IntegralComplexToBoolean: {
2692 return EmitComplexToScalarConversion(
V,
E->
getType(), DestTy,
2696 case CK_ZeroToOCLOpaqueType: {
2699 "CK_ZeroToOCLEvent cast on non-event type");
2700 return llvm::Constant::getNullValue(ConvertType(DestTy));
2703 case CK_IntToOCLSampler:
2706 case CK_HLSLVectorTruncation: {
2707 assert(DestTy->
isVectorType() &&
"Expected dest type to be vector type");
2711 for (
unsigned I = 0; I != NumElts; ++I)
2714 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2719 llvm_unreachable(
"unknown scalar cast");
2723 CodeGenFunction::StmtExprEvaluation eval(CGF);
2733 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2734 Value *
V = Visit(
E->getSubExpr());
2737 Scope.ForceCleanup({&
V});
2746 llvm::Value *InVal,
bool IsInc,
2750 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2752 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2753 BinOp.FPFeatures = FPFeatures;
2758llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2760 llvm::Value *Amount =
2761 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2762 StringRef Name = IsInc ?
"inc" :
"dec";
2763 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2765 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2766 return Builder.CreateAdd(InVal, Amount, Name);
2769 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2770 return Builder.CreateNSWAdd(InVal, Amount, Name);
2773 if (!
E->canOverflow())
2774 return Builder.CreateNSWAdd(InVal, Amount, Name);
2778 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2803class OMPLastprivateConditionalUpdateRAII {
2812 ~OMPLastprivateConditionalUpdateRAII() {
2815 CGF,
E->getSubExpr());
2822 bool isInc,
bool isPre) {
2823 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF,
E);
2825 llvm::PHINode *atomicPHI =
nullptr;
2831 int amount = (isInc ? 1 : -1);
2832 bool isSubtraction = !isInc;
2835 type = atomicTy->getValueType();
2836 if (isInc &&
type->isBooleanType()) {
2840 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2841 return Builder.getTrue();
2845 return Builder.CreateAtomicRMW(
2847 llvm::AtomicOrdering::SequentiallyConsistent);
2852 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2853 !(
type->isUnsignedIntegerType() &&
2854 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2857 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2858 llvm::AtomicRMWInst::Sub;
2859 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2860 llvm::Instruction::Sub;
2862 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2864 Builder.CreateAtomicRMW(aop, LV.
getAddress(), amt,
2865 llvm::AtomicOrdering::SequentiallyConsistent);
2866 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2869 if (
type->isFloatingType()) {
2870 llvm::AtomicRMWInst::BinOp aop =
2871 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
2872 llvm::Instruction::BinaryOps op =
2873 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
2874 llvm::Value *amt = llvm::ConstantFP::get(
2875 VMContext, llvm::APFloat(
static_cast<float>(1.0)));
2876 llvm::AtomicRMWInst *old =
2878 llvm::AtomicOrdering::SequentiallyConsistent);
2880 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2885 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2888 Builder.CreateBr(opBB);
2889 Builder.SetInsertPoint(opBB);
2890 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2891 atomicPHI->addIncoming(value, startBB);
2905 if (isInc &&
type->isBooleanType()) {
2906 value = Builder.getTrue();
2909 }
else if (
type->isIntegerType()) {
2911 bool canPerformLossyDemotionCheck =
false;
2913 bool excludeOverflowPattern =
2918 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2919 canPerformLossyDemotionCheck =
true;
2920 canPerformLossyDemotionCheck &=
2923 canPerformLossyDemotionCheck &=
2925 type, promotedType);
2926 assert((!canPerformLossyDemotionCheck ||
2927 type->isSignedIntegerOrEnumerationType() ||
2929 ConvertType(
type)->getScalarSizeInBits() ==
2930 ConvertType(promotedType)->getScalarSizeInBits()) &&
2931 "The following check expects that if we do promotion to different "
2932 "underlying canonical type, at least one of the types (either "
2933 "base or promoted) will be signed, or the bitwidths will match.");
2936 SanitizerKind::ImplicitIntegerArithmeticValueChange |
2937 SanitizerKind::ImplicitBitfieldConversion) &&
2938 canPerformLossyDemotionCheck) {
2952 value = EmitScalarConversion(value,
type, promotedType,
E->
getExprLoc());
2953 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2954 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2958 ScalarConversionOpts Opts;
2960 Opts = ScalarConversionOpts(CGF.
SanOpts);
2961 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
2963 SrcType = promotedType;
2966 value = EmitScalarConversion(value, promotedType,
type,
E->
getExprLoc(),
2972 }
else if (
E->canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2973 value = EmitIncDecConsiderOverflowBehavior(
E, value, isInc);
2974 }
else if (
E->canOverflow() &&
type->isUnsignedIntegerType() &&
2975 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
2976 !excludeOverflowPattern) {
2980 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2981 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2992 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2995 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2998 elemTy, value, numElts,
false, isSubtraction,
3002 }
else if (
type->isFunctionType()) {
3003 llvm::Value *amt = Builder.getInt32(amount);
3006 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3010 false, isSubtraction,
3015 llvm::Value *amt = Builder.getInt32(amount);
3018 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3021 elemTy, value, amt,
false, isSubtraction,
3026 }
else if (
type->isVectorType()) {
3027 if (
type->hasIntegerRepresentation()) {
3028 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
3030 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3032 value = Builder.CreateFAdd(
3034 llvm::ConstantFP::get(value->getType(), amount),
3035 isInc ?
"inc" :
"dec");
3039 }
else if (
type->isRealFloatingType()) {
3042 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF,
E);
3047 value = Builder.CreateCall(
3050 input,
"incdec.conv");
3052 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3056 if (value->getType()->isFloatTy())
3057 amt = llvm::ConstantFP::get(VMContext,
3058 llvm::APFloat(
static_cast<float>(amount)));
3059 else if (value->getType()->isDoubleTy())
3060 amt = llvm::ConstantFP::get(VMContext,
3061 llvm::APFloat(
static_cast<double>(amount)));
3065 llvm::APFloat F(
static_cast<float>(amount));
3067 const llvm::fltSemantics *FS;
3070 if (value->getType()->isFP128Ty())
3072 else if (value->getType()->isHalfTy())
3074 else if (value->getType()->isBFloatTy())
3076 else if (value->getType()->isPPC_FP128Ty())
3080 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3081 amt = llvm::ConstantFP::get(VMContext, F);
3083 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3087 value = Builder.CreateCall(
3090 value,
"incdec.conv");
3092 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3097 }
else if (
type->isFixedPointType()) {
3104 Info.Opcode = isInc ? BO_Add : BO_Sub;
3106 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3109 if (
type->isSignedFixedPointType()) {
3110 Info.Opcode = isInc ? BO_Sub : BO_Add;
3111 Info.RHS = Builder.CreateNeg(Info.RHS);
3116 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3118 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3119 value = EmitFixedPointBinOp(Info);
3126 if (!isInc) size = -size;
3127 llvm::Value *sizeValue =
3128 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3131 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3134 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3136 value = Builder.CreateBitCast(value, input->getType());
3140 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3145 llvm::Value *
success = Pair.second;
3146 atomicPHI->addIncoming(old, curBlock);
3147 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3148 Builder.SetInsertPoint(contBB);
3149 return isPre ? value : input;
3163 return isPre ? value : input;
3170 ? getPromotionType(
E->getSubExpr()->
getType())
3172 Value *result = VisitPlus(
E, promotionTy);
3173 if (result && !promotionTy.
isNull())
3174 result = EmitUnPromotedValue(result,
E->
getType());
3181 TestAndClearIgnoreResultAssign();
3182 if (!PromotionType.
isNull())
3184 return Visit(
E->getSubExpr());
3190 ? getPromotionType(
E->getSubExpr()->
getType())
3192 Value *result = VisitMinus(
E, promotionTy);
3193 if (result && !promotionTy.
isNull())
3194 result = EmitUnPromotedValue(result,
E->
getType());
3200 TestAndClearIgnoreResultAssign();
3202 if (!PromotionType.
isNull())
3205 Op = Visit(
E->getSubExpr());
3208 if (Op->
getType()->isFPOrFPVectorTy())
3209 return Builder.CreateFNeg(Op,
"fneg");
3214 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3216 BinOp.Opcode = BO_Sub;
3219 return EmitSub(BinOp);
3223 TestAndClearIgnoreResultAssign();
3224 Value *Op = Visit(
E->getSubExpr());
3225 return Builder.CreateNot(Op,
"not");
3233 Value *Oper = Visit(
E->getSubExpr());
3236 if (Oper->
getType()->isFPOrFPVectorTy()) {
3237 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3239 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
3241 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
3242 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
3251 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3254 return Builder.CreateZExt(BoolVal, ConvertType(
E->
getType()),
"lnot.ext");
3262 return Builder.getInt(
Value);
3266 unsigned n =
E->getNumComponents();
3267 llvm::Type* ResultType = ConvertType(
E->
getType());
3268 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3270 for (
unsigned i = 0; i != n; ++i) {
3272 llvm::Value *Offset =
nullptr;
3279 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3286 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3290 Offset = Builder.CreateMul(Idx, ElemSize);
3304 Field != FieldEnd; ++Field, ++i) {
3305 if (*Field == MemberDecl)
3308 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3313 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3316 CurrentType = MemberDecl->
getType();
3321 llvm_unreachable(
"dependent __builtin_offsetof");
3337 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3339 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3351ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3353 QualType TypeToSize =
E->getTypeOfArgument();
3354 if (
auto Kind =
E->getKind();
3355 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3358 if (
E->isArgumentType()) {
3368 llvm::Value *size = VlaSize.
NumElts;
3372 if (!eltSize.
isOne())
3377 }
else if (
E->getKind() == UETT_OpenMPRequiredSimdAlign) {
3381 E->getTypeOfArgument()->getPointeeType()))
3383 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3384 }
else if (
E->getKind() == UETT_VectorElements) {
3385 auto *VecTy = cast<llvm::VectorType>(ConvertType(
E->getTypeOfArgument()));
3386 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3397 ? getPromotionType(
E->getSubExpr()->
getType())
3399 Value *result = VisitReal(
E, promotionTy);
3400 if (result && !promotionTy.
isNull())
3401 result = EmitUnPromotedValue(result,
E->
getType());
3407 Expr *Op =
E->getSubExpr();
3413 if (!PromotionType.
isNull()) {
3415 Op, IgnoreResultAssign,
true);
3418 return result.first;
3428 if (!PromotionType.
isNull())
3436 ? getPromotionType(
E->getSubExpr()->
getType())
3438 Value *result = VisitImag(
E, promotionTy);
3439 if (result && !promotionTy.
isNull())
3440 result = EmitUnPromotedValue(result,
E->
getType());
3446 Expr *Op =
E->getSubExpr();
3452 if (!PromotionType.
isNull()) {
3454 Op,
true, IgnoreResultAssign);
3457 return result.second;
3471 else if (!PromotionType.
isNull())
3475 if (!PromotionType.
isNull())
3476 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3477 return llvm::Constant::getNullValue(ConvertType(
E->
getType()));
3484Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3486 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3489Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3491 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3496 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
3498#define HANDLE_BINOP(OP) \
3500 return Emit##OP(EmitBinOps(BO, PromotionType));
3509 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
3512 return VisitImag(UO, PromotionType);
3514 return VisitReal(UO, PromotionType);
3516 return VisitMinus(UO, PromotionType);
3518 return VisitPlus(UO, PromotionType);
3523 auto result = Visit(
const_cast<Expr *
>(
E));
3525 if (!PromotionType.
isNull())
3526 return EmitPromotedValue(result, PromotionType);
3528 return EmitUnPromotedValue(result,
E->
getType());
3535 TestAndClearIgnoreResultAssign();
3539 if (!PromotionType.
isNull())
3540 Result.Ty = PromotionType;
3543 Result.Opcode =
E->getOpcode();
3549LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3551 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3556 if (
E->getComputationResultType()->isAnyComplexType())
3563 PromotionTypeCR = getPromotionType(
E->getComputationResultType());
3564 if (PromotionTypeCR.
isNull())
3565 PromotionTypeCR =
E->getComputationResultType();
3566 QualType PromotionTypeLHS = getPromotionType(
E->getComputationLHSType());
3568 if (!PromotionTypeRHS.
isNull())
3571 OpInfo.RHS = Visit(
E->getRHS());
3572 OpInfo.Ty = PromotionTypeCR;
3573 OpInfo.Opcode =
E->getOpcode();
3579 llvm::PHINode *atomicPHI =
nullptr;
3582 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3583 !(
type->isUnsignedIntegerType() &&
3584 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3587 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3588 llvm::Instruction::BinaryOps Op;
3589 switch (OpInfo.Opcode) {
3591 case BO_MulAssign:
case BO_DivAssign:
3597 AtomicOp = llvm::AtomicRMWInst::Add;
3598 Op = llvm::Instruction::Add;
3601 AtomicOp = llvm::AtomicRMWInst::Sub;
3602 Op = llvm::Instruction::Sub;
3605 AtomicOp = llvm::AtomicRMWInst::And;
3606 Op = llvm::Instruction::And;
3609 AtomicOp = llvm::AtomicRMWInst::Xor;
3610 Op = llvm::Instruction::Xor;
3613 AtomicOp = llvm::AtomicRMWInst::Or;
3614 Op = llvm::Instruction::Or;
3617 llvm_unreachable(
"Invalid compound assignment type");
3619 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3621 EmitScalarConversion(OpInfo.RHS,
E->getRHS()->
getType(), LHSTy,
3625 llvm::AtomicRMWInst *OldVal =
3630 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3636 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3638 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3640 Builder.CreateBr(opBB);
3641 Builder.SetInsertPoint(opBB);
3642 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3643 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3644 OpInfo.LHS = atomicPHI;
3647 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3649 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3651 if (!PromotionTypeLHS.
isNull())
3652 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3655 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3656 E->getComputationLHSType(),
Loc);
3671 ScalarConversionOpts(CGF.
SanOpts));
3674 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3678 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3679 llvm::Value *
success = Pair.second;
3680 atomicPHI->addIncoming(old, curBlock);
3681 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3682 Builder.SetInsertPoint(contBB);
3707 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3708 bool Ignore = TestAndClearIgnoreResultAssign();
3709 Value *RHS =
nullptr;
3710 LValue LHS = EmitCompoundAssignLValue(
E,
Func, RHS);
3728void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3729 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3732 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3733 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3734 SanitizerKind::IntegerDivideByZero));
3737 const auto *BO = cast<BinaryOperator>(Ops.E);
3738 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3739 Ops.Ty->hasSignedIntegerRepresentation() &&
3741 Ops.mayHaveIntegerOverflow()) {
3742 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3744 llvm::Value *IntMin =
3745 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3746 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3748 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3749 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3750 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3752 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3755 if (Checks.size() > 0)
3756 EmitBinOpCheck(Checks, Ops);
3759Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3761 CodeGenFunction::SanitizerScope SanScope(&CGF);
3762 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3763 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3764 Ops.Ty->isIntegerType() &&
3765 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3766 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3767 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3768 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3769 Ops.Ty->isRealFloatingType() &&
3770 Ops.mayHaveFloatDivisionByZero()) {
3771 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3772 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3773 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3778 if (Ops.Ty->isConstantMatrixType()) {
3779 llvm::MatrixBuilder MB(Builder);
3782 auto *BO = cast<BinaryOperator>(Ops.E);
3786 "first operand must be a matrix");
3788 "second operand must be an arithmetic type");
3789 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3790 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3791 Ops.Ty->hasUnsignedIntegerRepresentation());
3794 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3796 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3797 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3801 else if (Ops.isFixedPointOp())
3802 return EmitFixedPointBinOp(Ops);
3803 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3804 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3806 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3809Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3811 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3812 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3813 Ops.Ty->isIntegerType() &&
3814 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3815 CodeGenFunction::SanitizerScope SanScope(&CGF);
3816 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3817 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3820 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3821 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3823 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3826Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3831 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3832 switch (Ops.Opcode) {
3836 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3837 llvm::Intrinsic::uadd_with_overflow;
3838 OverflowKind = SanitizerHandler::AddOverflow;
3843 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3844 llvm::Intrinsic::usub_with_overflow;
3845 OverflowKind = SanitizerHandler::SubOverflow;
3850 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3851 llvm::Intrinsic::umul_with_overflow;
3852 OverflowKind = SanitizerHandler::MulOverflow;
3855 llvm_unreachable(
"Unsupported operation for overflow detection");
3861 CodeGenFunction::SanitizerScope SanScope(&CGF);
3866 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3867 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3868 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3871 const std::string *handlerName =
3873 if (handlerName->empty()) {
3876 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3877 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3879 : SanitizerKind::UnsignedIntegerOverflow;
3880 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3882 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3887 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3888 llvm::BasicBlock *continueBB =
3892 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3896 Builder.SetInsertPoint(overflowBB);
3899 llvm::Type *Int8Ty = CGF.
Int8Ty;
3900 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3901 llvm::FunctionType *handlerTy =
3902 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3903 llvm::FunctionCallee handler =
3908 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3909 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3913 llvm::Value *handlerArgs[] = {
3916 Builder.getInt8(OpID),
3917 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3919 llvm::Value *handlerResult =
3923 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3924 Builder.CreateBr(continueBB);
3926 Builder.SetInsertPoint(continueBB);
3927 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3928 phi->addIncoming(result, initialBB);
3929 phi->addIncoming(handlerResult, overflowBB);
3936 const BinOpInfo &op,
3937 bool isSubtraction) {
3942 Value *pointer = op.LHS;
3943 Expr *pointerOperand =
expr->getLHS();
3944 Value *index = op.RHS;
3945 Expr *indexOperand =
expr->getRHS();
3948 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3949 std::swap(pointer, index);
3950 std::swap(pointerOperand, indexOperand);
3955 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3957 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3982 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3985 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3991 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3993 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
4003 llvm::Value *objectSize
4006 index = CGF.
Builder.CreateMul(index, objectSize);
4025 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
4028 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
4030 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4049 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4060 bool negMul,
bool negAdd) {
4061 Value *MulOp0 = MulOp->getOperand(0);
4062 Value *MulOp1 = MulOp->getOperand(1);
4064 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4066 Addend = Builder.CreateFNeg(Addend,
"neg");
4068 Value *FMulAdd =
nullptr;
4069 if (Builder.getIsFPConstrained()) {
4070 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4071 "Only constrained operation should be created when Builder is in FP "
4072 "constrained mode");
4073 FMulAdd = Builder.CreateConstrainedFPCall(
4074 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4076 {MulOp0, MulOp1, Addend});
4078 FMulAdd = Builder.CreateCall(
4080 {MulOp0, MulOp1, Addend});
4082 MulOp->eraseFromParent();
4097 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4098 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4099 "Only fadd/fsub can be the root of an fmuladd.");
4102 if (!op.FPFeatures.allowFPContractWithinStatement())
4105 Value *LHS = op.LHS;
4106 Value *RHS = op.RHS;
4110 bool NegLHS =
false;
4111 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4112 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4113 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4114 LHS = LHSUnOp->getOperand(0);
4119 bool NegRHS =
false;
4120 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4121 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4122 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4123 RHS = RHSUnOp->getOperand(0);
4131 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4132 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4133 (LHSBinOp->use_empty() || NegLHS)) {
4136 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4137 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4140 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4141 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4142 (RHSBinOp->use_empty() || NegRHS)) {
4145 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4146 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4150 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4151 if (LHSBinOp->getIntrinsicID() ==
4152 llvm::Intrinsic::experimental_constrained_fmul &&
4153 (LHSBinOp->use_empty() || NegLHS)) {
4156 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4157 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4160 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4161 if (RHSBinOp->getIntrinsicID() ==
4162 llvm::Intrinsic::experimental_constrained_fmul &&
4163 (RHSBinOp->use_empty() || NegRHS)) {
4166 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4167 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4174Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4175 if (op.LHS->getType()->isPointerTy() ||
4176 op.RHS->getType()->isPointerTy())
4179 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4180 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4182 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4183 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4186 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4187 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4190 if (CanElideOverflowCheck(CGF.
getContext(), op))
4191 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4192 return EmitOverflowCheckedBinOp(op);
4197 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4198 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4204 if (op.Ty->isConstantMatrixType()) {
4205 llvm::MatrixBuilder MB(Builder);
4206 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4207 return MB.CreateAdd(op.LHS, op.RHS);
4210 if (op.Ty->isUnsignedIntegerType() &&
4211 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4212 !CanElideOverflowCheck(CGF.
getContext(), op))
4213 return EmitOverflowCheckedBinOp(op);
4215 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4216 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4217 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4220 if (op.isFixedPointOp())
4221 return EmitFixedPointBinOp(op);
4223 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4228Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4230 using llvm::ConstantInt;
4238 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4239 RHSTy = BinOp->getRHS()->getType();
4240 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4245 LHSTy = CAO->getComputationLHSType();
4246 ResultTy = CAO->getComputationResultType();
4248 LHSTy = BinOp->getLHS()->getType();
4249 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4250 LHSTy = UnOp->getSubExpr()->getType();
4251 RHSTy = UnOp->getSubExpr()->getType();
4254 Value *LHS = op.LHS;
4255 Value *RHS = op.RHS;
4260 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4264 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4265 switch (op.Opcode) {
4268 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4272 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4276 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4280 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4284 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4288 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4291 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4293 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4295 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4297 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4302 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4304 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4308 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4321 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4327 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4332Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4334 if (!op.LHS->getType()->isPointerTy()) {
4335 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4336 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4338 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4339 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4342 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4343 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4346 if (CanElideOverflowCheck(CGF.
getContext(), op))
4347 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4348 return EmitOverflowCheckedBinOp(op);
4353 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4354 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4360 if (op.Ty->isConstantMatrixType()) {
4361 llvm::MatrixBuilder MB(Builder);
4362 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4363 return MB.CreateSub(op.LHS, op.RHS);
4366 if (op.Ty->isUnsignedIntegerType() &&
4367 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4368 !CanElideOverflowCheck(CGF.
getContext(), op))
4369 return EmitOverflowCheckedBinOp(op);
4371 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4372 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4373 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4376 if (op.isFixedPointOp())
4377 return EmitFixedPointBinOp(op);
4379 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4384 if (!op.RHS->getType()->isPointerTy())
4391 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4393 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4394 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4398 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4400 llvm::Value *divisor =
nullptr;
4406 elementType = VlaSize.Type;
4407 divisor = VlaSize.NumElts;
4411 if (!eltSize.
isOne())
4427 if (elementSize.
isOne())
4436 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4439Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4441 llvm::IntegerType *Ty;
4442 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4443 Ty = cast<llvm::IntegerType>(VT->getElementType());
4445 Ty = cast<llvm::IntegerType>(LHS->
getType());
4450 llvm::Type *RHSTy = RHS->
getType();
4451 llvm::APInt RHSMax =
4452 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4453 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4454 if (RHSMax.ult(Ty->getBitWidth()))
4455 return llvm::ConstantInt::get(RHSTy, RHSMax);
4456 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4460 const Twine &Name) {
4461 llvm::IntegerType *Ty;
4462 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4463 Ty = cast<llvm::IntegerType>(VT->getElementType());
4465 Ty = cast<llvm::IntegerType>(LHS->
getType());
4467 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4468 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4470 return Builder.CreateURem(
4471 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4474Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4476 if (Ops.isFixedPointOp())
4477 return EmitFixedPointBinOp(Ops);
4481 Value *RHS = Ops.RHS;
4482 if (Ops.LHS->getType() != RHS->
getType())
4483 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4485 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4486 Ops.Ty->hasSignedIntegerRepresentation() &&
4489 bool SanitizeUnsignedBase =
4490 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4491 Ops.Ty->hasUnsignedIntegerRepresentation();
4492 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4493 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4496 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4497 else if ((SanitizeBase || SanitizeExponent) &&
4498 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4499 CodeGenFunction::SanitizerScope SanScope(&CGF);
4501 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4502 llvm::Value *WidthMinusOne =
4503 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4504 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4506 if (SanitizeExponent) {
4508 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4515 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4518 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4519 llvm::Value *PromotedWidthMinusOne =
4520 (RHS == Ops.RHS) ? WidthMinusOne
4521 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4523 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4524 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4527 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4533 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4534 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4536 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4537 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4539 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4540 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4541 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4542 Checks.push_back(std::make_pair(
4543 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4544 : SanitizerKind::UnsignedShiftBase));
4547 assert(!Checks.empty());
4548 EmitBinOpCheck(Checks, Ops);
4551 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4554Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4556 if (Ops.isFixedPointOp())
4557 return EmitFixedPointBinOp(Ops);
4561 Value *RHS = Ops.RHS;
4562 if (Ops.LHS->getType() != RHS->
getType())
4563 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4567 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4568 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4569 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4570 CodeGenFunction::SanitizerScope SanScope(&CGF);
4571 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4572 llvm::Value *Valid = Builder.CreateICmpULE(
4573 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4574 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4577 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4578 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4579 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4587 default: llvm_unreachable(
"unexpected element type");
4588 case BuiltinType::Char_U:
4589 case BuiltinType::UChar:
4590 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4591 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4592 case BuiltinType::Char_S:
4593 case BuiltinType::SChar:
4594 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4595 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4596 case BuiltinType::UShort:
4597 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4598 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4599 case BuiltinType::Short:
4600 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4601 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4602 case BuiltinType::UInt:
4603 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4604 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4605 case BuiltinType::Int:
4606 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4607 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4608 case BuiltinType::ULong:
4609 case BuiltinType::ULongLong:
4610 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4611 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4612 case BuiltinType::Long:
4613 case BuiltinType::LongLong:
4614 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4615 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4616 case BuiltinType::Float:
4617 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4618 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4619 case BuiltinType::Double:
4620 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4621 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4622 case BuiltinType::UInt128:
4623 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4624 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4625 case BuiltinType::Int128:
4626 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4627 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4632 llvm::CmpInst::Predicate UICmpOpc,
4633 llvm::CmpInst::Predicate SICmpOpc,
4634 llvm::CmpInst::Predicate FCmpOpc,
4636 TestAndClearIgnoreResultAssign();
4641 assert(
E->getOpcode() == BO_EQ ||
4642 E->getOpcode() == BO_NE);
4646 CGF, LHS, RHS, MPT,
E->getOpcode() == BO_NE);
4648 BinOpInfo BOInfo = EmitBinOps(
E);
4649 Value *LHS = BOInfo.LHS;
4650 Value *RHS = BOInfo.RHS;
4656 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4658 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4661 Value *FirstVecArg = LHS,
4662 *SecondVecArg = RHS;
4667 switch(
E->getOpcode()) {
4668 default: llvm_unreachable(
"is not a comparison operation");
4680 std::swap(FirstVecArg, SecondVecArg);
4687 if (ElementKind == BuiltinType::Float) {
4689 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4690 std::swap(FirstVecArg, SecondVecArg);
4698 if (ElementKind == BuiltinType::Float) {
4700 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4705 std::swap(FirstVecArg, SecondVecArg);
4710 Value *CR6Param = Builder.getInt32(CR6);
4712 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4719 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4720 if (ResultTy->getBitWidth() > 1 &&
4722 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4727 if (BOInfo.isFixedPointOp()) {
4728 Result = EmitFixedPointBinOp(BOInfo);
4729 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4730 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4732 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4734 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4736 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4741 !isa<llvm::ConstantPointerNull>(LHS) &&
4742 !isa<llvm::ConstantPointerNull>(RHS)) {
4751 LHS = Builder.CreateStripInvariantGroup(LHS);
4753 RHS = Builder.CreateStripInvariantGroup(RHS);
4756 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4762 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
4770 CETy = CTy->getElementType();
4772 LHS.first = Visit(
E->getLHS());
4773 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4779 CTy->getElementType()) &&
4780 "The element types must always match.");
4783 RHS.first = Visit(
E->getRHS());
4784 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4786 "The element types must always match.");
4789 Value *ResultR, *ResultI;
4793 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4794 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4798 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4799 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4802 if (
E->getOpcode() == BO_EQ) {
4803 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4805 assert(
E->getOpcode() == BO_NE &&
4806 "Complex comparison other than == or != ?");
4807 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4819 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E->getRHS())) {
4821 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4822 *SrcType = ICE->getSubExpr()->getType();
4834 bool Ignore = TestAndClearIgnoreResultAssign();
4853 RHS = Visit(
E->getRHS());
4869 RHS = Visit(
E->getRHS());
4912 Value *LHS = Visit(
E->getLHS());
4913 Value *RHS = Visit(
E->getRHS());
4915 if (LHS->
getType()->isFPOrFPVectorTy()) {
4916 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4918 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4919 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4921 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4922 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4924 Value *
And = Builder.CreateAnd(LHS, RHS);
4925 return Builder.CreateSExt(
And, ConvertType(
E->
getType()),
"sext");
4929 llvm::Type *ResTy = ConvertType(
E->
getType());
4950 if (InstrumentRegions &&
4955 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4968 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4973 return llvm::Constant::getNullValue(ResTy);
4985 CodeGenFunction::ConditionalEvaluation eval(CGF);
4994 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4996 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4998 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5007 RHSBlock = Builder.GetInsertBlock();
5012 if (InstrumentRegions &&
5016 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5020 PN->addIncoming(RHSCond, RHSBlockCnt);
5030 PN->addIncoming(RHSCond, RHSBlock);
5040 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5044 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5052 Value *LHS = Visit(
E->getLHS());
5053 Value *RHS = Visit(
E->getRHS());
5055 if (LHS->
getType()->isFPOrFPVectorTy()) {
5056 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5058 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
5059 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
5061 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
5062 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
5064 Value *
Or = Builder.CreateOr(LHS, RHS);
5065 return Builder.CreateSExt(
Or, ConvertType(
E->
getType()),
"sext");
5069 llvm::Type *ResTy = ConvertType(
E->
getType());
5090 if (InstrumentRegions &&
5095 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5108 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5113 return llvm::ConstantInt::get(ResTy, 1);
5125 CodeGenFunction::ConditionalEvaluation eval(CGF);
5135 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5137 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5139 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5151 RHSBlock = Builder.GetInsertBlock();
5156 if (InstrumentRegions &&
5160 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5164 PN->addIncoming(RHSCond, RHSBlockCnt);
5170 PN->addIncoming(RHSCond, RHSBlock);
5178 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5184 return Visit(
E->getRHS());
5209Value *ScalarExprEmitter::
5211 TestAndClearIgnoreResultAssign();
5214 CodeGenFunction::OpaqueValueMapping binding(CGF,
E);
5216 Expr *condExpr =
E->getCond();
5217 Expr *lhsExpr =
E->getTrueExpr();
5218 Expr *rhsExpr =
E->getFalseExpr();
5224 Expr *live = lhsExpr, *dead = rhsExpr;
5225 if (!CondExprBool) std::swap(live, dead);
5255 llvm::Value *LHS = Visit(lhsExpr);
5256 llvm::Value *RHS = Visit(rhsExpr);
5258 llvm::Type *condType = ConvertType(condExpr->
getType());
5259 auto *vecTy = cast<llvm::FixedVectorType>(condType);
5261 unsigned numElem = vecTy->getNumElements();
5262 llvm::Type *elemType = vecTy->getElementType();
5264 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5265 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5266 llvm::Value *tmp = Builder.CreateSExt(
5267 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5268 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5271 llvm::Value *RHSTmp = RHS;
5272 llvm::Value *LHSTmp = LHS;
5273 bool wasCast =
false;
5274 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
5275 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5276 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5277 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5281 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5282 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5283 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5285 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5295 llvm::Value *LHS = Visit(lhsExpr);
5296 llvm::Value *RHS = Visit(rhsExpr);
5298 llvm::Type *CondType = ConvertType(condExpr->
getType());
5299 auto *VecTy = cast<llvm::VectorType>(CondType);
5300 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5302 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5303 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5312 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5321 llvm::Value *LHS = Visit(lhsExpr);
5322 llvm::Value *RHS = Visit(rhsExpr);
5325 assert(!RHS &&
"LHS and RHS types must match");
5328 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5339 CodeGenFunction::ConditionalEvaluation eval(CGF);
5357 Value *LHS = Visit(lhsExpr);
5360 LHSBlock = Builder.GetInsertBlock();
5361 Builder.CreateBr(ContBlock);
5375 Value *RHS = Visit(rhsExpr);
5378 RHSBlock = Builder.GetInsertBlock();
5388 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5389 PN->addIncoming(LHS, LHSBlock);
5390 PN->addIncoming(RHS, RHSBlock);
5401 return Visit(
E->getChosenSubExpr());
5416Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5422 Value *Src,
unsigned NumElementsDst) {
5423 static constexpr int Mask[] = {0, 1, 2, -1};
5424 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5444 const llvm::DataLayout &DL,
5445 Value *Src, llvm::Type *DstTy,
5446 StringRef Name =
"") {
5450 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5451 return Builder.CreateBitCast(Src, DstTy, Name);
5454 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5455 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5458 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5460 if (!DstTy->isIntegerTy())
5461 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5463 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5467 if (!SrcTy->isIntegerTy())
5468 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5470 return Builder.CreateIntToPtr(Src, DstTy, Name);
5475 llvm::Type *DstTy = ConvertType(
E->
getType());
5477 llvm::Type *SrcTy = Src->
getType();
5478 unsigned NumElementsSrc =
5479 isa<llvm::VectorType>(SrcTy)
5480 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5482 unsigned NumElementsDst =
5483 isa<llvm::VectorType>(DstTy)
5484 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5493 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5498 Src->setName(
"astype");
5505 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5506 auto *Vec4Ty = llvm::FixedVectorType::get(
5507 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5512 Src->setName(
"astype");
5517 Src, DstTy,
"astype");
5532 "Invalid scalar expression to emit");
5534 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5535 .Visit(
const_cast<Expr *
>(
E));
5544 "Invalid scalar expression to emit");
5545 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy,
Loc);
5555 "Invalid complex -> scalar conversion");
5556 return ScalarExprEmitter(*
this)
5557 .EmitComplexToScalarConversion(Src, SrcTy, DstTy,
Loc);
5564 if (!PromotionType.
isNull())
5565 return ScalarExprEmitter(*this).EmitPromoted(
E, PromotionType);
5567 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(
E));
5573 bool isInc,
bool isPre) {
5574 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(
E, LV, isInc, isPre);
5581 Expr *BaseExpr =
E->getBase();
5584 llvm::Type *BaseTy =
5599 ScalarExprEmitter
Scalar(*
this);
5601 switch (
E->getOpcode()) {
5602#define COMPOUND_OP(Op) \
5603 case BO_##Op##Assign: \
5604 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5641 llvm_unreachable(
"Not valid compound assignment operators");
5644 llvm_unreachable(
"Unhandled compound assignment operator");
5659 llvm::LLVMContext &VMContext,
5665 llvm::Value *TotalOffset =
nullptr;
5668 if (isa<llvm::Constant>(GEPVal)) {
5671 Value *BasePtr_int =
5672 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5674 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5675 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5676 return {TotalOffset, Builder.getFalse()};
5679 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5680 assert(GEP->getPointerOperand() == BasePtr &&
5681 "BasePtr must be the base of the GEP.");
5682 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5684 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5687 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5688 auto *SAddIntrinsic =
5689 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5690 auto *SMulIntrinsic =
5691 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5694 llvm::Value *OffsetOverflows = Builder.getFalse();
5698 llvm::Value *RHS) -> llvm::Value * {
5699 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
5702 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5703 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5705 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5708 OffsetOverflows = Builder.getTrue();
5709 return llvm::ConstantInt::get(VMContext, N);
5714 auto *ResultAndOverflow = Builder.CreateCall(
5715 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5716 OffsetOverflows = Builder.CreateOr(
5717 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5718 return Builder.CreateExtractValue(ResultAndOverflow, 0);
5722 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5723 GTI != GTE; ++GTI) {
5724 llvm::Value *LocalOffset;
5725 auto *Index = GTI.getOperand();
5727 if (
auto *STy = GTI.getStructTypeOrNull()) {
5730 unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5731 LocalOffset = llvm::ConstantInt::get(
5732 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5737 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5738 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
5739 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5744 if (!TotalOffset || TotalOffset == Zero)
5745 TotalOffset = LocalOffset;
5747 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5750 return {TotalOffset, OffsetOverflows};
5756 bool SignedIndices,
bool IsSubtraction,
5758 llvm::Type *PtrTy = Ptr->
getType();
5762 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5766 bool PerformNullCheck = !NullPointerIsDefined(
5767 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5770 bool PerformOverflowCheck =
5771 !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5773 if (!(PerformNullCheck || PerformOverflowCheck))
5778 SanitizerScope SanScope(
this);
5779 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
5784 assert((!isa<llvm::Constant>(EvaluatedGEP.
TotalOffset) ||
5786 "If the offset got constant-folded, we don't expect that there was an "
5789 auto *
Zero = llvm::ConstantInt::getNullValue(
IntPtrTy);
5803 if (PerformNullCheck) {
5815 auto *BaseIsNotNullptr =
Builder.CreateIsNotNull(Ptr);
5816 auto *ResultIsNotNullptr =
Builder.CreateIsNotNull(ComputedGEP);
5819 ?
Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5820 :
Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5821 Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5824 if (PerformOverflowCheck) {
5829 llvm::Value *ValidGEP;
5831 if (SignedIndices) {
5837 auto *PosOrZeroValid =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5838 auto *PosOrZeroOffset =
5840 llvm::Value *NegValid =
Builder.CreateICmpULT(ComputedGEP, IntPtr);
5842 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5848 ValidGEP =
Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5854 ValidGEP =
Builder.CreateICmpULE(ComputedGEP, IntPtr);
5856 ValidGEP =
Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5857 Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5860 assert(!Checks.empty() &&
"Should have produced some checks.");
5864 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5865 EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
5873 const Twine &Name) {
5874 if (!
SanOpts.
has(SanitizerKind::PointerOverflow))
5880 elementType, Align);
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
CodeGenFunction::ComplexPairTy ComplexPairTy
#define VISITCOMP(CODE, UI, SI, FP, SIG)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static Value * emitPointerArithmetic(CodeGenFunction &CGF, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
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 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 std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
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 isCheapEnoughToEvaluateUnconditionally(const Expr *E, CodeGenFunction &CGF)
isCheapEnoughToEvaluateUnconditionally - Return true if the specified expression is cheap enough and ...
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
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 std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerMask > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
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
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
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.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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.
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const 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.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
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())
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
SanitizerSet SanOpts
Sanitizers enabled for this function.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
static bool hasScalarEvaluationKind(QualType T)
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
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.
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.
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
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.
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
@ 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.
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
const TargetInfo & getTarget() const
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
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...
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
CGDebugInfo * getDebugInfo()
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
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)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
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.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
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...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
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.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
void maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
llvm::Type * ConvertType(QualType T)
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)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
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 * 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 * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
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...
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot())
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
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...
RValue EmitAtomicExpr(AtomicExpr *E)
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.
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.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
const LangOptions & getLangOpts() const
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::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::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
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)
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)
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, LangAS DestAddr, 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,...
@ 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...
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
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.
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).
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.
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.
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
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 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 ...
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 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 isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
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 * 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),...
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 Zero(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.