30#include "llvm/ADT/APFixedPoint.h"
31#include "llvm/IR/CFG.h"
32#include "llvm/IR/Constants.h"
33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/DerivedTypes.h"
35#include "llvm/IR/FixedPointBuilder.h"
36#include "llvm/IR/Function.h"
37#include "llvm/IR/GetElementPtrTypeIterator.h"
38#include "llvm/IR/GlobalVariable.h"
39#include "llvm/IR/Intrinsics.h"
40#include "llvm/IR/IntrinsicsPowerPC.h"
41#include "llvm/IR/MatrixBuilder.h"
42#include "llvm/IR/Module.h"
43#include "llvm/Support/TypeSize.h"
48using namespace CodeGen;
62bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
64 llvm::APInt &Result) {
67 const auto &LHSAP = LHS->getValue();
68 const auto &RHSAP = RHS->getValue();
69 if (Opcode == BO_Add) {
70 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
71 : LHSAP.uadd_ov(RHSAP, Overflow);
72 }
else if (Opcode == BO_Sub) {
73 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
74 : LHSAP.usub_ov(RHSAP, Overflow);
75 }
else if (Opcode == BO_Mul) {
76 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
77 : LHSAP.umul_ov(RHSAP, Overflow);
78 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
79 if (
Signed && !RHS->isZero())
80 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
96 bool mayHaveIntegerOverflow()
const {
98 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
99 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
100 if (!LHSCI || !RHSCI)
104 return ::mayHaveIntegerOverflow(
109 bool isDivremOp()
const {
115 bool mayHaveIntegerDivisionByZero()
const {
117 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
123 bool mayHaveFloatDivisionByZero()
const {
125 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
126 return CFP->isZero();
133 bool isFixedPointOp()
const {
136 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
137 QualType LHSType = BinOp->getLHS()->getType();
138 QualType RHSType = BinOp->getRHS()->getType();
141 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
142 return UnOp->getSubExpr()->getType()->isFixedPointType();
147static bool MustVisitNullValue(
const Expr *E) {
155static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
170static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
171 return getUnwidenedIntegerType(Ctx, E).has_value();
175static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
176 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
177 "Expected a unary or binary operator");
181 if (!Op.mayHaveIntegerOverflow())
185 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
186 return !UO->canOverflow();
190 const auto *BO = cast<BinaryOperator>(Op.E);
191 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
195 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
204 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
210 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
211 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
215class ScalarExprEmitter
219 bool IgnoreResultAssign;
220 llvm::LLVMContext &VMContext;
224 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
225 VMContext(cgf.getLLVMContext()) {
232 bool TestAndClearIgnoreResultAssign() {
233 bool I = IgnoreResultAssign;
234 IgnoreResultAssign =
false;
240 LValue EmitCheckedLValue(
const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
244 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
245 const BinOpInfo &Info);
251 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
252 const AlignValueAttr *AVAttr =
nullptr;
253 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
257 if (
const auto *TTy =
259 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
266 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
269 AVAttr = VD->
getAttr<AlignValueAttr>();
275 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
281 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
289 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
292 EmitLValueAlignmentAssumption(E,
V);
302 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
308 enum ImplicitConversionCheckKind :
unsigned char {
309 ICCK_IntegerTruncation = 0,
310 ICCK_UnsignedIntegerTruncation = 1,
311 ICCK_SignedIntegerTruncation = 2,
312 ICCK_IntegerSignChange = 3,
313 ICCK_SignedIntegerTruncationOrSignChange = 4,
329 struct ScalarConversionOpts {
330 bool TreatBooleanAsSigned;
331 bool EmitImplicitIntegerTruncationChecks;
332 bool EmitImplicitIntegerSignChangeChecks;
334 ScalarConversionOpts()
335 : TreatBooleanAsSigned(
false),
336 EmitImplicitIntegerTruncationChecks(
false),
337 EmitImplicitIntegerSignChangeChecks(
false) {}
340 : TreatBooleanAsSigned(
false),
341 EmitImplicitIntegerTruncationChecks(
343 EmitImplicitIntegerSignChangeChecks(
347 llvm::Type *SrcTy, llvm::Type *DstTy,
348 ScalarConversionOpts Opts);
352 ScalarConversionOpts Opts = ScalarConversionOpts());
361 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
371 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
372 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
379 return Builder.CreateICmpNE(
V, Zero,
"tobool");
386 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
387 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
388 Value *Result = ZI->getOperand(0);
393 ZI->eraseFromParent();
398 return Builder.CreateIsNotNull(
V,
"tobool");
412 llvm_unreachable(
"Stmt can't have complex result type!");
438 return Visit(
GE->getResultExpr());
452 return Builder.getInt(E->
getValue());
455 return Builder.getInt(E->
getValue());
458 return llvm::ConstantFP::get(VMContext, E->
getValue());
461 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
464 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
467 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
473 return EmitNullValue(E->
getType());
476 return EmitNullValue(E->
getType());
482 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
508 return EmitLoadOfLValue(E);
518 return EmitLoadOfLValue(E);
523 return EmitLoadOfLValue(E);
539 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
549 Value *VisitExtVectorElementExpr(
Expr *E) {
return EmitLoadOfLValue(E); }
556 return EmitLoadOfLValue(E);
563 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
568 return EmitNullValue(E->
getType());
572 return VisitCastExpr(E);
578 return EmitLoadOfLValue(E);
582 EmitLValueAlignmentAssumption(E,
V);
591 return EmitScalarPrePostIncDec(E, LV,
false,
false);
595 return EmitScalarPrePostIncDec(E, LV,
true,
false);
599 return EmitScalarPrePostIncDec(E, LV,
false,
true);
603 return EmitScalarPrePostIncDec(E, LV,
true,
true);
606 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
611 bool isInc,
bool isPre);
615 if (isa<MemberPointerType>(E->
getType()))
618 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
623 return EmitLoadOfLValue(E);
647 return EmitLoadOfLValue(E);
658 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
662 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
679 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
691 return llvm::ConstantInt::get(Builder.getInt32Ty(), E->
getValue());
695 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
709 return EmitNullValue(E->
getType());
718 return Builder.getInt1(E->
getValue());
722 Value *EmitMul(
const BinOpInfo &Ops) {
723 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
724 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
726 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
728 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
729 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
732 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
733 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
734 return EmitOverflowCheckedBinOp(Ops);
738 if (Ops.Ty->isConstantMatrixType()) {
739 llvm::MatrixBuilder MB(Builder);
742 auto *BO = cast<BinaryOperator>(Ops.E);
743 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
744 BO->getLHS()->getType().getCanonicalType());
745 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
746 BO->getRHS()->getType().getCanonicalType());
747 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
748 if (LHSMatTy && RHSMatTy)
749 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
750 LHSMatTy->getNumColumns(),
751 RHSMatTy->getNumColumns());
752 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
755 if (Ops.Ty->isUnsignedIntegerType() &&
756 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
757 !CanElideOverflowCheck(CGF.
getContext(), Ops))
758 return EmitOverflowCheckedBinOp(Ops);
760 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
762 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
763 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
765 if (Ops.isFixedPointOp())
766 return EmitFixedPointBinOp(Ops);
767 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
771 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
774 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
775 llvm::Value *Zero,
bool isDiv);
783 Value *EmitDiv(
const BinOpInfo &Ops);
784 Value *EmitRem(
const BinOpInfo &Ops);
785 Value *EmitAdd(
const BinOpInfo &Ops);
786 Value *EmitSub(
const BinOpInfo &Ops);
787 Value *EmitShl(
const BinOpInfo &Ops);
788 Value *EmitShr(
const BinOpInfo &Ops);
789 Value *EmitAnd(
const BinOpInfo &Ops) {
790 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
792 Value *EmitXor(
const BinOpInfo &Ops) {
793 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
795 Value *EmitOr (
const BinOpInfo &Ops) {
796 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
800 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
810 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
814 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
819 QualType ElementType = CT->getElementType();
826 unsigned NumElements = VT->getNumElements();
836#define HANDLEBINOP(OP) \
837 Value *VisitBin##OP(const BinaryOperator *E) { \
838 QualType promotionTy = getPromotionType(E->getType()); \
839 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
840 if (result && !promotionTy.isNull()) \
841 result = EmitUnPromotedValue(result, E->getType()); \
844 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
845 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
861 llvm::CmpInst::Predicate SICmpOpc,
862 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
863#define VISITCOMP(CODE, UI, SI, FP, SIG) \
864 Value *VisitBin##CODE(const BinaryOperator *E) { \
865 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
866 llvm::FCmpInst::FP, SIG); }
881 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
882 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
917 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
920 return EmitFloatToBoolConversion(Src);
926 "Unknown scalar type to convert");
928 if (isa<llvm::IntegerType>(Src->
getType()))
929 return EmitIntToBoolConversion(Src);
931 assert(isa<llvm::PointerType>(Src->
getType()));
932 return EmitPointerToBoolConversion(Src, SrcType);
935void ScalarExprEmitter::EmitFloatConversionCheck(
938 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
939 if (!isa<llvm::IntegerType>(DstTy))
942 CodeGenFunction::SanitizerScope SanScope(&CGF);
946 llvm::Value *Check =
nullptr;
947 const llvm::fltSemantics &SrcSema =
957 APFloat MinSrc(SrcSema, APFloat::uninitialized);
958 if (MinSrc.convertFromAPInt(Min, !
Unsigned, APFloat::rmTowardZero) &
962 MinSrc = APFloat::getInf(SrcSema,
true);
966 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
969 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
970 if (MaxSrc.convertFromAPInt(Max, !
Unsigned, APFloat::rmTowardZero) &
974 MaxSrc = APFloat::getInf(SrcSema,
false);
978 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
983 const llvm::fltSemantics &
Sema =
986 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
987 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
991 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
993 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
994 Check = Builder.CreateAnd(GE, LE);
999 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1000 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1005static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1006 std::pair<llvm::Value *, SanitizerMask>>
1009 llvm::Type *SrcTy = Src->
getType();
1010 llvm::Type *DstTy = Dst->
getType();
1015 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1016 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1017 "non-integer llvm type");
1024 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1026 if (!SrcSigned && !DstSigned) {
1027 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1028 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1030 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1031 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1034 llvm::Value *Check =
nullptr;
1036 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1038 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1040 return std::make_pair(Kind, std::make_pair(Check, Mask));
1048void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1060 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1061 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1063 if (SrcBits <= DstBits)
1066 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1073 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1074 (!SrcSigned && DstSigned))
1077 CodeGenFunction::SanitizerScope SanScope(&CGF);
1079 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1080 std::pair<llvm::Value *, SanitizerMask>>
1089 llvm::Constant *StaticArgs[] = {
1092 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
1093 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1099static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1100 std::pair<llvm::Value *, SanitizerMask>>
1103 llvm::Type *SrcTy = Src->
getType();
1104 llvm::Type *DstTy = Dst->
getType();
1106 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1107 "non-integer llvm type");
1113 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1114 unsigned DstBits = DstTy->getScalarSizeInBits();
1118 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1119 "either the widths should be different, or the signednesses.");
1123 const char *Name) ->
Value * {
1125 bool VSigned = VType->isSignedIntegerOrEnumerationType();
1126 llvm::Type *VTy =
V->getType();
1130 return llvm::ConstantInt::getFalse(VTy->getContext());
1133 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1136 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1137 llvm::Twine(Name) +
"." +
V->getName() +
1138 ".negativitycheck");
1142 llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType,
"src");
1144 llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType,
"dst");
1149 llvm::Value *Check =
nullptr;
1150 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1152 return std::make_pair(
1153 ScalarExprEmitter::ICCK_IntegerSignChange,
1154 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1157void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1160 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1163 llvm::Type *SrcTy = Src->
getType();
1164 llvm::Type *DstTy = Dst->
getType();
1174 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1175 unsigned DstBits = DstTy->getScalarSizeInBits();
1182 if (SrcSigned == DstSigned && SrcBits == DstBits)
1186 if (!SrcSigned && !DstSigned)
1191 if ((DstBits > SrcBits) && DstSigned)
1193 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1194 (SrcBits > DstBits) && SrcSigned) {
1202 CodeGenFunction::SanitizerScope SanScope(&CGF);
1204 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1205 std::pair<llvm::Value *, SanitizerMask>>
1209 ImplicitConversionCheckKind CheckKind;
1215 CheckKind = Check.first;
1216 Checks.emplace_back(Check.second);
1218 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1219 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1225 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1226 Checks.emplace_back(Check.second);
1230 llvm::Constant *StaticArgs[] = {
1233 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
1235 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1240 QualType DstType, llvm::Type *SrcTy,
1242 ScalarConversionOpts Opts) {
1244 llvm::Type *SrcElementTy;
1245 llvm::Type *DstElementTy;
1249 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1250 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1255 "cannot cast between matrix and non-matrix types");
1256 SrcElementTy = SrcTy;
1257 DstElementTy = DstTy;
1258 SrcElementType = SrcType;
1259 DstElementType = DstType;
1262 if (isa<llvm::IntegerType>(SrcElementTy)) {
1264 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1268 if (isa<llvm::IntegerType>(DstElementTy))
1269 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1271 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1272 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1275 if (isa<llvm::IntegerType>(DstElementTy)) {
1276 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1283 llvm::Intrinsic::ID IID =
1284 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1285 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1289 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1290 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1293 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1294 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1295 return Builder.CreateFPExt(Src, DstTy,
"conv");
1303 ScalarConversionOpts Opts) {
1318 return Builder.CreateIsNotNull(Src,
"tobool");
1321 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1324 "Unhandled scalar conversion from a fixed point type to another type.");
1328 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1331 "Unhandled scalar conversion to a fixed point type from another type.");
1334 QualType NoncanonicalSrcType = SrcType;
1335 QualType NoncanonicalDstType = DstType;
1339 if (SrcType == DstType)
return Src;
1343 llvm::Value *OrigSrc = Src;
1345 llvm::Type *SrcTy = Src->
getType();
1349 return EmitConversionToBool(Src, SrcType);
1351 llvm::Type *DstTy = ConvertType(DstType);
1356 if (DstTy->isFloatingPointTy()) {
1358 return Builder.CreateCall(
1366 Src = Builder.CreateCall(
1371 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1379 if (SrcTy == DstTy) {
1380 if (Opts.EmitImplicitIntegerSignChangeChecks)
1381 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1382 NoncanonicalDstType, Loc);
1390 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1392 if (isa<llvm::PointerType>(SrcTy))
1393 return Builder.CreateBitCast(Src, DstTy,
"conv");
1395 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1400 llvm::Value* IntResult =
1401 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1403 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1406 if (isa<llvm::PointerType>(SrcTy)) {
1408 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1409 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1418 "Splatted expr doesn't match with vector element type?");
1421 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1422 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1426 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1428 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1430 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1431 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1432 if (SrcSize == DstSize)
1433 return Builder.CreateBitCast(Src, DstTy,
"conv");
1442 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1443 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1446 assert(((SrcElementTy->isIntegerTy() &&
1447 DstElementTy->isIntegerTy()) ||
1448 (SrcElementTy->isFloatingPointTy() &&
1449 DstElementTy->isFloatingPointTy())) &&
1450 "unexpected conversion between a floating-point vector and an "
1454 if (SrcElementTy->isIntegerTy())
1455 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1458 if (SrcSize > DstSize)
1459 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1462 return Builder.CreateFPExt(Src, DstTy,
"conv");
1466 Value *Res =
nullptr;
1467 llvm::Type *ResTy = DstTy;
1474 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1476 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1482 if (SrcTy->isFloatingPointTy()) {
1486 return Builder.CreateCall(
1489 return Builder.CreateFPTrunc(Src, DstTy);
1494 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1496 if (DstTy != ResTy) {
1498 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1499 Res = Builder.CreateCall(
1503 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1507 if (Opts.EmitImplicitIntegerTruncationChecks)
1508 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1509 NoncanonicalDstType, Loc);
1511 if (Opts.EmitImplicitIntegerSignChangeChecks)
1512 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1513 NoncanonicalDstType, Loc);
1521 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1522 llvm::Value *Result;
1524 Result = FPBuilder.CreateFloatingToFixed(Src,
1527 Result = FPBuilder.CreateFixedToFloating(Src,
1529 ConvertType(DstTy));
1535 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1536 DstFPSema.getWidth(),
1537 DstFPSema.isSigned());
1539 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1542 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1549Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1558 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1559 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1560 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1567 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1578void ScalarExprEmitter::EmitBinOpCheck(
1579 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1591 if (UO && UO->
getOpcode() == UO_Minus) {
1592 Check = SanitizerHandler::NegateOverflow;
1594 DynamicData.push_back(Info.RHS);
1598 Check = SanitizerHandler::ShiftOutOfBounds;
1600 StaticData.push_back(
1602 StaticData.push_back(
1604 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1606 Check = SanitizerHandler::DivremOverflow;
1611 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1612 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1613 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1614 default: llvm_unreachable(
"unexpected opcode for bin op check");
1618 DynamicData.push_back(Info.LHS);
1619 DynamicData.push_back(Info.RHS);
1622 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1629Value *ScalarExprEmitter::VisitExpr(
Expr *E) {
1639 unsigned AddrSpace =
1641 llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1644 llvm::Type *ExprTy = ConvertType(E->
getType());
1645 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1656 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1657 unsigned LHSElts = LTy->getNumElements();
1661 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1665 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1666 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1674 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1675 MTy->getNumElements());
1676 Value* NewV = llvm::PoisonValue::get(RTy);
1677 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1678 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1679 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1681 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1682 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1694 if (Idx.isSigned() && Idx.isAllOnes())
1695 Indices.push_back(-1);
1697 Indices.push_back(Idx.getZExtValue());
1700 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1711 if (SrcType == DstType)
return Src;
1714 "ConvertVector source type must be a vector");
1716 "ConvertVector destination type must be a vector");
1718 llvm::Type *SrcTy = Src->
getType();
1719 llvm::Type *DstTy = ConvertType(DstType);
1728 assert(SrcTy->isVectorTy() &&
1729 "ConvertVector source IR type must be a vector");
1730 assert(DstTy->isVectorTy() &&
1731 "ConvertVector destination IR type must be a vector");
1733 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1734 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1736 if (DstEltType->isBooleanType()) {
1737 assert((SrcEltTy->isFloatingPointTy() ||
1738 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1740 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1741 if (SrcEltTy->isFloatingPointTy()) {
1742 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1744 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1749 Value *Res =
nullptr;
1751 if (isa<llvm::IntegerType>(SrcEltTy)) {
1753 if (isa<llvm::IntegerType>(DstEltTy))
1754 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1755 else if (InputSigned)
1756 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1758 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1759 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1760 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1761 if (DstEltType->isSignedIntegerOrEnumerationType())
1762 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1764 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1766 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1767 "Unknown real conversion");
1768 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1769 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1771 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1784 llvm::APSInt
Value = Result.Val.getInt();
1786 return Builder.getInt(
Value);
1790 return EmitLoadOfLValue(E);
1794 TestAndClearIgnoreResultAssign();
1802 return EmitLoadOfLValue(E);
1810 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1813 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
1817 TestAndClearIgnoreResultAssign();
1826 llvm::MatrixBuilder MB(Builder);
1827 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
1829 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
1834 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
1839 int MV = SVI->getMaskValue(Idx);
1846 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
1847 "Index operand too large for shufflevector mask!");
1848 return C->getZExtValue();
1852 bool Ignore = TestAndClearIgnoreResultAssign();
1854 assert (Ignore ==
false &&
"init list ignored");
1860 llvm::VectorType *VType =
1861 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
1864 if (NumInitElements == 0) {
1866 return EmitNullValue(E->
getType());
1872 if (isa<llvm::ScalableVectorType>(VType)) {
1873 if (NumInitElements == 0) {
1875 return EmitNullValue(E->
getType());
1878 if (NumInitElements == 1) {
1883 return Visit(InitVector);
1886 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
1889 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
1896 unsigned CurIdx = 0;
1897 bool VIsUndefShuffle =
false;
1898 llvm::Value *
V = llvm::UndefValue::get(VType);
1899 for (
unsigned i = 0; i != NumInitElements; ++i) {
1904 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
1910 if (isa<ExtVectorElementExpr>(IE)) {
1911 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
1913 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
1914 ->getNumElements() == ResElts) {
1915 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
1916 Value *LHS =
nullptr, *RHS =
nullptr;
1921 Args.resize(ResElts, -1);
1923 LHS = EI->getVectorOperand();
1925 VIsUndefShuffle =
true;
1926 }
else if (VIsUndefShuffle) {
1928 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
1929 for (
unsigned j = 0; j != CurIdx; ++j)
1931 Args.push_back(ResElts +
C->getZExtValue());
1932 Args.resize(ResElts, -1);
1934 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1935 RHS = EI->getVectorOperand();
1936 VIsUndefShuffle =
false;
1938 if (!Args.empty()) {
1939 V = Builder.CreateShuffleVector(LHS, RHS, Args);
1945 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
1947 VIsUndefShuffle =
false;
1952 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
1957 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1958 if (isa<ExtVectorElementExpr>(IE)) {
1959 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
1960 Value *SVOp = SVI->getOperand(0);
1961 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
1963 if (OpTy->getNumElements() == ResElts) {
1964 for (
unsigned j = 0; j != CurIdx; ++j) {
1967 if (VIsUndefShuffle) {
1968 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
1973 for (
unsigned j = 0, je = InitElts; j != je; ++j)
1975 Args.resize(ResElts, -1);
1977 if (VIsUndefShuffle)
1978 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
1987 for (
unsigned j = 0; j != InitElts; ++j)
1989 Args.resize(ResElts, -1);
1990 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
1993 for (
unsigned j = 0; j != CurIdx; ++j)
1995 for (
unsigned j = 0; j != InitElts; ++j)
1996 Args.push_back(j + Offset);
1997 Args.resize(ResElts, -1);
2004 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2005 VIsUndefShuffle = isa<llvm::UndefValue>(
Init);
2011 llvm::Type *EltTy = VType->getElementType();
2014 for (; CurIdx < ResElts; ++CurIdx) {
2015 Value *Idx = Builder.getInt32(CurIdx);
2016 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2017 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2022bool CodeGenFunction::ShouldNullCheckClassCastValue(
const CastExpr *CE) {
2025 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2035 if (ICE->isGLValue())
2049 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2053 bool Ignored = TestAndClearIgnoreResultAssign();
2059 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2060 case CK_BuiltinFnToFnPtr:
2061 llvm_unreachable(
"builtin functions are handled elsewhere");
2063 case CK_LValueBitCast:
2064 case CK_ObjCObjectLValueCast: {
2065 Address Addr = EmitLValue(E).getAddress(CGF);
2068 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2071 case CK_LValueToRValueBitCast: {
2077 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2080 case CK_CPointerToObjCPointerCast:
2081 case CK_BlockPointerToObjCPointerCast:
2082 case CK_AnyPointerToBlockPointerCast:
2084 Value *Src = Visit(
const_cast<Expr*
>(E));
2085 llvm::Type *SrcTy = Src->
getType();
2086 llvm::Type *DstTy = ConvertType(DestTy);
2088 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2089 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2090 "Address-space cast must be used to convert address spaces");
2092 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2095 PT->getPointeeType(),
2111 Src = Builder.CreateLaunderInvariantGroup(Src);
2119 Src = Builder.CreateStripInvariantGroup(Src);
2124 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2125 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2126 !isa<CastExpr>(E)) {
2128 if (!PointeeType.
isNull())
2137 if (
const auto *FixedSrc = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2138 if (
const auto *ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2141 bool NeedsBitCast =
false;
2142 auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16);
2143 llvm::Type *OrigType = DstTy;
2144 if (ScalableDst == PredType &&
2145 FixedSrc->getElementType() == Builder.getInt8Ty()) {
2146 DstTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2);
2147 ScalableDst = cast<llvm::ScalableVectorType>(DstTy);
2148 NeedsBitCast =
true;
2150 if (FixedSrc->getElementType() == ScalableDst->getElementType()) {
2151 llvm::Value *UndefVec = llvm::UndefValue::get(DstTy);
2152 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2153 llvm::Value *
Result = Builder.CreateInsertVector(
2154 DstTy, UndefVec, Src, Zero,
"cast.scalable");
2165 if (
const auto *ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2166 if (
const auto *FixedDst = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2169 auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16);
2170 if (ScalableSrc == PredType &&
2171 FixedDst->getElementType() == Builder.getInt8Ty()) {
2172 SrcTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2);
2173 ScalableSrc = cast<llvm::ScalableVectorType>(SrcTy);
2174 Src = Builder.CreateBitCast(Src, SrcTy);
2176 if (ScalableSrc->getElementType() == FixedDst->getElementType()) {
2177 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2178 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2189 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2190 isa<llvm::ScalableVectorType>(DstTy)) ||
2191 (isa<llvm::ScalableVectorType>(SrcTy) &&
2192 isa<llvm::FixedVectorType>(DstTy))) {
2199 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2201 return Builder.CreateBitCast(Src, DstTy);
2203 case CK_AddressSpaceConversion: {
2206 Result.Val.isNullPointer()) {
2210 if (
Result.HasSideEffects)
2213 ConvertType(DestTy)), DestTy);
2221 case CK_AtomicToNonAtomic:
2222 case CK_NonAtomicToAtomic:
2223 case CK_UserDefinedConversion:
2224 return Visit(
const_cast<Expr*
>(E));
2228 : Visit(const_cast<
Expr *>(E));
2231 case CK_BaseToDerived: {
2233 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2247 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2255 case CK_UncheckedDerivedToBase:
2256 case CK_DerivedToBase: {
2268 case CK_ArrayToPointerDecay:
2270 case CK_FunctionToPointerDecay:
2271 return EmitLValue(E).getPointer(CGF);
2273 case CK_NullToPointer:
2274 if (MustVisitNullValue(E))
2280 case CK_NullToMemberPointer: {
2281 if (MustVisitNullValue(E))
2288 case CK_ReinterpretMemberPointer:
2289 case CK_BaseToDerivedMemberPointer:
2290 case CK_DerivedToBaseMemberPointer: {
2291 Value *Src = Visit(E);
2302 case CK_ARCProduceObject:
2304 case CK_ARCConsumeObject:
2306 case CK_ARCReclaimReturnedObject:
2308 case CK_ARCExtendBlockObject:
2311 case CK_CopyAndAutoreleaseBlockObject:
2314 case CK_FloatingRealToComplex:
2315 case CK_FloatingComplexCast:
2316 case CK_IntegralRealToComplex:
2317 case CK_IntegralComplexCast:
2318 case CK_IntegralComplexToFloatingComplex:
2319 case CK_FloatingComplexToIntegralComplex:
2320 case CK_ConstructorConversion:
2322 llvm_unreachable(
"scalar cast to non-scalar value");
2324 case CK_LValueToRValue:
2326 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2327 return Visit(
const_cast<Expr*
>(E));
2329 case CK_IntegralToPointer: {
2330 Value *Src = Visit(
const_cast<Expr*
>(E));
2334 auto DestLLVMTy = ConvertType(DestTy);
2337 llvm::Value* IntResult =
2338 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2340 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2346 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2350 case CK_PointerToIntegral: {
2351 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2352 auto *PtrExpr = Visit(E);
2360 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2363 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2369 case CK_MatrixCast: {
2370 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2373 case CK_VectorSplat: {
2374 llvm::Type *DstTy = ConvertType(DestTy);
2375 Value *Elt = Visit(
const_cast<Expr *
>(E));
2377 llvm::ElementCount NumElements =
2378 cast<llvm::VectorType>(DstTy)->getElementCount();
2379 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2382 case CK_FixedPointCast:
2383 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2386 case CK_FixedPointToBoolean:
2388 "Expected src type to be fixed point type");
2389 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2390 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2393 case CK_FixedPointToIntegral:
2395 "Expected src type to be fixed point type");
2396 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2397 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2400 case CK_IntegralToFixedPoint:
2402 "Expected src type to be an integer");
2404 "Expected dest type to be fixed point type");
2405 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2408 case CK_IntegralCast: {
2409 ScalarConversionOpts Opts;
2410 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2411 if (!ICE->isPartOfExplicitCast())
2412 Opts = ScalarConversionOpts(CGF.
SanOpts);
2414 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2417 case CK_IntegralToFloating:
2418 case CK_FloatingToIntegral:
2419 case CK_FloatingCast:
2420 case CK_FixedPointToFloating:
2421 case CK_FloatingToFixedPoint: {
2422 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2423 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2426 case CK_BooleanToSignedIntegral: {
2427 ScalarConversionOpts Opts;
2428 Opts.TreatBooleanAsSigned =
true;
2429 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2432 case CK_IntegralToBoolean:
2433 return EmitIntToBoolConversion(Visit(E));
2434 case CK_PointerToBoolean:
2435 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2436 case CK_FloatingToBoolean: {
2437 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2438 return EmitFloatToBoolConversion(Visit(E));
2440 case CK_MemberPointerToBoolean: {
2441 llvm::Value *MemPtr = Visit(E);
2446 case CK_FloatingComplexToReal:
2447 case CK_IntegralComplexToReal:
2450 case CK_FloatingComplexToBoolean:
2451 case CK_IntegralComplexToBoolean: {
2455 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
2459 case CK_ZeroToOCLOpaqueType: {
2462 "CK_ZeroToOCLEvent cast on non-event type");
2463 return llvm::Constant::getNullValue(ConvertType(DestTy));
2466 case CK_IntToOCLSampler:
2471 llvm_unreachable(
"unknown scalar cast");
2475 CodeGenFunction::StmtExprEvaluation eval(CGF);
2485 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2489 Scope.ForceCleanup({&
V});
2498 llvm::Value *InVal,
bool IsInc,
2502 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2504 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2505 BinOp.FPFeatures = FPFeatures;
2510llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2512 llvm::Value *Amount =
2513 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2514 StringRef Name = IsInc ?
"inc" :
"dec";
2515 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2517 return Builder.CreateAdd(InVal, Amount, Name);
2519 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2520 return Builder.CreateNSWAdd(InVal, Amount, Name);
2524 return Builder.CreateNSWAdd(InVal, Amount, Name);
2528 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2533class OMPLastprivateConditionalUpdateRAII {
2542 ~OMPLastprivateConditionalUpdateRAII() {
2552 bool isInc,
bool isPre) {
2553 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
2555 llvm::PHINode *atomicPHI =
nullptr;
2559 int amount = (isInc ? 1 : -1);
2560 bool isSubtraction = !isInc;
2563 type = atomicTy->getValueType();
2564 if (isInc &&
type->isBooleanType()) {
2568 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2569 return Builder.getTrue();
2573 return Builder.CreateAtomicRMW(
2574 llvm::AtomicRMWInst::Xchg, LV.
getPointer(CGF), True,
2575 llvm::AtomicOrdering::SequentiallyConsistent);
2580 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2581 !(
type->isUnsignedIntegerType() &&
2582 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2585 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2586 llvm::AtomicRMWInst::Sub;
2587 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2588 llvm::Instruction::Sub;
2590 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2592 Builder.CreateAtomicRMW(aop, LV.
getPointer(CGF), amt,
2593 llvm::AtomicOrdering::SequentiallyConsistent);
2594 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2596 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2599 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2602 Builder.CreateBr(opBB);
2603 Builder.SetInsertPoint(opBB);
2604 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2605 atomicPHI->addIncoming(value, startBB);
2608 value = EmitLoadOfLValue(LV, E->
getExprLoc());
2619 if (isInc &&
type->isBooleanType()) {
2620 value = Builder.getTrue();
2623 }
else if (
type->isIntegerType()) {
2625 bool canPerformLossyDemotionCheck =
false;
2628 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2629 canPerformLossyDemotionCheck =
true;
2630 canPerformLossyDemotionCheck &=
2633 canPerformLossyDemotionCheck &=
2635 type, promotedType);
2636 assert((!canPerformLossyDemotionCheck ||
2637 type->isSignedIntegerOrEnumerationType() ||
2639 ConvertType(
type)->getScalarSizeInBits() ==
2640 ConvertType(promotedType)->getScalarSizeInBits()) &&
2641 "The following check expects that if we do promotion to different "
2642 "underlying canonical type, at least one of the types (either "
2643 "base or promoted) will be signed, or the bitwidths will match.");
2646 SanitizerKind::ImplicitIntegerArithmeticValueChange) &&
2647 canPerformLossyDemotionCheck) {
2657 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
2658 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2659 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2662 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
2663 ScalarConversionOpts(CGF.
SanOpts));
2668 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2669 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
2671 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2675 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2676 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2687 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2690 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2693 elemTy, value, numElts,
false, isSubtraction,
2697 }
else if (
type->isFunctionType()) {
2698 llvm::Value *amt = Builder.getInt32(amount);
2701 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
2705 false, isSubtraction,
2710 llvm::Value *amt = Builder.getInt32(amount);
2713 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
2716 elemTy, value, amt,
false, isSubtraction,
2721 }
else if (
type->isVectorType()) {
2722 if (
type->hasIntegerRepresentation()) {
2723 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2725 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2727 value = Builder.CreateFAdd(
2729 llvm::ConstantFP::get(value->getType(), amount),
2730 isInc ?
"inc" :
"dec");
2734 }
else if (
type->isRealFloatingType()) {
2737 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
2742 value = Builder.CreateCall(
2745 input,
"incdec.conv");
2747 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
2751 if (value->getType()->isFloatTy())
2752 amt = llvm::ConstantFP::get(VMContext,
2753 llvm::APFloat(
static_cast<float>(amount)));
2754 else if (value->getType()->isDoubleTy())
2755 amt = llvm::ConstantFP::get(VMContext,
2756 llvm::APFloat(
static_cast<double>(amount)));
2760 llvm::APFloat F(
static_cast<float>(amount));
2762 const llvm::fltSemantics *FS;
2765 if (value->getType()->isFP128Ty())
2767 else if (value->getType()->isHalfTy())
2769 else if (value->getType()->isBFloatTy())
2771 else if (value->getType()->isPPC_FP128Ty())
2775 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
2776 amt = llvm::ConstantFP::get(VMContext, F);
2778 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
2782 value = Builder.CreateCall(
2785 value,
"incdec.conv");
2787 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
2792 }
else if (
type->isFixedPointType()) {
2799 Info.Opcode = isInc ? BO_Add : BO_Sub;
2801 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
2804 if (
type->isSignedFixedPointType()) {
2805 Info.Opcode = isInc ? BO_Sub : BO_Add;
2806 Info.RHS = Builder.CreateNeg(Info.RHS);
2811 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
2813 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
2814 value = EmitFixedPointBinOp(Info);
2821 if (!isInc) size = -size;
2822 llvm::Value *sizeValue =
2823 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
2826 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
2829 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
2831 value = Builder.CreateBitCast(value, input->getType());
2835 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
2840 llvm::Value *
success = Pair.second;
2841 atomicPHI->addIncoming(old, curBlock);
2842 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
2843 Builder.SetInsertPoint(contBB);
2844 return isPre ? value : input;
2855 return isPre ? value : input;
2864 Value *result = VisitPlus(E, promotionTy);
2865 if (result && !promotionTy.
isNull())
2866 result = EmitUnPromotedValue(result, E->
getType());
2873 TestAndClearIgnoreResultAssign();
2874 if (!PromotionType.
isNull())
2884 Value *result = VisitMinus(E, promotionTy);
2885 if (result && !promotionTy.
isNull())
2886 result = EmitUnPromotedValue(result, E->
getType());
2892 TestAndClearIgnoreResultAssign();
2894 if (!PromotionType.
isNull())
2900 if (Op->
getType()->isFPOrFPVectorTy())
2901 return Builder.CreateFNeg(Op,
"fneg");
2906 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2908 BinOp.Opcode = BO_Sub;
2911 return EmitSub(BinOp);
2915 TestAndClearIgnoreResultAssign();
2917 return Builder.CreateNot(Op,
"not");
2928 if (Oper->
getType()->isFPOrFPVectorTy()) {
2929 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
2931 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
2933 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
2934 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
2943 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
2946 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
2954 return Builder.getInt(
Value);
2959 llvm::Type* ResultType = ConvertType(E->
getType());
2960 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
2962 for (
unsigned i = 0; i != n; ++i) {
2964 llvm::Value *Offset =
nullptr;
2971 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
2978 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2982 Offset = Builder.CreateMul(Idx, ElemSize);
2996 Field != FieldEnd; ++Field, ++i) {
2997 if (*Field == MemberDecl)
3000 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3005 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3008 CurrentType = MemberDecl->
getType();
3013 llvm_unreachable(
"dependent __builtin_offsetof");
3029 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3031 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3043ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3047 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3060 llvm::Value *size = VlaSize.
NumElts;
3064 if (!eltSize.
isOne())
3069 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3075 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3076 }
else if (E->
getKind() == UETT_VectorElements) {
3078 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3091 Value *result = VisitReal(E, promotionTy);
3092 if (result && !promotionTy.
isNull())
3093 result = EmitUnPromotedValue(result, E->
getType());
3105 if (!PromotionType.
isNull()) {
3107 Op, IgnoreResultAssign,
true);
3110 return result.first;
3120 if (!PromotionType.
isNull())
3130 Value *result = VisitImag(E, promotionTy);
3131 if (result && !promotionTy.
isNull())
3132 result = EmitUnPromotedValue(result, E->
getType());
3144 if (!PromotionType.
isNull()) {
3146 Op,
true, IgnoreResultAssign);
3149 return result.second;
3163 else if (!PromotionType.
isNull())
3167 if (!PromotionType.
isNull())
3168 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3169 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3176Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3178 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3181Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3183 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3188 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3190#define HANDLE_BINOP(OP) \
3192 return Emit##OP(EmitBinOps(BO, PromotionType));
3201 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3204 return VisitImag(UO, PromotionType);
3206 return VisitReal(UO, PromotionType);
3208 return VisitMinus(UO, PromotionType);
3210 return VisitPlus(UO, PromotionType);
3215 auto result = Visit(
const_cast<Expr *
>(E));
3217 if (!PromotionType.
isNull())
3218 return EmitPromotedValue(result, PromotionType);
3220 return EmitUnPromotedValue(result, E->
getType());
3227 TestAndClearIgnoreResultAssign();
3231 if (!PromotionType.
isNull())
3232 Result.Ty = PromotionType;
3241LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3243 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3256 if (PromotionTypeCR.
isNull())
3260 if (!PromotionTypeRHS.
isNull())
3263 OpInfo.RHS = Visit(E->
getRHS());
3264 OpInfo.Ty = PromotionTypeCR;
3271 llvm::PHINode *atomicPHI =
nullptr;
3274 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3275 !(
type->isUnsignedIntegerType() &&
3276 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3279 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3280 llvm::Instruction::BinaryOps Op;
3281 switch (OpInfo.Opcode) {
3283 case BO_MulAssign:
case BO_DivAssign:
3289 AtomicOp = llvm::AtomicRMWInst::Add;
3290 Op = llvm::Instruction::Add;
3293 AtomicOp = llvm::AtomicRMWInst::Sub;
3294 Op = llvm::Instruction::Sub;
3297 AtomicOp = llvm::AtomicRMWInst::And;
3298 Op = llvm::Instruction::And;
3301 AtomicOp = llvm::AtomicRMWInst::Xor;
3302 Op = llvm::Instruction::Xor;
3305 AtomicOp = llvm::AtomicRMWInst::Or;
3306 Op = llvm::Instruction::Or;
3309 llvm_unreachable(
"Invalid compound assignment type");
3311 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3313 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
3316 Value *OldVal = Builder.CreateAtomicRMW(
3318 llvm::AtomicOrdering::SequentiallyConsistent);
3322 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3328 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3330 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3332 Builder.CreateBr(opBB);
3333 Builder.SetInsertPoint(opBB);
3334 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3335 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3336 OpInfo.LHS = atomicPHI;
3339 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
3341 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3343 if (!PromotionTypeLHS.
isNull())
3344 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3347 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3355 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
3356 ScalarConversionOpts(CGF.
SanOpts));
3359 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3363 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3364 llvm::Value *
success = Pair.second;
3365 atomicPHI->addIncoming(old, curBlock);
3366 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3367 Builder.SetInsertPoint(contBB);
3387 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3388 bool Ignore = TestAndClearIgnoreResultAssign();
3389 Value *RHS =
nullptr;
3390 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
3405 return EmitLoadOfLValue(LHS, E->
getExprLoc());
3408void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3409 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3412 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3413 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3414 SanitizerKind::IntegerDivideByZero));
3417 const auto *BO = cast<BinaryOperator>(Ops.E);
3418 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3419 Ops.Ty->hasSignedIntegerRepresentation() &&
3421 Ops.mayHaveIntegerOverflow()) {
3422 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3424 llvm::Value *IntMin =
3425 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3426 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3428 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3429 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3430 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3432 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3435 if (Checks.size() > 0)
3436 EmitBinOpCheck(Checks, Ops);
3439Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3441 CodeGenFunction::SanitizerScope SanScope(&CGF);
3442 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3443 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3444 Ops.Ty->isIntegerType() &&
3445 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3446 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3447 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3448 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3449 Ops.Ty->isRealFloatingType() &&
3450 Ops.mayHaveFloatDivisionByZero()) {
3451 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3452 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3453 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3458 if (Ops.Ty->isConstantMatrixType()) {
3459 llvm::MatrixBuilder MB(Builder);
3462 auto *BO = cast<BinaryOperator>(Ops.E);
3466 "first operand must be a matrix");
3468 "second operand must be an arithmetic type");
3469 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3470 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3471 Ops.Ty->hasUnsignedIntegerRepresentation());
3474 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3476 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3477 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3481 else if (Ops.isFixedPointOp())
3482 return EmitFixedPointBinOp(Ops);
3483 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3484 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3486 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3489Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3491 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3492 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3493 Ops.Ty->isIntegerType() &&
3494 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3495 CodeGenFunction::SanitizerScope SanScope(&CGF);
3496 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3497 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3500 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3501 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3503 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3506Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3511 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3512 switch (Ops.Opcode) {
3516 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3517 llvm::Intrinsic::uadd_with_overflow;
3518 OverflowKind = SanitizerHandler::AddOverflow;
3523 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3524 llvm::Intrinsic::usub_with_overflow;
3525 OverflowKind = SanitizerHandler::SubOverflow;
3530 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3531 llvm::Intrinsic::umul_with_overflow;
3532 OverflowKind = SanitizerHandler::MulOverflow;
3535 llvm_unreachable(
"Unsupported operation for overflow detection");
3541 CodeGenFunction::SanitizerScope SanScope(&CGF);
3546 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3547 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3548 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3551 const std::string *handlerName =
3553 if (handlerName->empty()) {
3556 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3557 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3559 : SanitizerKind::UnsignedIntegerOverflow;
3560 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3562 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3567 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3568 llvm::BasicBlock *continueBB =
3572 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3576 Builder.SetInsertPoint(overflowBB);
3579 llvm::Type *Int8Ty = CGF.
Int8Ty;
3580 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3581 llvm::FunctionType *handlerTy =
3582 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3583 llvm::FunctionCallee handler =
3588 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3589 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3593 llvm::Value *handlerArgs[] = {
3596 Builder.getInt8(OpID),
3597 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3599 llvm::Value *handlerResult =
3603 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3604 Builder.CreateBr(continueBB);
3606 Builder.SetInsertPoint(continueBB);
3607 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3608 phi->addIncoming(result, initialBB);
3609 phi->addIncoming(handlerResult, overflowBB);
3616 const BinOpInfo &op,
3617 bool isSubtraction) {
3622 Value *pointer = op.LHS;
3623 Expr *pointerOperand =
expr->getLHS();
3624 Value *index = op.RHS;
3625 Expr *indexOperand =
expr->getRHS();
3628 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3629 std::swap(pointer, index);
3630 std::swap(pointerOperand, indexOperand);
3635 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3637 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3662 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3665 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3671 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3673 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3683 llvm::Value *objectSize
3686 index = CGF.
Builder.CreateMul(index, objectSize);
3705 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3708 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3710 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3729 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
3740 bool negMul,
bool negAdd) {
3741 Value *MulOp0 = MulOp->getOperand(0);
3742 Value *MulOp1 = MulOp->getOperand(1);
3744 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
3746 Addend = Builder.CreateFNeg(Addend,
"neg");
3748 Value *FMulAdd =
nullptr;
3749 if (Builder.getIsFPConstrained()) {
3750 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
3751 "Only constrained operation should be created when Builder is in FP "
3752 "constrained mode");
3753 FMulAdd = Builder.CreateConstrainedFPCall(
3754 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
3756 {MulOp0, MulOp1, Addend});
3758 FMulAdd = Builder.CreateCall(
3760 {MulOp0, MulOp1, Addend});
3762 MulOp->eraseFromParent();
3777 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
3778 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
3779 "Only fadd/fsub can be the root of an fmuladd.");
3782 if (!op.FPFeatures.allowFPContractWithinStatement())
3785 Value *LHS = op.LHS;
3786 Value *RHS = op.RHS;
3790 bool NegLHS =
false;
3791 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
3792 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
3793 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
3794 LHS = LHSUnOp->getOperand(0);
3799 bool NegRHS =
false;
3800 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
3801 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
3802 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
3803 RHS = RHSUnOp->getOperand(0);
3811 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
3812 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3813 (LHSBinOp->use_empty() || NegLHS)) {
3816 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
3817 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
3820 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
3821 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3822 (RHSBinOp->use_empty() || NegRHS)) {
3825 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
3826 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
3830 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
3831 if (LHSBinOp->getIntrinsicID() ==
3832 llvm::Intrinsic::experimental_constrained_fmul &&
3833 (LHSBinOp->use_empty() || NegLHS)) {
3836 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
3837 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
3840 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
3841 if (RHSBinOp->getIntrinsicID() ==
3842 llvm::Intrinsic::experimental_constrained_fmul &&
3843 (RHSBinOp->use_empty() || NegRHS)) {
3846 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
3847 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
3854Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
3855 if (op.LHS->getType()->isPointerTy() ||
3856 op.RHS->getType()->isPointerTy())
3859 if (op.Ty->isSignedIntegerOrEnumerationType()) {
3860 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3862 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3864 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3865 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3868 if (CanElideOverflowCheck(CGF.
getContext(), op))
3869 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
3870 return EmitOverflowCheckedBinOp(op);
3875 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3876 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3882 if (op.Ty->isConstantMatrixType()) {
3883 llvm::MatrixBuilder MB(Builder);
3884 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3885 return MB.CreateAdd(op.LHS, op.RHS);
3888 if (op.Ty->isUnsignedIntegerType() &&
3889 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3890 !CanElideOverflowCheck(CGF.
getContext(), op))
3891 return EmitOverflowCheckedBinOp(op);
3893 if (op.LHS->getType()->isFPOrFPVectorTy()) {
3894 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3895 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
3898 if (op.isFixedPointOp())
3899 return EmitFixedPointBinOp(op);
3901 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
3906Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
3908 using llvm::ConstantInt;
3916 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
3917 RHSTy = BinOp->getRHS()->getType();
3918 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
3923 LHSTy = CAO->getComputationLHSType();
3924 ResultTy = CAO->getComputationResultType();
3926 LHSTy = BinOp->getLHS()->getType();
3927 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
3928 LHSTy = UnOp->getSubExpr()->getType();
3929 RHSTy = UnOp->getSubExpr()->getType();
3932 Value *LHS = op.LHS;
3933 Value *RHS = op.RHS;
3938 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
3942 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3943 switch (op.Opcode) {
3946 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
3950 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
3954 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
3958 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
3962 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
3966 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
3969 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
3971 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
3973 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
3975 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
3980 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
3982 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
3986 llvm_unreachable(
"Found unimplemented fixed point binary operation");
3999 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4005 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4010Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4012 if (!op.LHS->getType()->isPointerTy()) {
4013 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4014 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4016 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4018 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4019 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4022 if (CanElideOverflowCheck(CGF.
getContext(), op))
4023 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4024 return EmitOverflowCheckedBinOp(op);
4029 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4030 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4036 if (op.Ty->isConstantMatrixType()) {
4037 llvm::MatrixBuilder MB(Builder);
4038 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4039 return MB.CreateSub(op.LHS, op.RHS);
4042 if (op.Ty->isUnsignedIntegerType() &&
4043 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4044 !CanElideOverflowCheck(CGF.
getContext(), op))
4045 return EmitOverflowCheckedBinOp(op);
4047 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4048 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4049 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4052 if (op.isFixedPointOp())
4053 return EmitFixedPointBinOp(op);
4055 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4060 if (!op.RHS->getType()->isPointerTy())
4067 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4069 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4070 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4074 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4076 llvm::Value *divisor =
nullptr;
4082 elementType = VlaSize.Type;
4083 divisor = VlaSize.NumElts;
4087 if (!eltSize.
isOne())
4103 if (elementSize.
isOne())
4112 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4115Value *ScalarExprEmitter::GetWidthMinusOneValue(
Value* LHS,
Value* RHS) {
4116 llvm::IntegerType *Ty;
4117 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4118 Ty = cast<llvm::IntegerType>(VT->getElementType());
4120 Ty = cast<llvm::IntegerType>(LHS->
getType());
4121 return llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth() - 1);
4125 const Twine &Name) {
4126 llvm::IntegerType *Ty;
4127 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4128 Ty = cast<llvm::IntegerType>(VT->getElementType());
4130 Ty = cast<llvm::IntegerType>(LHS->
getType());
4132 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4133 return Builder.CreateAnd(RHS, GetWidthMinusOneValue(LHS, RHS), Name);
4135 return Builder.CreateURem(
4136 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4139Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4141 if (Ops.isFixedPointOp())
4142 return EmitFixedPointBinOp(Ops);
4146 Value *RHS = Ops.RHS;
4147 if (Ops.LHS->getType() != RHS->
getType())
4148 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4150 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4151 Ops.Ty->hasSignedIntegerRepresentation() &&
4154 bool SanitizeUnsignedBase =
4155 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4156 Ops.Ty->hasUnsignedIntegerRepresentation();
4157 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4158 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4161 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4162 else if ((SanitizeBase || SanitizeExponent) &&
4163 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4164 CodeGenFunction::SanitizerScope SanScope(&CGF);
4166 llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
4167 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4169 if (SanitizeExponent) {
4171 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4178 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4181 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4182 llvm::Value *PromotedWidthMinusOne =
4183 (RHS == Ops.RHS) ? WidthMinusOne
4184 : GetWidthMinusOneValue(Ops.LHS, RHS);
4186 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4187 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4190 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4196 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4197 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4199 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4200 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4202 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4203 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4204 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4205 Checks.push_back(std::make_pair(
4206 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4207 : SanitizerKind::UnsignedShiftBase));
4210 assert(!Checks.empty());
4211 EmitBinOpCheck(Checks, Ops);
4214 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4217Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4219 if (Ops.isFixedPointOp())
4220 return EmitFixedPointBinOp(Ops);
4224 Value *RHS = Ops.RHS;
4225 if (Ops.LHS->getType() != RHS->
getType())
4226 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4230 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4231 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4232 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4233 CodeGenFunction::SanitizerScope SanScope(&CGF);
4234 llvm::Value *Valid =
4235 Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
4236 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4239 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4240 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4241 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4249 default: llvm_unreachable(
"unexpected element type");
4250 case BuiltinType::Char_U:
4251 case BuiltinType::UChar:
4252 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4253 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4254 case BuiltinType::Char_S:
4255 case BuiltinType::SChar:
4256 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4257 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4258 case BuiltinType::UShort:
4259 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4260 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4261 case BuiltinType::Short:
4262 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4263 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4264 case BuiltinType::UInt:
4265 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4266 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4267 case BuiltinType::Int:
4268 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4269 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4270 case BuiltinType::ULong:
4271 case BuiltinType::ULongLong:
4272 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4273 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4274 case BuiltinType::Long:
4275 case BuiltinType::LongLong:
4276 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4277 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4278 case BuiltinType::Float:
4279 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4280 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4281 case BuiltinType::Double:
4282 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4283 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4284 case BuiltinType::UInt128:
4285 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4286 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4287 case BuiltinType::Int128:
4288 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4289 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4294 llvm::CmpInst::Predicate UICmpOpc,
4295 llvm::CmpInst::Predicate SICmpOpc,
4296 llvm::CmpInst::Predicate FCmpOpc,
4298 TestAndClearIgnoreResultAssign();
4308 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
4310 BinOpInfo BOInfo = EmitBinOps(E);
4311 Value *LHS = BOInfo.LHS;
4312 Value *RHS = BOInfo.RHS;
4318 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4320 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4323 Value *FirstVecArg = LHS,
4324 *SecondVecArg = RHS;
4330 default: llvm_unreachable(
"is not a comparison operation");
4342 std::swap(FirstVecArg, SecondVecArg);
4349 if (ElementKind == BuiltinType::Float) {
4351 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4352 std::swap(FirstVecArg, SecondVecArg);
4360 if (ElementKind == BuiltinType::Float) {
4362 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4367 std::swap(FirstVecArg, SecondVecArg);
4372 Value *CR6Param = Builder.getInt32(CR6);
4374 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4381 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4382 if (ResultTy->getBitWidth() > 1 &&
4384 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4389 if (BOInfo.isFixedPointOp()) {
4390 Result = EmitFixedPointBinOp(BOInfo);
4391 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4392 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4394 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4396 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4398 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4403 !isa<llvm::ConstantPointerNull>(LHS) &&
4404 !isa<llvm::ConstantPointerNull>(RHS)) {
4413 LHS = Builder.CreateStripInvariantGroup(LHS);
4415 RHS = Builder.CreateStripInvariantGroup(RHS);
4418 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4424 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
4432 CETy = CTy->getElementType();
4434 LHS.first = Visit(E->
getLHS());
4435 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4441 CTy->getElementType()) &&
4442 "The element types must always match.");
4445 RHS.first = Visit(E->
getRHS());
4446 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4448 "The element types must always match.");
4451 Value *ResultR, *ResultI;
4455 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4456 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4460 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4461 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4465 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4468 "Complex comparison other than == or != ?");
4469 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4478 bool Ignore = TestAndClearIgnoreResultAssign();
4497 RHS = Visit(E->
getRHS());
4505 RHS = Visit(E->
getRHS());
4533 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4544 if (LHS->
getType()->isFPOrFPVectorTy()) {
4545 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4547 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4548 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4550 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4551 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4553 Value *
And = Builder.CreateAnd(LHS, RHS);
4554 return Builder.CreateSExt(And, ConvertType(E->
getType()),
"sext");
4558 llvm::Type *ResTy = ConvertType(E->
getType());
4573 if (InstrumentRegions &&
4577 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4585 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4590 return llvm::Constant::getNullValue(ResTy);
4596 CodeGenFunction::ConditionalEvaluation eval(CGF);
4605 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4607 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4609 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4618 RHSBlock = Builder.GetInsertBlock();
4623 if (InstrumentRegions &&
4626 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4630 PN->addIncoming(RHSCond, RHSBlockCnt);
4640 PN->addIncoming(RHSCond, RHSBlock);
4645 PN->setDebugLoc(Builder.getCurrentDebugLocation());
4649 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
4660 if (LHS->
getType()->isFPOrFPVectorTy()) {
4661 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4663 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4664 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4666 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4667 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4669 Value *Or = Builder.CreateOr(LHS, RHS);
4670 return Builder.CreateSExt(Or, ConvertType(E->
getType()),
"sext");
4674 llvm::Type *ResTy = ConvertType(E->
getType());
4689 if (InstrumentRegions &&
4693 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
4701 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
4706 return llvm::ConstantInt::get(ResTy, 1);
4712 CodeGenFunction::ConditionalEvaluation eval(CGF);
4722 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
4724 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4726 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
4738 RHSBlock = Builder.GetInsertBlock();
4743 if (InstrumentRegions &&
4746 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
4750 PN->addIncoming(RHSCond, RHSBlockCnt);
4756 PN->addIncoming(RHSCond, RHSBlock);
4759 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
4765 return Visit(E->
getRHS());
4790Value *ScalarExprEmitter::
4792 TestAndClearIgnoreResultAssign();
4795 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
4805 Expr *live = lhsExpr, *dead = rhsExpr;
4806 if (!CondExprBool) std::swap(live, dead);
4831 llvm::Value *LHS = Visit(lhsExpr);
4832 llvm::Value *RHS = Visit(rhsExpr);
4834 llvm::Type *condType = ConvertType(condExpr->
getType());
4835 auto *vecTy = cast<llvm::FixedVectorType>(condType);
4837 unsigned numElem = vecTy->getNumElements();
4838 llvm::Type *elemType = vecTy->getElementType();
4840 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
4841 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
4842 llvm::Value *tmp = Builder.CreateSExt(
4843 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
4844 llvm::Value *tmp2 = Builder.CreateNot(tmp);
4847 llvm::Value *RHSTmp = RHS;
4848 llvm::Value *LHSTmp = LHS;
4849 bool wasCast =
false;
4850 llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
4851 if (rhsVTy->getElementType()->isFloatingPointTy()) {
4852 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
4853 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
4857 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
4858 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
4859 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
4861 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
4871 llvm::Value *LHS = Visit(lhsExpr);
4872 llvm::Value *RHS = Visit(rhsExpr);
4874 llvm::Type *CondType = ConvertType(condExpr->
getType());
4875 auto *VecTy = cast<llvm::VectorType>(CondType);
4876 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
4878 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
4879 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
4888 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
4892 llvm::Value *LHS = Visit(lhsExpr);
4893 llvm::Value *RHS = Visit(rhsExpr);
4896 assert(!RHS &&
"LHS and RHS types must match");
4899 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
4906 CodeGenFunction::ConditionalEvaluation eval(CGF);
4913 Value *LHS = Visit(lhsExpr);
4916 LHSBlock = Builder.GetInsertBlock();
4917 Builder.CreateBr(ContBlock);
4921 Value *RHS = Visit(rhsExpr);
4924 RHSBlock = Builder.GetInsertBlock();
4934 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
4935 PN->addIncoming(LHS, LHSBlock);
4936 PN->addIncoming(RHS, RHSBlock);
4953 llvm::Type *ArgTy = ConvertType(VE->
getType());
4958 return llvm::UndefValue::get(ArgTy);
4962 llvm::Value *Val = Builder.CreateLoad(ArgPtr);
4965 if (ArgTy != Val->getType()) {
4966 if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
4967 Val = Builder.CreateIntToPtr(Val, ArgTy);
4969 Val = Builder.CreateTrunc(Val, ArgTy);
4975Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
4981 Value *Src,
unsigned NumElementsDst) {
4982 static constexpr int Mask[] = {0, 1, 2, -1};
4983 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5003 const llvm::DataLayout &DL,
5004 Value *Src, llvm::Type *DstTy,
5005 StringRef Name =
"") {
5009 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5010 return Builder.CreateBitCast(Src, DstTy, Name);
5013 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5014 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5017 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5019 if (!DstTy->isIntegerTy())
5020 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5022 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5026 if (!SrcTy->isIntegerTy())
5027 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5029 return Builder.CreateIntToPtr(Src, DstTy, Name);
5034 llvm::Type *DstTy = ConvertType(E->
getType());
5036 llvm::Type *SrcTy = Src->
getType();
5037 unsigned NumElementsSrc =
5038 isa<llvm::VectorType>(SrcTy)
5039 ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5041 unsigned NumElementsDst =
5042 isa<llvm::VectorType>(DstTy)
5043 ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5052 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5057 Src->setName(
"astype");
5064 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5065 auto *Vec4Ty = llvm::FixedVectorType::get(
5066 cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5071 Src->setName(
"astype");
5076 Src, DstTy,
"astype");
5091 "Invalid scalar expression to emit");
5093 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5094 .Visit(
const_cast<Expr *
>(E));
5103 "Invalid scalar expression to emit");
5104 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5114 "Invalid complex -> scalar conversion");
5115 return ScalarExprEmitter(*
this)
5116 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5123 if (!PromotionType.
isNull())
5124 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5126 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
5132 bool isInc,
bool isPre) {
5133 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
5143 llvm::Type *BaseTy =
5158 ScalarExprEmitter
Scalar(*
this);
5161#define COMPOUND_OP(Op) \
5162 case BO_##Op##Assign: \
5163 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
5200 llvm_unreachable(
"Not valid compound assignment operators");
5203 llvm_unreachable(
"Unhandled compound assignment operator");
5218 llvm::LLVMContext &VMContext,
5224 llvm::Value *TotalOffset =
nullptr;
5227 if (isa<llvm::Constant>(GEPVal)) {
5230 Value *BasePtr_int =
5231 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
5233 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
5234 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5235 return {TotalOffset, Builder.getFalse()};
5238 auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5239 assert(GEP->getPointerOperand() == BasePtr &&
5240 "BasePtr must be the base of the GEP.");
5241 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
5243 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5246 auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5247 auto *SAddIntrinsic =
5248 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5249 auto *SMulIntrinsic =
5250 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);