31#include "llvm/ADT/APFixedPoint.h"
32#include "llvm/IR/CFG.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/DerivedTypes.h"
36#include "llvm/IR/FixedPointBuilder.h"
37#include "llvm/IR/Function.h"
38#include "llvm/IR/GetElementPtrTypeIterator.h"
39#include "llvm/IR/GlobalVariable.h"
40#include "llvm/IR/Intrinsics.h"
41#include "llvm/IR/IntrinsicsPowerPC.h"
42#include "llvm/IR/MatrixBuilder.h"
43#include "llvm/IR/Module.h"
44#include "llvm/Support/TypeSize.h"
49using namespace CodeGen;
67bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
69 llvm::APInt &Result) {
72 const auto &LHSAP = LHS->getValue();
73 const auto &RHSAP = RHS->getValue();
74 if (Opcode == BO_Add) {
75 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
76 : LHSAP.uadd_ov(RHSAP, Overflow);
77 }
else if (Opcode == BO_Sub) {
78 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
79 : LHSAP.usub_ov(RHSAP, Overflow);
80 }
else if (Opcode == BO_Mul) {
81 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
82 : LHSAP.umul_ov(RHSAP, Overflow);
83 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
84 if (
Signed && !RHS->isZero())
85 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
101 bool mayHaveIntegerOverflow()
const {
103 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
104 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
105 if (!LHSCI || !RHSCI)
109 return ::mayHaveIntegerOverflow(
114 bool isDivremOp()
const {
120 bool mayHaveIntegerDivisionByZero()
const {
122 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
128 bool mayHaveFloatDivisionByZero()
const {
130 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
131 return CFP->isZero();
138 bool isFixedPointOp()
const {
141 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
142 QualType LHSType = BinOp->getLHS()->getType();
143 QualType RHSType = BinOp->getRHS()->getType();
146 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
147 return UnOp->getSubExpr()->getType()->isFixedPointType();
152 bool rhsHasSignedIntegerRepresentation()
const {
153 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
154 QualType RHSType = BinOp->getRHS()->getType();
161static bool MustVisitNullValue(
const Expr *
E) {
169static std::optional<QualType> getUnwidenedIntegerType(
const ASTContext &Ctx,
185 return getUnwidenedIntegerType(Ctx,
E).has_value();
189static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
190 assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
191 "Expected a unary or binary operator");
195 if (!Op.mayHaveIntegerOverflow())
199 if (
const auto *UO = dyn_cast<UnaryOperator>(Op.E))
200 return !UO->canOverflow();
204 const auto *BO = cast<BinaryOperator>(Op.E);
205 auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
209 auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
218 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
224 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
225 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
229class ScalarExprEmitter
233 bool IgnoreResultAssign;
234 llvm::LLVMContext &VMContext;
238 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
239 VMContext(cgf.getLLVMContext()) {
246 bool TestAndClearIgnoreResultAssign() {
247 bool I = IgnoreResultAssign;
248 IgnoreResultAssign =
false;
254 LValue EmitCheckedLValue(
const Expr *
E, CodeGenFunction::TypeCheckKind TCK) {
258 void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
259 const BinOpInfo &Info);
265 void EmitLValueAlignmentAssumption(
const Expr *
E,
Value *
V) {
266 const AlignValueAttr *AVAttr =
nullptr;
267 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
271 if (
const auto *TTy =
273 AVAttr = TTy->getDecl()->
getAttr<AlignValueAttr>();
280 if (isa<ParmVarDecl>(VD) && !CGF.
SanOpts.
has(SanitizerKind::Alignment))
283 AVAttr = VD->
getAttr<AlignValueAttr>();
289 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
295 llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
303 Value *
V = EmitLoadOfLValue(EmitCheckedLValue(
E, CodeGenFunction::TCK_Load),
306 EmitLValueAlignmentAssumption(
E,
V);
316 void EmitFloatConversionCheck(
Value *OrigSrc,
QualType OrigSrcType,
323 enum ImplicitConversionCheckKind :
unsigned char {
324 ICCK_IntegerTruncation = 0,
325 ICCK_UnsignedIntegerTruncation = 1,
326 ICCK_SignedIntegerTruncation = 2,
327 ICCK_IntegerSignChange = 3,
328 ICCK_SignedIntegerTruncationOrSignChange = 4,
344 struct ScalarConversionOpts {
345 bool TreatBooleanAsSigned;
346 bool EmitImplicitIntegerTruncationChecks;
347 bool EmitImplicitIntegerSignChangeChecks;
349 ScalarConversionOpts()
350 : TreatBooleanAsSigned(
false),
351 EmitImplicitIntegerTruncationChecks(
false),
352 EmitImplicitIntegerSignChangeChecks(
false) {}
355 : TreatBooleanAsSigned(
false),
356 EmitImplicitIntegerTruncationChecks(
358 EmitImplicitIntegerSignChangeChecks(
362 llvm::Type *SrcTy, llvm::Type *DstTy,
363 ScalarConversionOpts Opts);
367 ScalarConversionOpts Opts = ScalarConversionOpts());
376 Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
386 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
387 return Builder.CreateFCmpUNE(
V, Zero,
"tobool");
394 return Builder.CreateICmpNE(
V, Zero,
"tobool");
401 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
402 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
403 Value *Result = ZI->getOperand(0);
408 ZI->eraseFromParent();
413 return Builder.CreateIsNotNull(
V,
"tobool");
427 llvm_unreachable(
"Stmt can't have complex result type!");
445 return Visit(
E->getSubExpr());
451 return Visit(
E->getReplacement());
454 return Visit(
GE->getResultExpr());
463 return Visit(
E->getSubExpr());
468 return Builder.getInt(
E->getValue());
471 return Builder.getInt(
E->getValue());
474 return llvm::ConstantFP::get(VMContext,
E->getValue());
477 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
480 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
483 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
498 return Builder.CreateBitCast(
V, ConvertType(
E->
getType()));
502 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getPackLength());
525 return EmitLoadOfLValue(
E);
535 return EmitLoadOfLValue(
E);
538 if (
E->getMethodDecl() &&
539 E->getMethodDecl()->getReturnType()->isReferenceType())
540 return EmitLoadOfLValue(
E);
551 VersionTuple Version =
E->getVersion();
556 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
566 Value *VisitExtVectorElementExpr(
Expr *
E) {
return EmitLoadOfLValue(
E); }
573 return EmitLoadOfLValue(
E);
580 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
589 return VisitCastExpr(
E);
594 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
595 return EmitLoadOfLValue(
E);
599 EmitLValueAlignmentAssumption(
E,
V);
607 LValue LV = EmitLValue(
E->getSubExpr());
608 return EmitScalarPrePostIncDec(
E, LV,
false,
false);
611 LValue LV = EmitLValue(
E->getSubExpr());
612 return EmitScalarPrePostIncDec(
E, LV,
true,
false);
615 LValue LV = EmitLValue(
E->getSubExpr());
616 return EmitScalarPrePostIncDec(
E, LV,
false,
true);
619 LValue LV = EmitLValue(
E->getSubExpr());
620 return EmitScalarPrePostIncDec(
E, LV,
true,
true);
623 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *
E,
628 bool isInc,
bool isPre);
632 if (isa<MemberPointerType>(
E->
getType()))
635 return EmitLValue(
E->getSubExpr()).getPointer(CGF);
639 return Visit(
E->getSubExpr());
640 return EmitLoadOfLValue(
E);
659 return Visit(
E->getSubExpr());
664 return EmitLoadOfLValue(
E);
675 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
679 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
696 return llvm::ConstantInt::get(ConvertType(
E->
getType()),
E->getValue());
700 return Builder.getInt1(
E->isSatisfied());
704 return Builder.getInt1(
E->isSatisfied());
708 return llvm::ConstantInt::get(Builder.getInt32Ty(),
E->getValue());
712 return llvm::ConstantInt::get(Builder.getInt1Ty(),
E->getValue());
735 return Builder.getInt1(
E->getValue());
739 Value *EmitMul(
const BinOpInfo &Ops) {
740 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
741 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
743 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
744 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
747 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
748 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
751 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
752 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
753 return EmitOverflowCheckedBinOp(Ops);
757 if (Ops.Ty->isConstantMatrixType()) {
758 llvm::MatrixBuilder MB(Builder);
761 auto *BO = cast<BinaryOperator>(Ops.E);
762 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
763 BO->getLHS()->getType().getCanonicalType());
764 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
765 BO->getRHS()->getType().getCanonicalType());
766 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
767 if (LHSMatTy && RHSMatTy)
768 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
769 LHSMatTy->getNumColumns(),
770 RHSMatTy->getNumColumns());
771 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
774 if (Ops.Ty->isUnsignedIntegerType() &&
775 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
776 !CanElideOverflowCheck(CGF.
getContext(), Ops))
777 return EmitOverflowCheckedBinOp(Ops);
779 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
781 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
782 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
784 if (Ops.isFixedPointOp())
785 return EmitFixedPointBinOp(Ops);
786 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
790 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
793 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
794 llvm::Value *Zero,
bool isDiv);
796 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
802 Value *EmitDiv(
const BinOpInfo &Ops);
803 Value *EmitRem(
const BinOpInfo &Ops);
804 Value *EmitAdd(
const BinOpInfo &Ops);
805 Value *EmitSub(
const BinOpInfo &Ops);
806 Value *EmitShl(
const BinOpInfo &Ops);
807 Value *EmitShr(
const BinOpInfo &Ops);
808 Value *EmitAnd(
const BinOpInfo &Ops) {
809 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
811 Value *EmitXor(
const BinOpInfo &Ops) {
812 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
814 Value *EmitOr (
const BinOpInfo &Ops) {
815 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
819 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
829 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
833 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
838 QualType ElementType = CT->getElementType();
845 unsigned NumElements = VT->getNumElements();
855#define HANDLEBINOP(OP) \
856 Value *VisitBin##OP(const BinaryOperator *E) { \
857 QualType promotionTy = getPromotionType(E->getType()); \
858 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
859 if (result && !promotionTy.isNull()) \
860 result = EmitUnPromotedValue(result, E->getType()); \
863 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
864 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
880 llvm::CmpInst::Predicate SICmpOpc,
881 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
882#define VISITCOMP(CODE, UI, SI, FP, SIG) \
883 Value *VisitBin##CODE(const BinaryOperator *E) { \
884 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
885 llvm::FCmpInst::FP, SIG); }
900 Value *VisitBinPtrMemD(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
901 Value *VisitBinPtrMemI(
const Expr *
E) {
return EmitLoadOfLValue(
E); }
904 return Visit(
E->getSemanticForm());
927 return Visit(
E->getSelectedExpr());
939 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
942 return EmitFloatToBoolConversion(Src);
948 "Unknown scalar type to convert");
950 if (isa<llvm::IntegerType>(Src->
getType()))
951 return EmitIntToBoolConversion(Src);
953 assert(isa<llvm::PointerType>(Src->
getType()));
954 return EmitPointerToBoolConversion(Src, SrcType);
957void ScalarExprEmitter::EmitFloatConversionCheck(
960 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
961 if (!isa<llvm::IntegerType>(DstTy))
964 CodeGenFunction::SanitizerScope SanScope(&CGF);
968 llvm::Value *Check =
nullptr;
969 const llvm::fltSemantics &SrcSema =
979 APFloat MinSrc(SrcSema, APFloat::uninitialized);
980 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
984 MinSrc = APFloat::getInf(SrcSema,
true);
988 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
991 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
992 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
996 MaxSrc = APFloat::getInf(SrcSema,
false);
1000 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1005 const llvm::fltSemantics &
Sema =
1008 MinSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1009 MaxSrc.convert(
Sema, APFloat::rmTowardZero, &IsInexact);
1013 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1015 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1016 Check = Builder.CreateAnd(GE, LE);
1021 CGF.
EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1022 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
1027static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1028 std::pair<llvm::Value *, SanitizerMask>>
1031 llvm::Type *SrcTy = Src->
getType();
1032 llvm::Type *DstTy = Dst->
getType();
1037 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1038 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1039 "non-integer llvm type");
1046 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1048 if (!SrcSigned && !DstSigned) {
1049 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1050 Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1052 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1053 Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1056 llvm::Value *Check =
nullptr;
1058 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1060 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1062 return std::make_pair(Kind, std::make_pair(Check, Mask));
1070void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src,
QualType SrcType,
1082 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1083 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1085 if (SrcBits <= DstBits)
1088 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1095 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1096 (!SrcSigned && DstSigned))
1099 CodeGenFunction::SanitizerScope SanScope(&CGF);
1101 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1102 std::pair<llvm::Value *, SanitizerMask>>
1111 llvm::Constant *StaticArgs[] = {
1114 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1115 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1117 CGF.
EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1125 llvm::Type *VTy =
V->getType();
1128 return llvm::ConstantInt::getFalse(VTy->getContext());
1130 llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1131 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V, Zero,
1132 llvm::Twine(Name) +
"." +
V->getName() +
1133 ".negativitycheck");
1138static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1139 std::pair<llvm::Value *, SanitizerMask>>
1142 llvm::Type *SrcTy = Src->
getType();
1143 llvm::Type *DstTy = Dst->
getType();
1145 assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1146 "non-integer llvm type");
1152 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1153 unsigned DstBits = DstTy->getScalarSizeInBits();
1157 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1158 "either the widths should be different, or the signednesses.");
1161 llvm::Value *SrcIsNegative =
1164 llvm::Value *DstIsNegative =
1170 llvm::Value *Check =
nullptr;
1171 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1173 return std::make_pair(
1174 ScalarExprEmitter::ICCK_IntegerSignChange,
1175 std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1178void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src,
QualType SrcType,
1181 if (!CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange))
1184 llvm::Type *SrcTy = Src->
getType();
1185 llvm::Type *DstTy = Dst->
getType();
1195 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1196 unsigned DstBits = DstTy->getScalarSizeInBits();
1203 if (SrcSigned == DstSigned && SrcBits == DstBits)
1207 if (!SrcSigned && !DstSigned)
1212 if ((DstBits > SrcBits) && DstSigned)
1214 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1215 (SrcBits > DstBits) && SrcSigned) {
1223 CodeGenFunction::SanitizerScope SanScope(&CGF);
1225 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1226 std::pair<llvm::Value *, SanitizerMask>>
1230 ImplicitConversionCheckKind CheckKind;
1236 CheckKind = Check.first;
1237 Checks.emplace_back(Check.second);
1239 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1240 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1246 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1247 Checks.emplace_back(Check.second);
1251 llvm::Constant *StaticArgs[] = {
1254 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1255 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1257 CGF.
EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1263static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1264 std::pair<llvm::Value *, SanitizerMask>>
1270 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1271 if (!SrcSigned && !DstSigned)
1272 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1274 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1276 llvm::Value *Check =
nullptr;
1278 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1280 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1283 return std::make_pair(
1284 Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1289static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1290 std::pair<llvm::Value *, SanitizerMask>>
1294 llvm::Value *SrcIsNegative =
1297 llvm::Value *DstIsNegative =
1303 llvm::Value *Check =
nullptr;
1305 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1307 return std::make_pair(
1308 ScalarExprEmitter::ICCK_IntegerSignChange,
1309 std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1312void CodeGenFunction::EmitBitfieldConversionCheck(
Value *Src,
QualType SrcType,
1317 if (!
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion))
1330 assert(isa<llvm::IntegerType>(Src->
getType()) &&
1331 isa<llvm::IntegerType>(Dst->
getType()) &&
"non-integer llvm type");
1335 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1336 unsigned DstBits = Info.
Size;
1341 CodeGenFunction::SanitizerScope SanScope(
this);
1343 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1344 std::pair<llvm::Value *, SanitizerMask>>
1348 bool EmitTruncation = DstBits < SrcBits;
1352 bool EmitTruncationFromUnsignedToSigned =
1353 EmitTruncation && DstSigned && !SrcSigned;
1355 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1356 bool BothUnsigned = !SrcSigned && !DstSigned;
1357 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1364 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1369 else if (EmitSignChange) {
1370 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1371 "either the widths should be different, or the signednesses.");
1377 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1378 if (EmitTruncationFromUnsignedToSigned)
1379 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1381 llvm::Constant *StaticArgs[] = {
1384 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1385 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1387 EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1392 QualType DstType, llvm::Type *SrcTy,
1394 ScalarConversionOpts Opts) {
1396 llvm::Type *SrcElementTy;
1397 llvm::Type *DstElementTy;
1401 SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1402 DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1407 "cannot cast between matrix and non-matrix types");
1408 SrcElementTy = SrcTy;
1409 DstElementTy = DstTy;
1410 SrcElementType = SrcType;
1411 DstElementType = DstType;
1414 if (isa<llvm::IntegerType>(SrcElementTy)) {
1416 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1420 if (isa<llvm::IntegerType>(DstElementTy))
1421 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1423 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1424 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1427 if (isa<llvm::IntegerType>(DstElementTy)) {
1428 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1435 llvm::Intrinsic::ID IID =
1436 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1437 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1441 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1442 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1445 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1446 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1447 return Builder.CreateFPExt(Src, DstTy,
"conv");
1455 ScalarConversionOpts Opts) {
1470 return Builder.CreateIsNotNull(Src,
"tobool");
1473 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1476 "Unhandled scalar conversion from a fixed point type to another type.");
1480 return EmitFixedPointConversion(Src, SrcType, DstType,
Loc);
1483 "Unhandled scalar conversion to a fixed point type from another type.");
1486 QualType NoncanonicalSrcType = SrcType;
1487 QualType NoncanonicalDstType = DstType;
1491 if (SrcType == DstType)
return Src;
1495 llvm::Value *OrigSrc = Src;
1497 llvm::Type *SrcTy = Src->
getType();
1501 return EmitConversionToBool(Src, SrcType);
1503 llvm::Type *DstTy = ConvertType(DstType);
1508 if (DstTy->isFloatingPointTy()) {
1510 return Builder.CreateCall(
1518 Src = Builder.CreateCall(
1523 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1531 if (SrcTy == DstTy) {
1532 if (Opts.EmitImplicitIntegerSignChangeChecks)
1533 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1534 NoncanonicalDstType,
Loc);
1542 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1544 if (isa<llvm::PointerType>(SrcTy))
1547 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1552 llvm::Value* IntResult =
1553 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1555 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1558 if (isa<llvm::PointerType>(SrcTy)) {
1560 assert(isa<llvm::IntegerType>(DstTy) &&
"not ptr->int?");
1561 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1570 "Splatted expr doesn't match with vector element type?");
1573 unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
1574 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1578 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1580 if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1582 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1583 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1584 if (SrcSize == DstSize)
1585 return Builder.CreateBitCast(Src, DstTy,
"conv");
1594 llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1595 llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1598 assert(((SrcElementTy->isIntegerTy() &&
1599 DstElementTy->isIntegerTy()) ||
1600 (SrcElementTy->isFloatingPointTy() &&
1601 DstElementTy->isFloatingPointTy())) &&
1602 "unexpected conversion between a floating-point vector and an "
1606 if (SrcElementTy->isIntegerTy())
1607 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1610 if (SrcSize > DstSize)
1611 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1614 return Builder.CreateFPExt(Src, DstTy,
"conv");
1618 Value *Res =
nullptr;
1619 llvm::Type *ResTy = DstTy;
1626 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1628 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1634 if (SrcTy->isFloatingPointTy()) {
1638 return Builder.CreateCall(
1641 return Builder.CreateFPTrunc(Src, DstTy);
1646 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1648 if (DstTy != ResTy) {
1650 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1651 Res = Builder.CreateCall(
1655 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1659 if (Opts.EmitImplicitIntegerTruncationChecks)
1660 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1661 NoncanonicalDstType,
Loc);
1663 if (Opts.EmitImplicitIntegerSignChangeChecks)
1664 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1665 NoncanonicalDstType,
Loc);
1673 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1676 Result = FPBuilder.CreateFloatingToFixed(Src,
1679 Result = FPBuilder.CreateFixedToFloating(Src,
1681 ConvertType(DstTy));
1687 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1688 DstFPSema.getWidth(),
1689 DstFPSema.isSigned());
1691 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1694 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1701Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1710 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1711 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy,
Loc);
1712 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1719 return EmitScalarConversion(Src.first, SrcTy, DstTy,
Loc);
1730void ScalarExprEmitter::EmitBinOpCheck(
1731 ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
const BinOpInfo &Info) {
1743 if (UO && UO->
getOpcode() == UO_Minus) {
1744 Check = SanitizerHandler::NegateOverflow;
1746 DynamicData.push_back(Info.RHS);
1750 Check = SanitizerHandler::ShiftOutOfBounds;
1752 StaticData.push_back(
1754 StaticData.push_back(
1756 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1758 Check = SanitizerHandler::DivremOverflow;
1763 case BO_Add: Check = SanitizerHandler::AddOverflow;
break;
1764 case BO_Sub: Check = SanitizerHandler::SubOverflow;
break;
1765 case BO_Mul: Check = SanitizerHandler::MulOverflow;
break;
1766 default: llvm_unreachable(
"unexpected opcode for bin op check");
1770 DynamicData.push_back(Info.LHS);
1771 DynamicData.push_back(Info.RHS);
1774 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData);
1781Value *ScalarExprEmitter::VisitExpr(
Expr *
E) {
1791 unsigned AddrSpace =
1793 llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1794 E->ComputeName(Context),
"__usn_str", AddrSpace);
1796 llvm::Type *ExprTy = ConvertType(
E->
getType());
1797 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1802 assert(
E->getDataElementCount() == 1);
1803 auto It =
E->begin();
1804 return Builder.getInt((*It)->getValue());
1809 if (
E->getNumSubExprs() == 2) {
1814 auto *LTy = cast<llvm::FixedVectorType>(LHS->
getType());
1815 unsigned LHSElts = LTy->getNumElements();
1819 auto *MTy = cast<llvm::FixedVectorType>(Mask->
getType());
1823 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1824 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1832 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1833 MTy->getNumElements());
1834 Value* NewV = llvm::PoisonValue::get(RTy);
1835 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1836 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1837 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1839 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1840 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1849 for (
unsigned i = 2; i <
E->getNumSubExprs(); ++i) {
1850 llvm::APSInt Idx =
E->getShuffleMaskIdx(CGF.
getContext(), i-2);
1852 if (Idx.isSigned() && Idx.isAllOnes())
1853 Indices.push_back(-1);
1855 Indices.push_back(Idx.getZExtValue());
1858 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1869 if (SrcType == DstType)
return Src;
1872 "ConvertVector source type must be a vector");
1874 "ConvertVector destination type must be a vector");
1876 llvm::Type *SrcTy = Src->
getType();
1877 llvm::Type *DstTy = ConvertType(DstType);
1886 assert(SrcTy->isVectorTy() &&
1887 "ConvertVector source IR type must be a vector");
1888 assert(DstTy->isVectorTy() &&
1889 "ConvertVector destination IR type must be a vector");
1891 llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1892 *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1894 if (DstEltType->isBooleanType()) {
1895 assert((SrcEltTy->isFloatingPointTy() ||
1896 isa<llvm::IntegerType>(SrcEltTy)) &&
"Unknown boolean conversion");
1898 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
1899 if (SrcEltTy->isFloatingPointTy()) {
1900 return Builder.CreateFCmpUNE(Src, Zero,
"tobool");
1902 return Builder.CreateICmpNE(Src, Zero,
"tobool");
1907 Value *Res =
nullptr;
1909 if (isa<llvm::IntegerType>(SrcEltTy)) {
1911 if (isa<llvm::IntegerType>(DstEltTy))
1912 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1913 else if (InputSigned)
1914 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
1916 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
1917 }
else if (isa<llvm::IntegerType>(DstEltTy)) {
1918 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
1919 if (DstEltType->isSignedIntegerOrEnumerationType())
1920 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
1922 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
1924 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1925 "Unknown real conversion");
1926 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1927 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
1929 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
1944 return Builder.getInt(
Value);
1948 llvm::Value *
Result = EmitLoadOfLValue(
E);
1954 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
1955 if (llvm::GetElementPtrInst *GEP =
1956 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
1957 if (llvm::Instruction *
Pointer =
1958 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
1971 TestAndClearIgnoreResultAssign();
1979 return EmitLoadOfLValue(
E);
1984 Value *Idx = Visit(
E->getIdx());
1987 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
1990 return Builder.CreateExtractElement(
Base, Idx,
"vecext");
1994 TestAndClearIgnoreResultAssign();
1998 Value *RowIdx = Visit(
E->getRowIdx());
1999 Value *ColumnIdx = Visit(
E->getColumnIdx());
2003 llvm::MatrixBuilder MB(Builder);
2004 Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2006 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2008 Value *Matrix = Visit(
E->getBase());
2011 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2016 int MV = SVI->getMaskValue(Idx);
2023 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2024 "Index operand too large for shufflevector mask!");
2025 return C->getZExtValue();
2029 bool Ignore = TestAndClearIgnoreResultAssign();
2031 assert (Ignore ==
false &&
"init list ignored");
2032 unsigned NumInitElements =
E->getNumInits();
2034 if (
E->hadArrayRangeDesignator())
2037 llvm::VectorType *VType =
2038 dyn_cast<llvm::VectorType>(ConvertType(
E->
getType()));
2041 if (NumInitElements == 0) {
2043 return EmitNullValue(
E->
getType());
2046 return Visit(
E->getInit(0));
2049 if (isa<llvm::ScalableVectorType>(VType)) {
2050 if (NumInitElements == 0) {
2052 return EmitNullValue(
E->
getType());
2055 if (NumInitElements == 1) {
2056 Expr *InitVector =
E->getInit(0);
2060 return Visit(InitVector);
2063 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2066 unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
2073 unsigned CurIdx = 0;
2074 bool VIsPoisonShuffle =
false;
2075 llvm::Value *
V = llvm::PoisonValue::get(VType);
2076 for (
unsigned i = 0; i != NumInitElements; ++i) {
2077 Expr *IE =
E->getInit(i);
2081 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2087 if (isa<ExtVectorElementExpr>(IE)) {
2088 llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(
Init);
2090 if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2091 ->getNumElements() == ResElts) {
2092 llvm::ConstantInt *
C = cast<llvm::ConstantInt>(EI->getIndexOperand());
2093 Value *LHS =
nullptr, *RHS =
nullptr;
2098 Args.resize(ResElts, -1);
2100 LHS = EI->getVectorOperand();
2102 VIsPoisonShuffle =
true;
2103 }
else if (VIsPoisonShuffle) {
2105 llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(
V);
2106 for (
unsigned j = 0; j != CurIdx; ++j)
2108 Args.push_back(ResElts +
C->getZExtValue());
2109 Args.resize(ResElts, -1);
2111 LHS = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2112 RHS = EI->getVectorOperand();
2113 VIsPoisonShuffle =
false;
2115 if (!Args.empty()) {
2116 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2122 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2124 VIsPoisonShuffle =
false;
2129 unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
2134 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2135 if (isa<ExtVectorElementExpr>(IE)) {
2136 llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(
Init);
2137 Value *SVOp = SVI->getOperand(0);
2138 auto *OpTy = cast<llvm::FixedVectorType>(SVOp->
getType());
2140 if (OpTy->getNumElements() == ResElts) {
2141 for (
unsigned j = 0; j != CurIdx; ++j) {
2144 if (VIsPoisonShuffle) {
2145 Args.push_back(
getMaskElt(cast<llvm::ShuffleVectorInst>(
V), j, 0));
2150 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2152 Args.resize(ResElts, -1);
2154 if (VIsPoisonShuffle)
2155 V = cast<llvm::ShuffleVectorInst>(
V)->getOperand(0);
2164 for (
unsigned j = 0; j != InitElts; ++j)
2166 Args.resize(ResElts, -1);
2167 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2170 for (
unsigned j = 0; j != CurIdx; ++j)
2172 for (
unsigned j = 0; j != InitElts; ++j)
2173 Args.push_back(j + Offset);
2174 Args.resize(ResElts, -1);
2181 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2182 VIsPoisonShuffle = isa<llvm::PoisonValue>(
Init);
2188 llvm::Type *EltTy = VType->getElementType();
2191 for (; CurIdx < ResElts; ++CurIdx) {
2192 Value *Idx = Builder.getInt32(CurIdx);
2193 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2194 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2202 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2212 if (ICE->isGLValue())
2226 CodeGenFunction::CGFPOptionsRAII
FPOptions(CGF, CE);
2230 bool Ignored = TestAndClearIgnoreResultAssign();
2236 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2237 case CK_BuiltinFnToFnPtr:
2238 llvm_unreachable(
"builtin functions are handled elsewhere");
2240 case CK_LValueBitCast:
2241 case CK_ObjCObjectLValueCast: {
2242 Address Addr = EmitLValue(
E).getAddress();
2245 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2248 case CK_LValueToRValueBitCast: {
2254 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2257 case CK_CPointerToObjCPointerCast:
2258 case CK_BlockPointerToObjCPointerCast:
2259 case CK_AnyPointerToBlockPointerCast:
2262 llvm::Type *SrcTy = Src->
getType();
2263 llvm::Type *DstTy = ConvertType(DestTy);
2265 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2266 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2267 "Address-space cast must be used to convert address spaces");
2269 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2272 PT->getPointeeType(),
2288 Src = Builder.CreateLaunderInvariantGroup(Src);
2296 Src = Builder.CreateStripInvariantGroup(Src);
2301 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2302 if (CI->getMetadata(
"heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2303 !isa<CastExpr>(
E)) {
2305 if (!PointeeType.
isNull())
2314 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2315 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2318 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2319 ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2320 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2321 ScalableDstTy = llvm::ScalableVectorType::get(
2322 FixedSrcTy->getElementType(),
2323 ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2325 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2326 llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2327 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2328 llvm::Value *
Result = Builder.CreateInsertVector(
2329 ScalableDstTy, UndefVec, Src, Zero,
"cast.scalable");
2330 if (
Result->getType() != DstTy)
2340 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2341 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2344 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2345 ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2346 FixedDstTy->getElementType()->isIntegerTy(8)) {
2347 ScalableSrcTy = llvm::ScalableVectorType::get(
2348 FixedDstTy->getElementType(),
2349 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2350 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2352 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2353 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
CGM.
Int64Ty);
2354 return Builder.CreateExtractVector(DstTy, Src, Zero,
"cast.fixed");
2365 if ((isa<llvm::FixedVectorType>(SrcTy) &&
2366 isa<llvm::ScalableVectorType>(DstTy)) ||
2367 (isa<llvm::ScalableVectorType>(SrcTy) &&
2368 isa<llvm::FixedVectorType>(DstTy))) {
2375 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2378 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2381 case CK_AddressSpaceConversion: {
2384 Result.Val.isNullPointer()) {
2388 if (
Result.HasSideEffects)
2391 ConvertType(DestTy)), DestTy);
2399 case CK_AtomicToNonAtomic:
2400 case CK_NonAtomicToAtomic:
2401 case CK_UserDefinedConversion:
2402 return Visit(
const_cast<Expr*
>(
E));
2406 : Visit(const_cast<
Expr *>(
E));
2409 case CK_BaseToDerived: {
2411 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2425 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2433 case CK_UncheckedDerivedToBase:
2434 case CK_DerivedToBase: {
2447 case CK_ArrayToPointerDecay:
2450 case CK_FunctionToPointerDecay:
2451 return EmitLValue(
E).getPointer(CGF);
2453 case CK_NullToPointer:
2454 if (MustVisitNullValue(
E))
2460 case CK_NullToMemberPointer: {
2461 if (MustVisitNullValue(
E))
2468 case CK_ReinterpretMemberPointer:
2469 case CK_BaseToDerivedMemberPointer:
2470 case CK_DerivedToBaseMemberPointer: {
2482 case CK_ARCProduceObject:
2484 case CK_ARCConsumeObject:
2486 case CK_ARCReclaimReturnedObject:
2488 case CK_ARCExtendBlockObject:
2491 case CK_CopyAndAutoreleaseBlockObject:
2494 case CK_FloatingRealToComplex:
2495 case CK_FloatingComplexCast:
2496 case CK_IntegralRealToComplex:
2497 case CK_IntegralComplexCast:
2498 case CK_IntegralComplexToFloatingComplex:
2499 case CK_FloatingComplexToIntegralComplex:
2500 case CK_ConstructorConversion:
2502 case CK_HLSLArrayRValue:
2503 llvm_unreachable(
"scalar cast to non-scalar value");
2505 case CK_LValueToRValue:
2507 assert(
E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2508 return Visit(
const_cast<Expr*
>(
E));
2510 case CK_IntegralToPointer: {
2515 auto DestLLVMTy = ConvertType(DestTy);
2518 llvm::Value* IntResult =
2519 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2521 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2527 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2533 case CK_PointerToIntegral: {
2534 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2535 auto *PtrExpr = Visit(
E);
2543 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2547 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2553 case CK_MatrixCast: {
2554 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2557 case CK_VectorSplat: {
2558 llvm::Type *DstTy = ConvertType(DestTy);
2561 llvm::ElementCount NumElements =
2562 cast<llvm::VectorType>(DstTy)->getElementCount();
2563 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2566 case CK_FixedPointCast:
2567 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2570 case CK_FixedPointToBoolean:
2572 "Expected src type to be fixed point type");
2573 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2574 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2577 case CK_FixedPointToIntegral:
2579 "Expected src type to be fixed point type");
2580 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2581 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2584 case CK_IntegralToFixedPoint:
2586 "Expected src type to be an integer");
2588 "Expected dest type to be fixed point type");
2589 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2592 case CK_IntegralCast: {
2595 return Builder.CreateIntCast(Visit(
E), ConvertType(DestTy),
2599 ScalarConversionOpts Opts;
2600 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2601 if (!ICE->isPartOfExplicitCast())
2602 Opts = ScalarConversionOpts(CGF.
SanOpts);
2604 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2607 case CK_IntegralToFloating: {
2612 return Builder.CreateSIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2613 return Builder.CreateUIToFP(Visit(
E), ConvertType(DestTy),
"conv");
2615 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2616 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2619 case CK_FloatingToIntegral: {
2624 return Builder.CreateFPToSI(Visit(
E), ConvertType(DestTy),
"conv");
2625 return Builder.CreateFPToUI(Visit(
E), ConvertType(DestTy),
"conv");
2627 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2628 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2631 case CK_FloatingCast: {
2638 return Builder.CreateFPTrunc(Visit(
E), ConvertType(DestTy),
"conv");
2639 return Builder.CreateFPExt(Visit(
E), ConvertType(DestTy),
"conv");
2641 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2642 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2645 case CK_FixedPointToFloating:
2646 case CK_FloatingToFixedPoint: {
2647 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2648 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2651 case CK_BooleanToSignedIntegral: {
2652 ScalarConversionOpts Opts;
2653 Opts.TreatBooleanAsSigned =
true;
2654 return EmitScalarConversion(Visit(
E),
E->
getType(), DestTy,
2657 case CK_IntegralToBoolean:
2658 return EmitIntToBoolConversion(Visit(
E));
2659 case CK_PointerToBoolean:
2660 return EmitPointerToBoolConversion(Visit(
E),
E->
getType());
2661 case CK_FloatingToBoolean: {
2662 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2663 return EmitFloatToBoolConversion(Visit(
E));
2665 case CK_MemberPointerToBoolean: {
2666 llvm::Value *MemPtr = Visit(
E);
2671 case CK_FloatingComplexToReal:
2672 case CK_IntegralComplexToReal:
2675 case CK_FloatingComplexToBoolean:
2676 case CK_IntegralComplexToBoolean: {
2680 return EmitComplexToScalarConversion(
V,
E->
getType(), DestTy,
2684 case CK_ZeroToOCLOpaqueType: {
2687 "CK_ZeroToOCLEvent cast on non-event type");
2688 return llvm::Constant::getNullValue(ConvertType(DestTy));
2691 case CK_IntToOCLSampler:
2694 case CK_HLSLVectorTruncation: {
2695 assert(DestTy->
isVectorType() &&
"Expected dest type to be vector type");
2699 for (
unsigned I = 0; I != NumElts; ++I)
2702 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
2707 llvm_unreachable(
"unknown scalar cast");
2711 CodeGenFunction::StmtExprEvaluation eval(CGF);
2721 CodeGenFunction::RunCleanupsScope
Scope(CGF);
2722 Value *
V = Visit(
E->getSubExpr());
2725 Scope.ForceCleanup({&
V});
2734 llvm::Value *InVal,
bool IsInc,
2738 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
2740 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2741 BinOp.FPFeatures = FPFeatures;
2746llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
2748 llvm::Value *Amount =
2749 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
2750 StringRef Name = IsInc ?
"inc" :
"dec";
2751 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
2753 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2754 return Builder.CreateAdd(InVal, Amount, Name);
2757 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
2758 return Builder.CreateNSWAdd(InVal, Amount, Name);
2761 if (!
E->canOverflow())
2762 return Builder.CreateNSWAdd(InVal, Amount, Name);
2766 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
2771class OMPLastprivateConditionalUpdateRAII {
2780 ~OMPLastprivateConditionalUpdateRAII() {
2783 CGF,
E->getSubExpr());
2790 bool isInc,
bool isPre) {
2791 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF,
E);
2793 llvm::PHINode *atomicPHI =
nullptr;
2799 int amount = (isInc ? 1 : -1);
2800 bool isSubtraction = !isInc;
2803 type = atomicTy->getValueType();
2804 if (isInc &&
type->isBooleanType()) {
2808 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2809 return Builder.getTrue();
2813 return Builder.CreateAtomicRMW(
2815 llvm::AtomicOrdering::SequentiallyConsistent);
2820 if (!
type->isBooleanType() &&
type->isIntegerType() &&
2821 !(
type->isUnsignedIntegerType() &&
2822 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
2825 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2826 llvm::AtomicRMWInst::Sub;
2827 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2828 llvm::Instruction::Sub;
2830 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
2832 Builder.CreateAtomicRMW(aop, LV.
getAddress(), amt,
2833 llvm::AtomicOrdering::SequentiallyConsistent);
2834 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2837 if (
type->isFloatingType()) {
2838 llvm::AtomicRMWInst::BinOp aop =
2839 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
2840 llvm::Instruction::BinaryOps op =
2841 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
2842 llvm::Value *amt = llvm::ConstantFP::get(
2843 VMContext, llvm::APFloat(
static_cast<float>(1.0)));
2844 llvm::AtomicRMWInst *old =
2846 llvm::AtomicOrdering::SequentiallyConsistent);
2848 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2853 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2856 Builder.CreateBr(opBB);
2857 Builder.SetInsertPoint(opBB);
2858 atomicPHI = Builder.CreatePHI(value->getType(), 2);
2859 atomicPHI->addIncoming(value, startBB);
2873 if (isInc &&
type->isBooleanType()) {
2874 value = Builder.getTrue();
2877 }
else if (
type->isIntegerType()) {
2879 bool canPerformLossyDemotionCheck =
false;
2882 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
2883 canPerformLossyDemotionCheck =
true;
2884 canPerformLossyDemotionCheck &=
2887 canPerformLossyDemotionCheck &=
2889 type, promotedType);
2890 assert((!canPerformLossyDemotionCheck ||
2891 type->isSignedIntegerOrEnumerationType() ||
2893 ConvertType(
type)->getScalarSizeInBits() ==
2894 ConvertType(promotedType)->getScalarSizeInBits()) &&
2895 "The following check expects that if we do promotion to different "
2896 "underlying canonical type, at least one of the types (either "
2897 "base or promoted) will be signed, or the bitwidths will match.");
2900 SanitizerKind::ImplicitIntegerArithmeticValueChange |
2901 SanitizerKind::ImplicitBitfieldConversion) &&
2902 canPerformLossyDemotionCheck) {
2916 value = EmitScalarConversion(value,
type, promotedType,
E->
getExprLoc());
2917 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2918 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2922 ScalarConversionOpts Opts;
2924 Opts = ScalarConversionOpts(CGF.
SanOpts);
2925 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
2927 SrcType = promotedType;
2930 value = EmitScalarConversion(value, promotedType,
type,
E->
getExprLoc(),
2936 }
else if (
E->canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
2937 value = EmitIncDecConsiderOverflowBehavior(
E, value, isInc);
2938 }
else if (
E->canOverflow() &&
type->isUnsignedIntegerType() &&
2939 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) {
2943 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
2944 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2955 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
2958 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
2961 elemTy, value, numElts,
false, isSubtraction,
2965 }
else if (
type->isFunctionType()) {
2966 llvm::Value *amt = Builder.getInt32(amount);
2969 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
2973 false, isSubtraction,
2978 llvm::Value *amt = Builder.getInt32(amount);
2981 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
2984 elemTy, value, amt,
false, isSubtraction,
2989 }
else if (
type->isVectorType()) {
2990 if (
type->hasIntegerRepresentation()) {
2991 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2993 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
2995 value = Builder.CreateFAdd(
2997 llvm::ConstantFP::get(value->getType(), amount),
2998 isInc ?
"inc" :
"dec");
3002 }
else if (
type->isRealFloatingType()) {
3005 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF,
E);
3010 value = Builder.CreateCall(
3013 input,
"incdec.conv");
3015 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3019 if (value->getType()->isFloatTy())
3020 amt = llvm::ConstantFP::get(VMContext,
3021 llvm::APFloat(
static_cast<float>(amount)));
3022 else if (value->getType()->isDoubleTy())
3023 amt = llvm::ConstantFP::get(VMContext,
3024 llvm::APFloat(
static_cast<double>(amount)));
3028 llvm::APFloat F(
static_cast<float>(amount));
3030 const llvm::fltSemantics *FS;
3033 if (value->getType()->isFP128Ty())
3035 else if (value->getType()->isHalfTy())
3037 else if (value->getType()->isBFloatTy())
3039 else if (value->getType()->isPPC_FP128Ty())
3043 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3044 amt = llvm::ConstantFP::get(VMContext, F);
3046 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3050 value = Builder.CreateCall(
3053 value,
"incdec.conv");
3055 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3060 }
else if (
type->isFixedPointType()) {
3067 Info.Opcode = isInc ? BO_Add : BO_Sub;
3069 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3072 if (
type->isSignedFixedPointType()) {
3073 Info.Opcode = isInc ? BO_Sub : BO_Add;
3074 Info.RHS = Builder.CreateNeg(Info.RHS);
3079 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3081 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3082 value = EmitFixedPointBinOp(Info);
3089 if (!isInc) size = -size;
3090 llvm::Value *sizeValue =
3091 llvm::ConstantInt::get(CGF.
SizeTy, size.getQuantity());
3094 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3097 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3099 value = Builder.CreateBitCast(value, input->getType());
3103 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3108 llvm::Value *
success = Pair.second;
3109 atomicPHI->addIncoming(old, curBlock);
3110 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3111 Builder.SetInsertPoint(contBB);
3112 return isPre ? value : input;
3126 return isPre ? value : input;
3133 ? getPromotionType(
E->getSubExpr()->
getType())
3135 Value *result = VisitPlus(
E, promotionTy);
3136 if (result && !promotionTy.
isNull())
3137 result = EmitUnPromotedValue(result,
E->
getType());
3144 TestAndClearIgnoreResultAssign();
3145 if (!PromotionType.
isNull())
3147 return Visit(
E->getSubExpr());
3153 ? getPromotionType(
E->getSubExpr()->
getType())
3155 Value *result = VisitMinus(
E, promotionTy);
3156 if (result && !promotionTy.
isNull())
3157 result = EmitUnPromotedValue(result,
E->
getType());
3163 TestAndClearIgnoreResultAssign();
3165 if (!PromotionType.
isNull())
3168 Op = Visit(
E->getSubExpr());
3171 if (Op->
getType()->isFPOrFPVectorTy())
3172 return Builder.CreateFNeg(Op,
"fneg");
3177 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3179 BinOp.Opcode = BO_Sub;
3182 return EmitSub(BinOp);
3186 TestAndClearIgnoreResultAssign();
3187 Value *Op = Visit(
E->getSubExpr());
3188 return Builder.CreateNot(Op,
"not");
3196 Value *Oper = Visit(
E->getSubExpr());
3199 if (Oper->
getType()->isFPOrFPVectorTy()) {
3200 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3202 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero,
"cmp");
3204 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero,
"cmp");
3205 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
3214 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3217 return Builder.CreateZExt(BoolVal, ConvertType(
E->
getType()),
"lnot.ext");
3225 return Builder.getInt(
Value);
3229 unsigned n =
E->getNumComponents();
3230 llvm::Type* ResultType = ConvertType(
E->
getType());
3231 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3233 for (
unsigned i = 0; i != n; ++i) {
3235 llvm::Value *Offset =
nullptr;
3242 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3249 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3253 Offset = Builder.CreateMul(Idx, ElemSize);
3267 Field != FieldEnd; ++Field, ++i) {
3268 if (*Field == MemberDecl)
3271 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3276 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3279 CurrentType = MemberDecl->
getType();
3284 llvm_unreachable(
"dependent __builtin_offsetof");
3300 auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
3302 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3314ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3316 QualType TypeToSize =
E->getTypeOfArgument();
3317 if (
auto Kind =
E->getKind();
3318 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3321 if (
E->isArgumentType()) {
3331 llvm::Value *size = VlaSize.
NumElts;
3335 if (!eltSize.
isOne())
3340 }
else if (
E->getKind() == UETT_OpenMPRequiredSimdAlign) {
3344 E->getTypeOfArgument()->getPointeeType()))
3346 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3347 }
else if (
E->getKind() == UETT_VectorElements) {
3348 auto *VecTy = cast<llvm::VectorType>(ConvertType(
E->getTypeOfArgument()));
3349 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3360 ? getPromotionType(
E->getSubExpr()->
getType())
3362 Value *result = VisitReal(
E, promotionTy);
3363 if (result && !promotionTy.
isNull())
3364 result = EmitUnPromotedValue(result,
E->
getType());
3370 Expr *Op =
E->getSubExpr();
3376 if (!PromotionType.
isNull()) {
3378 Op, IgnoreResultAssign,
true);
3381 return result.first;
3391 if (!PromotionType.
isNull())
3399 ? getPromotionType(
E->getSubExpr()->
getType())
3401 Value *result = VisitImag(
E, promotionTy);
3402 if (result && !promotionTy.
isNull())
3403 result = EmitUnPromotedValue(result,
E->
getType());
3409 Expr *Op =
E->getSubExpr();
3415 if (!PromotionType.
isNull()) {
3417 Op,
true, IgnoreResultAssign);
3420 return result.second;
3434 else if (!PromotionType.
isNull())
3438 if (!PromotionType.
isNull())
3439 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3440 return llvm::Constant::getNullValue(ConvertType(
E->
getType()));
3447Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3449 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3452Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3454 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3459 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
3461#define HANDLE_BINOP(OP) \
3463 return Emit##OP(EmitBinOps(BO, PromotionType));
3472 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
3475 return VisitImag(UO, PromotionType);
3477 return VisitReal(UO, PromotionType);
3479 return VisitMinus(UO, PromotionType);
3481 return VisitPlus(UO, PromotionType);
3486 auto result = Visit(
const_cast<Expr *
>(
E));
3488 if (!PromotionType.
isNull())
3489 return EmitPromotedValue(result, PromotionType);
3491 return EmitUnPromotedValue(result,
E->
getType());
3498 TestAndClearIgnoreResultAssign();
3502 if (!PromotionType.
isNull())
3503 Result.Ty = PromotionType;
3506 Result.Opcode =
E->getOpcode();
3512LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3514 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3519 if (
E->getComputationResultType()->isAnyComplexType())
3526 PromotionTypeCR = getPromotionType(
E->getComputationResultType());
3527 if (PromotionTypeCR.
isNull())
3528 PromotionTypeCR =
E->getComputationResultType();
3529 QualType PromotionTypeLHS = getPromotionType(
E->getComputationLHSType());
3531 if (!PromotionTypeRHS.
isNull())
3534 OpInfo.RHS = Visit(
E->getRHS());
3535 OpInfo.Ty = PromotionTypeCR;
3536 OpInfo.Opcode =
E->getOpcode();
3542 llvm::PHINode *atomicPHI =
nullptr;
3545 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3546 !(
type->isUnsignedIntegerType() &&
3547 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3550 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3551 llvm::Instruction::BinaryOps Op;
3552 switch (OpInfo.Opcode) {
3554 case BO_MulAssign:
case BO_DivAssign:
3560 AtomicOp = llvm::AtomicRMWInst::Add;
3561 Op = llvm::Instruction::Add;
3564 AtomicOp = llvm::AtomicRMWInst::Sub;
3565 Op = llvm::Instruction::Sub;
3568 AtomicOp = llvm::AtomicRMWInst::And;
3569 Op = llvm::Instruction::And;
3572 AtomicOp = llvm::AtomicRMWInst::Xor;
3573 Op = llvm::Instruction::Xor;
3576 AtomicOp = llvm::AtomicRMWInst::Or;
3577 Op = llvm::Instruction::Or;
3580 llvm_unreachable(
"Invalid compound assignment type");
3582 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3584 EmitScalarConversion(OpInfo.RHS,
E->getRHS()->
getType(), LHSTy,
3588 llvm::AtomicRMWInst *OldVal =
3593 Result = Builder.CreateBinOp(Op, OldVal, Amt);
3599 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3601 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3603 Builder.CreateBr(opBB);
3604 Builder.SetInsertPoint(opBB);
3605 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3606 atomicPHI->addIncoming(OpInfo.LHS, startBB);
3607 OpInfo.LHS = atomicPHI;
3610 OpInfo.LHS = EmitLoadOfLValue(LHSLV,
E->
getExprLoc());
3612 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
3614 if (!PromotionTypeLHS.
isNull())
3615 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3618 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3619 E->getComputationLHSType(),
Loc);
3634 ScalarConversionOpts(CGF.
SanOpts));
3637 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3641 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
3642 llvm::Value *
success = Pair.second;
3643 atomicPHI->addIncoming(old, curBlock);
3644 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3645 Builder.SetInsertPoint(contBB);
3670 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
3671 bool Ignore = TestAndClearIgnoreResultAssign();
3672 Value *RHS =
nullptr;
3673 LValue LHS = EmitCompoundAssignLValue(
E,
Func, RHS);
3691void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
3692 const BinOpInfo &Ops, llvm::Value *Zero,
bool isDiv) {
3695 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
3696 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
3697 SanitizerKind::IntegerDivideByZero));
3700 const auto *BO = cast<BinaryOperator>(Ops.E);
3701 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
3702 Ops.Ty->hasSignedIntegerRepresentation() &&
3704 Ops.mayHaveIntegerOverflow()) {
3705 llvm::IntegerType *Ty = cast<llvm::IntegerType>(
Zero->getType());
3707 llvm::Value *IntMin =
3708 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3709 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3711 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
3712 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
3713 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
3715 std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3718 if (Checks.size() > 0)
3719 EmitBinOpCheck(Checks, Ops);
3722Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
3724 CodeGenFunction::SanitizerScope SanScope(&CGF);
3725 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3726 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3727 Ops.Ty->isIntegerType() &&
3728 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3729 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3730 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
true);
3731 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
3732 Ops.Ty->isRealFloatingType() &&
3733 Ops.mayHaveFloatDivisionByZero()) {
3734 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3735 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
3736 EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
3741 if (Ops.Ty->isConstantMatrixType()) {
3742 llvm::MatrixBuilder MB(Builder);
3745 auto *BO = cast<BinaryOperator>(Ops.E);
3749 "first operand must be a matrix");
3751 "second operand must be an arithmetic type");
3752 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3753 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3754 Ops.Ty->hasUnsignedIntegerRepresentation());
3757 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3759 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3760 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
3764 else if (Ops.isFixedPointOp())
3765 return EmitFixedPointBinOp(Ops);
3766 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3767 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
3769 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
3772Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
3774 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
3775 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
3776 Ops.Ty->isIntegerType() &&
3777 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3778 CodeGenFunction::SanitizerScope SanScope(&CGF);
3779 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3780 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero,
false);
3783 if (Ops.Ty->hasUnsignedIntegerRepresentation())
3784 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
3786 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
3789Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
3794 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3795 switch (Ops.Opcode) {
3799 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3800 llvm::Intrinsic::uadd_with_overflow;
3801 OverflowKind = SanitizerHandler::AddOverflow;
3806 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3807 llvm::Intrinsic::usub_with_overflow;
3808 OverflowKind = SanitizerHandler::SubOverflow;
3813 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3814 llvm::Intrinsic::umul_with_overflow;
3815 OverflowKind = SanitizerHandler::MulOverflow;
3818 llvm_unreachable(
"Unsupported operation for overflow detection");
3824 CodeGenFunction::SanitizerScope SanScope(&CGF);
3829 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3830 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3831 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3834 const std::string *handlerName =
3836 if (handlerName->empty()) {
3839 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
3840 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
3842 : SanitizerKind::UnsignedIntegerOverflow;
3843 EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
3845 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
3850 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3851 llvm::BasicBlock *continueBB =
3855 Builder.CreateCondBr(overflow, overflowBB, continueBB);
3859 Builder.SetInsertPoint(overflowBB);
3862 llvm::Type *Int8Ty = CGF.
Int8Ty;
3863 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
3864 llvm::FunctionType *handlerTy =
3865 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
3866 llvm::FunctionCallee handler =
3871 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
3872 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
3876 llvm::Value *handlerArgs[] = {
3879 Builder.getInt8(OpID),
3880 Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3882 llvm::Value *handlerResult =
3886 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3887 Builder.CreateBr(continueBB);
3889 Builder.SetInsertPoint(continueBB);
3890 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3891 phi->addIncoming(result, initialBB);
3892 phi->addIncoming(handlerResult, overflowBB);
3899 const BinOpInfo &op,
3900 bool isSubtraction) {
3905 Value *pointer = op.LHS;
3906 Expr *pointerOperand =
expr->getLHS();
3907 Value *index = op.RHS;
3908 Expr *indexOperand =
expr->getRHS();
3911 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
3912 std::swap(pointer, index);
3913 std::swap(pointerOperand, indexOperand);
3918 unsigned width = cast<llvm::IntegerType>(index->
getType())->getBitWidth();
3920 auto PtrTy = cast<llvm::PointerType>(pointer->
getType());
3945 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3948 index = CGF.
Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3954 index = CGF.
Builder.CreateNeg(index,
"idx.neg");
3956 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
3966 llvm::Value *objectSize
3969 index = CGF.
Builder.CreateMul(index, objectSize);
3988 index = CGF.
Builder.CreateMul(index, numElements,
"vla.index");
3991 index = CGF.
Builder.CreateNSWMul(index, numElements,
"vla.index");
3993 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4012 elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
4023 bool negMul,
bool negAdd) {
4024 Value *MulOp0 = MulOp->getOperand(0);
4025 Value *MulOp1 = MulOp->getOperand(1);
4027 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4029 Addend = Builder.CreateFNeg(Addend,
"neg");
4031 Value *FMulAdd =
nullptr;
4032 if (Builder.getIsFPConstrained()) {
4033 assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4034 "Only constrained operation should be created when Builder is in FP "
4035 "constrained mode");
4036 FMulAdd = Builder.CreateConstrainedFPCall(
4037 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4039 {MulOp0, MulOp1, Addend});
4041 FMulAdd = Builder.CreateCall(
4043 {MulOp0, MulOp1, Addend});
4045 MulOp->eraseFromParent();
4060 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4061 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4062 "Only fadd/fsub can be the root of an fmuladd.");
4065 if (!op.FPFeatures.allowFPContractWithinStatement())
4068 Value *LHS = op.LHS;
4069 Value *RHS = op.RHS;
4073 bool NegLHS =
false;
4074 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4075 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4076 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4077 LHS = LHSUnOp->getOperand(0);
4082 bool NegRHS =
false;
4083 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4084 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4085 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4086 RHS = RHSUnOp->getOperand(0);
4094 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4095 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4096 (LHSBinOp->use_empty() || NegLHS)) {
4099 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4100 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4103 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4104 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4105 (RHSBinOp->use_empty() || NegRHS)) {
4108 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4109 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4113 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4114 if (LHSBinOp->getIntrinsicID() ==
4115 llvm::Intrinsic::experimental_constrained_fmul &&
4116 (LHSBinOp->use_empty() || NegLHS)) {
4119 cast<llvm::Instruction>(op.LHS)->eraseFromParent();
4120 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4123 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4124 if (RHSBinOp->getIntrinsicID() ==
4125 llvm::Intrinsic::experimental_constrained_fmul &&
4126 (RHSBinOp->use_empty() || NegRHS)) {
4129 cast<llvm::Instruction>(op.RHS)->eraseFromParent();
4130 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4137Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4138 if (op.LHS->getType()->isPointerTy() ||
4139 op.RHS->getType()->isPointerTy())
4142 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4143 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4145 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4146 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4149 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4150 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4153 if (CanElideOverflowCheck(CGF.
getContext(), op))
4154 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4155 return EmitOverflowCheckedBinOp(op);
4160 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4161 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4167 if (op.Ty->isConstantMatrixType()) {
4168 llvm::MatrixBuilder MB(Builder);
4169 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4170 return MB.CreateAdd(op.LHS, op.RHS);
4173 if (op.Ty->isUnsignedIntegerType() &&
4174 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4175 !CanElideOverflowCheck(CGF.
getContext(), op))
4176 return EmitOverflowCheckedBinOp(op);
4178 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4179 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4180 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4183 if (op.isFixedPointOp())
4184 return EmitFixedPointBinOp(op);
4186 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4191Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4193 using llvm::ConstantInt;
4201 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4202 RHSTy = BinOp->getRHS()->getType();
4203 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4208 LHSTy = CAO->getComputationLHSType();
4209 ResultTy = CAO->getComputationResultType();
4211 LHSTy = BinOp->getLHS()->getType();
4212 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4213 LHSTy = UnOp->getSubExpr()->getType();
4214 RHSTy = UnOp->getSubExpr()->getType();
4217 Value *LHS = op.LHS;
4218 Value *RHS = op.RHS;
4223 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4227 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4228 switch (op.Opcode) {
4231 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4235 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4239 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4243 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4247 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4251 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4254 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4256 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4258 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4260 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4265 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4267 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4271 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4284 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4290 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4295Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4297 if (!op.LHS->getType()->isPointerTy()) {
4298 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4299 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4301 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4302 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4305 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4306 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4309 if (CanElideOverflowCheck(CGF.
getContext(), op))
4310 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4311 return EmitOverflowCheckedBinOp(op);
4316 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4317 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4323 if (op.Ty->isConstantMatrixType()) {
4324 llvm::MatrixBuilder MB(Builder);
4325 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4326 return MB.CreateSub(op.LHS, op.RHS);
4329 if (op.Ty->isUnsignedIntegerType() &&
4330 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4331 !CanElideOverflowCheck(CGF.
getContext(), op))
4332 return EmitOverflowCheckedBinOp(op);
4334 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4335 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4336 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4339 if (op.isFixedPointOp())
4340 return EmitFixedPointBinOp(op);
4342 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4347 if (!op.RHS->getType()->isPointerTy())
4354 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4356 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4357 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4361 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4363 llvm::Value *divisor =
nullptr;
4369 elementType = VlaSize.Type;
4370 divisor = VlaSize.NumElts;
4374 if (!eltSize.
isOne())
4390 if (elementSize.
isOne())
4399 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4402Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4404 llvm::IntegerType *Ty;
4405 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4406 Ty = cast<llvm::IntegerType>(VT->getElementType());
4408 Ty = cast<llvm::IntegerType>(LHS->
getType());
4413 llvm::Type *RHSTy = RHS->
getType();
4414 llvm::APInt RHSMax =
4415 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4416 :
llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4417 if (RHSMax.ult(Ty->getBitWidth()))
4418 return llvm::ConstantInt::get(RHSTy, RHSMax);
4419 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4423 const Twine &Name) {
4424 llvm::IntegerType *Ty;
4425 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4426 Ty = cast<llvm::IntegerType>(VT->getElementType());
4428 Ty = cast<llvm::IntegerType>(LHS->
getType());
4430 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4431 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4433 return Builder.CreateURem(
4434 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4437Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4439 if (Ops.isFixedPointOp())
4440 return EmitFixedPointBinOp(Ops);
4444 Value *RHS = Ops.RHS;
4445 if (Ops.LHS->getType() != RHS->
getType())
4446 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4448 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4449 Ops.Ty->hasSignedIntegerRepresentation() &&
4452 bool SanitizeUnsignedBase =
4453 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4454 Ops.Ty->hasUnsignedIntegerRepresentation();
4455 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4456 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4459 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4460 else if ((SanitizeBase || SanitizeExponent) &&
4461 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4462 CodeGenFunction::SanitizerScope SanScope(&CGF);
4464 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4465 llvm::Value *WidthMinusOne =
4466 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4467 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4469 if (SanitizeExponent) {
4471 std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
4478 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4481 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4482 llvm::Value *PromotedWidthMinusOne =
4483 (RHS == Ops.RHS) ? WidthMinusOne
4484 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4486 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4487 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4490 if (SanitizeUnsignedBase || CGF.
getLangOpts().CPlusPlus) {
4496 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4497 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4499 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4500 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4502 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4503 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4504 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4505 Checks.push_back(std::make_pair(
4506 BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4507 : SanitizerKind::UnsignedShiftBase));
4510 assert(!Checks.empty());
4511 EmitBinOpCheck(Checks, Ops);
4514 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4517Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4519 if (Ops.isFixedPointOp())
4520 return EmitFixedPointBinOp(Ops);
4524 Value *RHS = Ops.RHS;
4525 if (Ops.LHS->getType() != RHS->
getType())
4526 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4530 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4531 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4532 isa<llvm::IntegerType>(Ops.LHS->getType())) {
4533 CodeGenFunction::SanitizerScope SanScope(&CGF);
4534 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4535 llvm::Value *Valid = Builder.CreateICmpULE(
4536 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4537 EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
4540 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4541 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
4542 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
4550 default: llvm_unreachable(
"unexpected element type");
4551 case BuiltinType::Char_U:
4552 case BuiltinType::UChar:
4553 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4554 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4555 case BuiltinType::Char_S:
4556 case BuiltinType::SChar:
4557 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4558 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4559 case BuiltinType::UShort:
4560 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4561 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4562 case BuiltinType::Short:
4563 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4564 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4565 case BuiltinType::UInt:
4566 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4567 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4568 case BuiltinType::Int:
4569 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4570 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4571 case BuiltinType::ULong:
4572 case BuiltinType::ULongLong:
4573 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4574 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4575 case BuiltinType::Long:
4576 case BuiltinType::LongLong:
4577 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4578 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4579 case BuiltinType::Float:
4580 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4581 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4582 case BuiltinType::Double:
4583 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4584 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4585 case BuiltinType::UInt128:
4586 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4587 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4588 case BuiltinType::Int128:
4589 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4590 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4595 llvm::CmpInst::Predicate UICmpOpc,
4596 llvm::CmpInst::Predicate SICmpOpc,
4597 llvm::CmpInst::Predicate FCmpOpc,
4599 TestAndClearIgnoreResultAssign();
4604 assert(
E->getOpcode() == BO_EQ ||
4605 E->getOpcode() == BO_NE);
4609 CGF, LHS, RHS, MPT,
E->getOpcode() == BO_NE);
4611 BinOpInfo BOInfo = EmitBinOps(
E);
4612 Value *LHS = BOInfo.LHS;
4613 Value *RHS = BOInfo.RHS;
4619 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4621 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
4624 Value *FirstVecArg = LHS,
4625 *SecondVecArg = RHS;
4630 switch(
E->getOpcode()) {
4631 default: llvm_unreachable(
"is not a comparison operation");
4643 std::swap(FirstVecArg, SecondVecArg);
4650 if (ElementKind == BuiltinType::Float) {
4652 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4653 std::swap(FirstVecArg, SecondVecArg);
4661 if (ElementKind == BuiltinType::Float) {
4663 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4668 std::swap(FirstVecArg, SecondVecArg);
4673 Value *CR6Param = Builder.getInt32(CR6);
4675 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4682 llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(
Result->getType());
4683 if (ResultTy->getBitWidth() > 1 &&
4685 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
4690 if (BOInfo.isFixedPointOp()) {
4691 Result = EmitFixedPointBinOp(BOInfo);
4692 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
4693 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4695 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
4697 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
4699 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
4704 !isa<llvm::ConstantPointerNull>(LHS) &&
4705 !isa<llvm::ConstantPointerNull>(RHS)) {
4714 LHS = Builder.CreateStripInvariantGroup(LHS);
4716 RHS = Builder.CreateStripInvariantGroup(RHS);
4719 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
4725 return Builder.CreateSExt(
Result, ConvertType(
E->
getType()),
"sext");
4733 CETy = CTy->getElementType();
4735 LHS.first = Visit(
E->getLHS());
4736 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
4742 CTy->getElementType()) &&
4743 "The element types must always match.");
4746 RHS.first = Visit(
E->getRHS());
4747 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
4749 "The element types must always match.");
4752 Value *ResultR, *ResultI;
4756 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
4757 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
4761 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
4762 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
4765 if (
E->getOpcode() == BO_EQ) {
4766 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
4768 assert(
E->getOpcode() == BO_NE &&
4769 "Complex comparison other than == or != ?");
4770 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
4782 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E->getRHS())) {
4784 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4785 *SrcType = ICE->getSubExpr()->getType();
4797 bool Ignore = TestAndClearIgnoreResultAssign();
4816 RHS = Visit(
E->getRHS());
4832 RHS = Visit(
E->getRHS());
4875 Value *LHS = Visit(
E->getLHS());
4876 Value *RHS = Visit(
E->getRHS());
4878 if (LHS->
getType()->isFPOrFPVectorTy()) {
4879 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4881 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero,
"cmp");
4882 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero,
"cmp");
4884 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero,
"cmp");
4885 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero,
"cmp");
4887 Value *
And = Builder.CreateAnd(LHS, RHS);
4888 return Builder.CreateSExt(
And, ConvertType(
E->
getType()),
"sext");
4892 llvm::Type *ResTy = ConvertType(
E->
getType());
4913 if (InstrumentRegions &&
4918 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4931 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
4936 return llvm::Constant::getNullValue(ResTy);
4945 llvm::BasicBlock *ContBlock = CGF.