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());