1f22ef01cSRoman Divacky //===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
14e580952dSDimitry Andric #include "CGCXXABI.h"
15*b5893f02SDimitry Andric #include "CGCleanup.h"
16139f7f9bSDimitry Andric #include "CGDebugInfo.h"
17f22ef01cSRoman Divacky #include "CGObjCRuntime.h"
18*b5893f02SDimitry Andric #include "CodeGenFunction.h"
19f22ef01cSRoman Divacky #include "CodeGenModule.h"
203dac3a9bSDimitry Andric #include "TargetInfo.h"
21f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h"
22f22ef01cSRoman Divacky #include "clang/AST/DeclObjC.h"
2344290647SDimitry Andric #include "clang/AST/Expr.h"
24f22ef01cSRoman Divacky #include "clang/AST/RecordLayout.h"
25f22ef01cSRoman Divacky #include "clang/AST/StmtVisitor.h"
26*b5893f02SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
27*b5893f02SDimitry Andric #include "clang/Basic/FixedPoint.h"
28f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h"
2920e90f04SDimitry Andric #include "llvm/ADT/Optional.h"
3059d1ed5bSDimitry Andric #include "llvm/IR/CFG.h"
31139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
32139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
33139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
34f9448bf3SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
35139f7f9bSDimitry Andric #include "llvm/IR/GlobalVariable.h"
36139f7f9bSDimitry Andric #include "llvm/IR/Intrinsics.h"
37139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
38f22ef01cSRoman Divacky #include <cstdarg>
39f22ef01cSRoman Divacky
40f22ef01cSRoman Divacky using namespace clang;
41f22ef01cSRoman Divacky using namespace CodeGen;
42f22ef01cSRoman Divacky using llvm::Value;
43f22ef01cSRoman Divacky
44f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
45f22ef01cSRoman Divacky // Scalar Expression Emitter
46f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
47f22ef01cSRoman Divacky
482754fe60SDimitry Andric namespace {
49f9448bf3SDimitry Andric
50f9448bf3SDimitry Andric /// Determine whether the given binary operation may overflow.
51f9448bf3SDimitry Andric /// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
52f9448bf3SDimitry Andric /// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
53f9448bf3SDimitry Andric /// the returned overflow check is precise. The returned value is 'true' for
54f9448bf3SDimitry Andric /// all other opcodes, to be conservative.
mayHaveIntegerOverflow(llvm::ConstantInt * LHS,llvm::ConstantInt * RHS,BinaryOperator::Opcode Opcode,bool Signed,llvm::APInt & Result)55f9448bf3SDimitry Andric bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
56f9448bf3SDimitry Andric BinaryOperator::Opcode Opcode, bool Signed,
57f9448bf3SDimitry Andric llvm::APInt &Result) {
58f9448bf3SDimitry Andric // Assume overflow is possible, unless we can prove otherwise.
59f9448bf3SDimitry Andric bool Overflow = true;
60f9448bf3SDimitry Andric const auto &LHSAP = LHS->getValue();
61f9448bf3SDimitry Andric const auto &RHSAP = RHS->getValue();
62f9448bf3SDimitry Andric if (Opcode == BO_Add) {
63f9448bf3SDimitry Andric if (Signed)
64f9448bf3SDimitry Andric Result = LHSAP.sadd_ov(RHSAP, Overflow);
65f9448bf3SDimitry Andric else
66f9448bf3SDimitry Andric Result = LHSAP.uadd_ov(RHSAP, Overflow);
67f9448bf3SDimitry Andric } else if (Opcode == BO_Sub) {
68f9448bf3SDimitry Andric if (Signed)
69f9448bf3SDimitry Andric Result = LHSAP.ssub_ov(RHSAP, Overflow);
70f9448bf3SDimitry Andric else
71f9448bf3SDimitry Andric Result = LHSAP.usub_ov(RHSAP, Overflow);
72f9448bf3SDimitry Andric } else if (Opcode == BO_Mul) {
73f9448bf3SDimitry Andric if (Signed)
74f9448bf3SDimitry Andric Result = LHSAP.smul_ov(RHSAP, Overflow);
75f9448bf3SDimitry Andric else
76f9448bf3SDimitry Andric Result = LHSAP.umul_ov(RHSAP, Overflow);
77f9448bf3SDimitry Andric } else if (Opcode == BO_Div || Opcode == BO_Rem) {
78f9448bf3SDimitry Andric if (Signed && !RHS->isZero())
79f9448bf3SDimitry Andric Result = LHSAP.sdiv_ov(RHSAP, Overflow);
80f9448bf3SDimitry Andric else
81f9448bf3SDimitry Andric return false;
82f9448bf3SDimitry Andric }
83f9448bf3SDimitry Andric return Overflow;
84f9448bf3SDimitry Andric }
85f9448bf3SDimitry Andric
86f22ef01cSRoman Divacky struct BinOpInfo {
87f22ef01cSRoman Divacky Value *LHS;
88f22ef01cSRoman Divacky Value *RHS;
89f22ef01cSRoman Divacky QualType Ty; // Computation Type.
90ffd1746dSEd Schouten BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
9120e90f04SDimitry Andric FPOptions FPFeatures;
92ffd1746dSEd Schouten const Expr *E; // Entire expr, for error unsupported. May not be binop.
93f37b6182SDimitry Andric
94f37b6182SDimitry Andric /// Check if the binop can result in integer overflow.
mayHaveIntegerOverflow__anon442aaf6c0111::BinOpInfo95f37b6182SDimitry Andric bool mayHaveIntegerOverflow() const {
96f37b6182SDimitry Andric // Without constant input, we can't rule out overflow.
97f9448bf3SDimitry Andric auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
98f9448bf3SDimitry Andric auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
99f37b6182SDimitry Andric if (!LHSCI || !RHSCI)
100f37b6182SDimitry Andric return true;
101f37b6182SDimitry Andric
102f9448bf3SDimitry Andric llvm::APInt Result;
103f9448bf3SDimitry Andric return ::mayHaveIntegerOverflow(
104f9448bf3SDimitry Andric LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result);
105f37b6182SDimitry Andric }
106f37b6182SDimitry Andric
107f37b6182SDimitry Andric /// Check if the binop computes a division or a remainder.
isDivremOp__anon442aaf6c0111::BinOpInfo1085517e702SDimitry Andric bool isDivremOp() const {
109f37b6182SDimitry Andric return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
110f37b6182SDimitry Andric Opcode == BO_RemAssign;
111f37b6182SDimitry Andric }
112f37b6182SDimitry Andric
113f37b6182SDimitry Andric /// Check if the binop can result in an integer division by zero.
mayHaveIntegerDivisionByZero__anon442aaf6c0111::BinOpInfo114f37b6182SDimitry Andric bool mayHaveIntegerDivisionByZero() const {
1155517e702SDimitry Andric if (isDivremOp())
116f37b6182SDimitry Andric if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
117f37b6182SDimitry Andric return CI->isZero();
118f37b6182SDimitry Andric return true;
119f37b6182SDimitry Andric }
120f37b6182SDimitry Andric
121f37b6182SDimitry Andric /// Check if the binop can result in a float division by zero.
mayHaveFloatDivisionByZero__anon442aaf6c0111::BinOpInfo122f37b6182SDimitry Andric bool mayHaveFloatDivisionByZero() const {
1235517e702SDimitry Andric if (isDivremOp())
124f37b6182SDimitry Andric if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
125f37b6182SDimitry Andric return CFP->isZero();
126f37b6182SDimitry Andric return true;
127f37b6182SDimitry Andric }
128f22ef01cSRoman Divacky };
129f22ef01cSRoman Divacky
MustVisitNullValue(const Expr * E)1302754fe60SDimitry Andric static bool MustVisitNullValue(const Expr *E) {
1312754fe60SDimitry Andric // If a null pointer expression's type is the C++0x nullptr_t, then
1322754fe60SDimitry Andric // it's not necessarily a simple constant and it must be evaluated
1332754fe60SDimitry Andric // for its potential side effects.
1342754fe60SDimitry Andric return E->getType()->isNullPtrType();
1352754fe60SDimitry Andric }
1362754fe60SDimitry Andric
13720e90f04SDimitry Andric /// If \p E is a widened promoted integer, get its base (unpromoted) type.
getUnwidenedIntegerType(const ASTContext & Ctx,const Expr * E)13820e90f04SDimitry Andric static llvm::Optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
13920e90f04SDimitry Andric const Expr *E) {
14020e90f04SDimitry Andric const Expr *Base = E->IgnoreImpCasts();
14120e90f04SDimitry Andric if (E == Base)
14220e90f04SDimitry Andric return llvm::None;
14320e90f04SDimitry Andric
14420e90f04SDimitry Andric QualType BaseTy = Base->getType();
14520e90f04SDimitry Andric if (!BaseTy->isPromotableIntegerType() ||
14620e90f04SDimitry Andric Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
14720e90f04SDimitry Andric return llvm::None;
14820e90f04SDimitry Andric
14920e90f04SDimitry Andric return BaseTy;
15020e90f04SDimitry Andric }
15120e90f04SDimitry Andric
15220e90f04SDimitry Andric /// Check if \p E is a widened promoted integer.
IsWidenedIntegerOp(const ASTContext & Ctx,const Expr * E)15320e90f04SDimitry Andric static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
15420e90f04SDimitry Andric return getUnwidenedIntegerType(Ctx, E).hasValue();
15520e90f04SDimitry Andric }
15620e90f04SDimitry Andric
15720e90f04SDimitry Andric /// Check if we can skip the overflow check for \p Op.
CanElideOverflowCheck(const ASTContext & Ctx,const BinOpInfo & Op)15820e90f04SDimitry Andric static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
15920e90f04SDimitry Andric assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
16020e90f04SDimitry Andric "Expected a unary or binary operator");
16120e90f04SDimitry Andric
162f37b6182SDimitry Andric // If the binop has constant inputs and we can prove there is no overflow,
163f37b6182SDimitry Andric // we can elide the overflow check.
164f37b6182SDimitry Andric if (!Op.mayHaveIntegerOverflow())
165f37b6182SDimitry Andric return true;
166f37b6182SDimitry Andric
167f37b6182SDimitry Andric // If a unary op has a widened operand, the op cannot overflow.
16820e90f04SDimitry Andric if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
1694ba319b5SDimitry Andric return !UO->canOverflow();
17020e90f04SDimitry Andric
171f37b6182SDimitry Andric // We usually don't need overflow checks for binops with widened operands.
172f37b6182SDimitry Andric // Multiplication with promoted unsigned operands is a special case.
17320e90f04SDimitry Andric const auto *BO = cast<BinaryOperator>(Op.E);
17420e90f04SDimitry Andric auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
17520e90f04SDimitry Andric if (!OptionalLHSTy)
17620e90f04SDimitry Andric return false;
17720e90f04SDimitry Andric
17820e90f04SDimitry Andric auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
17920e90f04SDimitry Andric if (!OptionalRHSTy)
18020e90f04SDimitry Andric return false;
18120e90f04SDimitry Andric
18220e90f04SDimitry Andric QualType LHSTy = *OptionalLHSTy;
18320e90f04SDimitry Andric QualType RHSTy = *OptionalRHSTy;
18420e90f04SDimitry Andric
185f37b6182SDimitry Andric // This is the simple case: binops without unsigned multiplication, and with
186f37b6182SDimitry Andric // widened operands. No overflow check is needed here.
18720e90f04SDimitry Andric if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
18820e90f04SDimitry Andric !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
18920e90f04SDimitry Andric return true;
19020e90f04SDimitry Andric
191f37b6182SDimitry Andric // For unsigned multiplication the overflow check can be elided if either one
192f37b6182SDimitry Andric // of the unpromoted types are less than half the size of the promoted type.
19320e90f04SDimitry Andric unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
19420e90f04SDimitry Andric return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
19520e90f04SDimitry Andric (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
19620e90f04SDimitry Andric }
19720e90f04SDimitry Andric
19820e90f04SDimitry Andric /// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions.
updateFastMathFlags(llvm::FastMathFlags & FMF,FPOptions FPFeatures)19920e90f04SDimitry Andric static void updateFastMathFlags(llvm::FastMathFlags &FMF,
20020e90f04SDimitry Andric FPOptions FPFeatures) {
20120e90f04SDimitry Andric FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement());
20220e90f04SDimitry Andric }
20320e90f04SDimitry Andric
20420e90f04SDimitry Andric /// Propagate fast-math flags from \p Op to the instruction in \p V.
propagateFMFlags(Value * V,const BinOpInfo & Op)20520e90f04SDimitry Andric static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) {
20620e90f04SDimitry Andric if (auto *I = dyn_cast<llvm::Instruction>(V)) {
20720e90f04SDimitry Andric llvm::FastMathFlags FMF = I->getFastMathFlags();
20820e90f04SDimitry Andric updateFastMathFlags(FMF, Op.FPFeatures);
20920e90f04SDimitry Andric I->setFastMathFlags(FMF);
21020e90f04SDimitry Andric }
21120e90f04SDimitry Andric return V;
21220e90f04SDimitry Andric }
21320e90f04SDimitry Andric
214f22ef01cSRoman Divacky class ScalarExprEmitter
215f22ef01cSRoman Divacky : public StmtVisitor<ScalarExprEmitter, Value*> {
216f22ef01cSRoman Divacky CodeGenFunction &CGF;
217f22ef01cSRoman Divacky CGBuilderTy &Builder;
218f22ef01cSRoman Divacky bool IgnoreResultAssign;
219f22ef01cSRoman Divacky llvm::LLVMContext &VMContext;
220f22ef01cSRoman Divacky public:
221f22ef01cSRoman Divacky
ScalarExprEmitter(CodeGenFunction & cgf,bool ira=false)222f22ef01cSRoman Divacky ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false)
223f22ef01cSRoman Divacky : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
224f22ef01cSRoman Divacky VMContext(cgf.getLLVMContext()) {
225f22ef01cSRoman Divacky }
226f22ef01cSRoman Divacky
227f22ef01cSRoman Divacky //===--------------------------------------------------------------------===//
228f22ef01cSRoman Divacky // Utilities
229f22ef01cSRoman Divacky //===--------------------------------------------------------------------===//
230f22ef01cSRoman Divacky
TestAndClearIgnoreResultAssign()231f22ef01cSRoman Divacky bool TestAndClearIgnoreResultAssign() {
232f22ef01cSRoman Divacky bool I = IgnoreResultAssign;
233f22ef01cSRoman Divacky IgnoreResultAssign = false;
234f22ef01cSRoman Divacky return I;
235f22ef01cSRoman Divacky }
236f22ef01cSRoman Divacky
ConvertType(QualType T)2376122f3e6SDimitry Andric llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
EmitLValue(const Expr * E)238f22ef01cSRoman Divacky LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
EmitCheckedLValue(const Expr * E,CodeGenFunction::TypeCheckKind TCK)2393861d79fSDimitry Andric LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
2403861d79fSDimitry Andric return CGF.EmitCheckedLValue(E, TCK);
2413861d79fSDimitry Andric }
2423861d79fSDimitry Andric
24333956c43SDimitry Andric void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
24439d628a0SDimitry Andric const BinOpInfo &Info);
245f22ef01cSRoman Divacky
EmitLoadOfLValue(LValue LV,SourceLocation Loc)246f785676fSDimitry Andric Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
247f785676fSDimitry Andric return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
248f22ef01cSRoman Divacky }
249f22ef01cSRoman Divacky
EmitLValueAlignmentAssumption(const Expr * E,Value * V)25039d628a0SDimitry Andric void EmitLValueAlignmentAssumption(const Expr *E, Value *V) {
25139d628a0SDimitry Andric const AlignValueAttr *AVAttr = nullptr;
25239d628a0SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
25339d628a0SDimitry Andric const ValueDecl *VD = DRE->getDecl();
25439d628a0SDimitry Andric
25539d628a0SDimitry Andric if (VD->getType()->isReferenceType()) {
25639d628a0SDimitry Andric if (const auto *TTy =
25739d628a0SDimitry Andric dyn_cast<TypedefType>(VD->getType().getNonReferenceType()))
25839d628a0SDimitry Andric AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
25939d628a0SDimitry Andric } else {
26039d628a0SDimitry Andric // Assumptions for function parameters are emitted at the start of the
261*b5893f02SDimitry Andric // function, so there is no need to repeat that here,
262*b5893f02SDimitry Andric // unless the alignment-assumption sanitizer is enabled,
263*b5893f02SDimitry Andric // then we prefer the assumption over alignment attribute
264*b5893f02SDimitry Andric // on IR function param.
265*b5893f02SDimitry Andric if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment))
26639d628a0SDimitry Andric return;
26739d628a0SDimitry Andric
26839d628a0SDimitry Andric AVAttr = VD->getAttr<AlignValueAttr>();
26939d628a0SDimitry Andric }
27039d628a0SDimitry Andric }
27139d628a0SDimitry Andric
27239d628a0SDimitry Andric if (!AVAttr)
27339d628a0SDimitry Andric if (const auto *TTy =
27439d628a0SDimitry Andric dyn_cast<TypedefType>(E->getType()))
27539d628a0SDimitry Andric AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
27639d628a0SDimitry Andric
27739d628a0SDimitry Andric if (!AVAttr)
27839d628a0SDimitry Andric return;
27939d628a0SDimitry Andric
28039d628a0SDimitry Andric Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
28139d628a0SDimitry Andric llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
282*b5893f02SDimitry Andric CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(),
283*b5893f02SDimitry Andric AlignmentCI->getZExtValue());
28439d628a0SDimitry Andric }
28539d628a0SDimitry Andric
286f22ef01cSRoman Divacky /// EmitLoadOfLValue - Given an expression with complex type that represents a
287f22ef01cSRoman Divacky /// value l-value, this method emits the address of the l-value, then loads
288f22ef01cSRoman Divacky /// and returns the result.
EmitLoadOfLValue(const Expr * E)289f22ef01cSRoman Divacky Value *EmitLoadOfLValue(const Expr *E) {
29039d628a0SDimitry Andric Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
291f785676fSDimitry Andric E->getExprLoc());
29239d628a0SDimitry Andric
29339d628a0SDimitry Andric EmitLValueAlignmentAssumption(E, V);
29439d628a0SDimitry Andric return V;
295f22ef01cSRoman Divacky }
296f22ef01cSRoman Divacky
297f22ef01cSRoman Divacky /// EmitConversionToBool - Convert the specified expression value to a
298f22ef01cSRoman Divacky /// boolean (i1) truth value. This is equivalent to "Val != 0".
299f22ef01cSRoman Divacky Value *EmitConversionToBool(Value *Src, QualType DstTy);
300f22ef01cSRoman Divacky
3010623d748SDimitry Andric /// Emit a check that a conversion to or from a floating-point type does not
3020623d748SDimitry Andric /// overflow.
3033861d79fSDimitry Andric void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
3040623d748SDimitry Andric Value *Src, QualType SrcType, QualType DstType,
3050623d748SDimitry Andric llvm::Type *DstTy, SourceLocation Loc);
3063861d79fSDimitry Andric
3074ba319b5SDimitry Andric /// Known implicit conversion check kinds.
3084ba319b5SDimitry Andric /// Keep in sync with the enum of the same name in ubsan_handlers.h
3094ba319b5SDimitry Andric enum ImplicitConversionCheckKind : unsigned char {
310*b5893f02SDimitry Andric ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
311*b5893f02SDimitry Andric ICCK_UnsignedIntegerTruncation = 1,
312*b5893f02SDimitry Andric ICCK_SignedIntegerTruncation = 2,
313*b5893f02SDimitry Andric ICCK_IntegerSignChange = 3,
314*b5893f02SDimitry Andric ICCK_SignedIntegerTruncationOrSignChange = 4,
3154ba319b5SDimitry Andric };
3164ba319b5SDimitry Andric
3174ba319b5SDimitry Andric /// Emit a check that an [implicit] truncation of an integer does not
3184ba319b5SDimitry Andric /// discard any bits. It is not UB, so we use the value after truncation.
3194ba319b5SDimitry Andric void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst,
3204ba319b5SDimitry Andric QualType DstType, SourceLocation Loc);
3214ba319b5SDimitry Andric
322*b5893f02SDimitry Andric /// Emit a check that an [implicit] conversion of an integer does not change
323*b5893f02SDimitry Andric /// the sign of the value. It is not UB, so we use the value after conversion.
324*b5893f02SDimitry Andric /// NOTE: Src and Dst may be the exact same value! (point to the same thing)
325*b5893f02SDimitry Andric void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
326*b5893f02SDimitry Andric QualType DstType, SourceLocation Loc);
327*b5893f02SDimitry Andric
3280623d748SDimitry Andric /// Emit a conversion from the specified type to the specified destination
3290623d748SDimitry Andric /// type, both of which are LLVM scalar types.
3304ba319b5SDimitry Andric struct ScalarConversionOpts {
3314ba319b5SDimitry Andric bool TreatBooleanAsSigned;
3324ba319b5SDimitry Andric bool EmitImplicitIntegerTruncationChecks;
333*b5893f02SDimitry Andric bool EmitImplicitIntegerSignChangeChecks;
334f22ef01cSRoman Divacky
ScalarConversionOpts__anon442aaf6c0111::ScalarExprEmitter::ScalarConversionOpts3354ba319b5SDimitry Andric ScalarConversionOpts()
3364ba319b5SDimitry Andric : TreatBooleanAsSigned(false),
337*b5893f02SDimitry Andric EmitImplicitIntegerTruncationChecks(false),
338*b5893f02SDimitry Andric EmitImplicitIntegerSignChangeChecks(false) {}
339*b5893f02SDimitry Andric
ScalarConversionOpts__anon442aaf6c0111::ScalarExprEmitter::ScalarConversionOpts340*b5893f02SDimitry Andric ScalarConversionOpts(clang::SanitizerSet SanOpts)
341*b5893f02SDimitry Andric : TreatBooleanAsSigned(false),
342*b5893f02SDimitry Andric EmitImplicitIntegerTruncationChecks(
343*b5893f02SDimitry Andric SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
344*b5893f02SDimitry Andric EmitImplicitIntegerSignChangeChecks(
345*b5893f02SDimitry Andric SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {}
3464ba319b5SDimitry Andric };
3474ba319b5SDimitry Andric Value *
3484ba319b5SDimitry Andric EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
3494ba319b5SDimitry Andric SourceLocation Loc,
3504ba319b5SDimitry Andric ScalarConversionOpts Opts = ScalarConversionOpts());
3510623d748SDimitry Andric
352*b5893f02SDimitry Andric Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy,
353*b5893f02SDimitry Andric SourceLocation Loc);
354*b5893f02SDimitry Andric
3550623d748SDimitry Andric /// Emit a conversion from the specified complex type to the specified
3560623d748SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
357f22ef01cSRoman Divacky Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
3580623d748SDimitry Andric QualType SrcTy, QualType DstTy,
3590623d748SDimitry Andric SourceLocation Loc);
360f22ef01cSRoman Divacky
361f22ef01cSRoman Divacky /// EmitNullValue - Emit a value that corresponds to null for the given type.
362f22ef01cSRoman Divacky Value *EmitNullValue(QualType Ty);
363f22ef01cSRoman Divacky
3642754fe60SDimitry Andric /// EmitFloatToBoolConversion - Perform an FP to boolean conversion.
EmitFloatToBoolConversion(Value * V)3652754fe60SDimitry Andric Value *EmitFloatToBoolConversion(Value *V) {
3662754fe60SDimitry Andric // Compare against 0.0 for fp scalars.
3672754fe60SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
3682754fe60SDimitry Andric return Builder.CreateFCmpUNE(V, Zero, "tobool");
3692754fe60SDimitry Andric }
3702754fe60SDimitry Andric
3712754fe60SDimitry Andric /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion.
EmitPointerToBoolConversion(Value * V,QualType QT)37244290647SDimitry Andric Value *EmitPointerToBoolConversion(Value *V, QualType QT) {
37344290647SDimitry Andric Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT);
37444290647SDimitry Andric
3752754fe60SDimitry Andric return Builder.CreateICmpNE(V, Zero, "tobool");
3762754fe60SDimitry Andric }
3772754fe60SDimitry Andric
EmitIntToBoolConversion(Value * V)3782754fe60SDimitry Andric Value *EmitIntToBoolConversion(Value *V) {
3792754fe60SDimitry Andric // Because of the type rules of C, we often end up computing a
3802754fe60SDimitry Andric // logical value, then zero extending it to int, then wanting it
3812754fe60SDimitry Andric // as a logical value again. Optimize this common case.
3822754fe60SDimitry Andric if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
3832754fe60SDimitry Andric if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
3842754fe60SDimitry Andric Value *Result = ZI->getOperand(0);
3852754fe60SDimitry Andric // If there aren't any more uses, zap the instruction to save space.
3862754fe60SDimitry Andric // Note that there can be more uses, for example if this
3872754fe60SDimitry Andric // is the result of an assignment.
3882754fe60SDimitry Andric if (ZI->use_empty())
3892754fe60SDimitry Andric ZI->eraseFromParent();
3902754fe60SDimitry Andric return Result;
3912754fe60SDimitry Andric }
3922754fe60SDimitry Andric }
3932754fe60SDimitry Andric
3943b0f4066SDimitry Andric return Builder.CreateIsNotNull(V, "tobool");
3952754fe60SDimitry Andric }
3962754fe60SDimitry Andric
397f22ef01cSRoman Divacky //===--------------------------------------------------------------------===//
398f22ef01cSRoman Divacky // Visitor Methods
399f22ef01cSRoman Divacky //===--------------------------------------------------------------------===//
400f22ef01cSRoman Divacky
Visit(Expr * E)4012754fe60SDimitry Andric Value *Visit(Expr *E) {
40233956c43SDimitry Andric ApplyDebugLocation DL(CGF, E);
4032754fe60SDimitry Andric return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
4042754fe60SDimitry Andric }
4052754fe60SDimitry Andric
VisitStmt(Stmt * S)406f22ef01cSRoman Divacky Value *VisitStmt(Stmt *S) {
407f22ef01cSRoman Divacky S->dump(CGF.getContext().getSourceManager());
4086122f3e6SDimitry Andric llvm_unreachable("Stmt can't have complex result type!");
409f22ef01cSRoman Divacky }
410f22ef01cSRoman Divacky Value *VisitExpr(Expr *S);
411f22ef01cSRoman Divacky
VisitConstantExpr(ConstantExpr * E)412*b5893f02SDimitry Andric Value *VisitConstantExpr(ConstantExpr *E) {
413*b5893f02SDimitry Andric return Visit(E->getSubExpr());
414*b5893f02SDimitry Andric }
VisitParenExpr(ParenExpr * PE)4152754fe60SDimitry Andric Value *VisitParenExpr(ParenExpr *PE) {
4162754fe60SDimitry Andric return Visit(PE->getSubExpr());
4172754fe60SDimitry Andric }
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)41817a519f9SDimitry Andric Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
41917a519f9SDimitry Andric return Visit(E->getReplacement());
42017a519f9SDimitry Andric }
VisitGenericSelectionExpr(GenericSelectionExpr * GE)4213b0f4066SDimitry Andric Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
4223b0f4066SDimitry Andric return Visit(GE->getResultExpr());
4233b0f4066SDimitry Andric }
VisitCoawaitExpr(CoawaitExpr * S)42420e90f04SDimitry Andric Value *VisitCoawaitExpr(CoawaitExpr *S) {
42520e90f04SDimitry Andric return CGF.EmitCoawaitExpr(*S).getScalarVal();
42620e90f04SDimitry Andric }
VisitCoyieldExpr(CoyieldExpr * S)42720e90f04SDimitry Andric Value *VisitCoyieldExpr(CoyieldExpr *S) {
42820e90f04SDimitry Andric return CGF.EmitCoyieldExpr(*S).getScalarVal();
42920e90f04SDimitry Andric }
VisitUnaryCoawait(const UnaryOperator * E)43020e90f04SDimitry Andric Value *VisitUnaryCoawait(const UnaryOperator *E) {
43120e90f04SDimitry Andric return Visit(E->getSubExpr());
43220e90f04SDimitry Andric }
433f22ef01cSRoman Divacky
434f22ef01cSRoman Divacky // Leaves.
VisitIntegerLiteral(const IntegerLiteral * E)435f22ef01cSRoman Divacky Value *VisitIntegerLiteral(const IntegerLiteral *E) {
4363b0f4066SDimitry Andric return Builder.getInt(E->getValue());
437f22ef01cSRoman Divacky }
VisitFixedPointLiteral(const FixedPointLiteral * E)4384ba319b5SDimitry Andric Value *VisitFixedPointLiteral(const FixedPointLiteral *E) {
4394ba319b5SDimitry Andric return Builder.getInt(E->getValue());
4404ba319b5SDimitry Andric }
VisitFloatingLiteral(const FloatingLiteral * E)441f22ef01cSRoman Divacky Value *VisitFloatingLiteral(const FloatingLiteral *E) {
442f22ef01cSRoman Divacky return llvm::ConstantFP::get(VMContext, E->getValue());
443f22ef01cSRoman Divacky }
VisitCharacterLiteral(const CharacterLiteral * E)444f22ef01cSRoman Divacky Value *VisitCharacterLiteral(const CharacterLiteral *E) {
445f22ef01cSRoman Divacky return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
446f22ef01cSRoman Divacky }
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * E)447dff0c46cSDimitry Andric Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
448dff0c46cSDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
449dff0c46cSDimitry Andric }
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * E)450f22ef01cSRoman Divacky Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
451f22ef01cSRoman Divacky return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
452f22ef01cSRoman Divacky }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)453ffd1746dSEd Schouten Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
454f22ef01cSRoman Divacky return EmitNullValue(E->getType());
455f22ef01cSRoman Divacky }
VisitGNUNullExpr(const GNUNullExpr * E)456f22ef01cSRoman Divacky Value *VisitGNUNullExpr(const GNUNullExpr *E) {
457f22ef01cSRoman Divacky return EmitNullValue(E->getType());
458f22ef01cSRoman Divacky }
459e580952dSDimitry Andric Value *VisitOffsetOfExpr(OffsetOfExpr *E);
4603b0f4066SDimitry Andric Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
VisitAddrLabelExpr(const AddrLabelExpr * E)461f22ef01cSRoman Divacky Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
462f22ef01cSRoman Divacky llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
463f22ef01cSRoman Divacky return Builder.CreateBitCast(V, ConvertType(E->getType()));
464f22ef01cSRoman Divacky }
465f22ef01cSRoman Divacky
VisitSizeOfPackExpr(SizeOfPackExpr * E)4662754fe60SDimitry Andric Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
4673b0f4066SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength());
4682754fe60SDimitry Andric }
4692754fe60SDimitry Andric
VisitPseudoObjectExpr(PseudoObjectExpr * E)470dff0c46cSDimitry Andric Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
471dff0c46cSDimitry Andric return CGF.EmitPseudoObjectRValue(E).getScalarVal();
472dff0c46cSDimitry Andric }
473dff0c46cSDimitry Andric
VisitOpaqueValueExpr(OpaqueValueExpr * E)4742754fe60SDimitry Andric Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
4752754fe60SDimitry Andric if (E->isGLValue())
4764ba319b5SDimitry Andric return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E),
4774ba319b5SDimitry Andric E->getExprLoc());
4782754fe60SDimitry Andric
4792754fe60SDimitry Andric // Otherwise, assume the mapping is the scalar directly.
4804ba319b5SDimitry Andric return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal();
4812754fe60SDimitry Andric }
4822754fe60SDimitry Andric
483f22ef01cSRoman Divacky // l-values.
VisitDeclRefExpr(DeclRefExpr * E)484f22ef01cSRoman Divacky Value *VisitDeclRefExpr(DeclRefExpr *E) {
4859a199699SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
486*b5893f02SDimitry Andric return CGF.emitScalarConstant(Constant, E);
487f22ef01cSRoman Divacky return EmitLoadOfLValue(E);
4882754fe60SDimitry Andric }
4892754fe60SDimitry Andric
VisitObjCSelectorExpr(ObjCSelectorExpr * E)490f22ef01cSRoman Divacky Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
491f22ef01cSRoman Divacky return CGF.EmitObjCSelectorExpr(E);
492f22ef01cSRoman Divacky }
VisitObjCProtocolExpr(ObjCProtocolExpr * E)493f22ef01cSRoman Divacky Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
494f22ef01cSRoman Divacky return CGF.EmitObjCProtocolExpr(E);
495f22ef01cSRoman Divacky }
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)496f22ef01cSRoman Divacky Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
497f22ef01cSRoman Divacky return EmitLoadOfLValue(E);
498f22ef01cSRoman Divacky }
VisitObjCMessageExpr(ObjCMessageExpr * E)499f22ef01cSRoman Divacky Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
5003b0f4066SDimitry Andric if (E->getMethodDecl() &&
50159d1ed5bSDimitry Andric E->getMethodDecl()->getReturnType()->isReferenceType())
5023b0f4066SDimitry Andric return EmitLoadOfLValue(E);
503f22ef01cSRoman Divacky return CGF.EmitObjCMessageExpr(E).getScalarVal();
504f22ef01cSRoman Divacky }
505f22ef01cSRoman Divacky
VisitObjCIsaExpr(ObjCIsaExpr * E)506f22ef01cSRoman Divacky Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
507f22ef01cSRoman Divacky LValue LV = CGF.EmitObjCIsaExpr(E);
508f785676fSDimitry Andric Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal();
509f22ef01cSRoman Divacky return V;
510f22ef01cSRoman Divacky }
511f22ef01cSRoman Divacky
VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * E)51220e90f04SDimitry Andric Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
51320e90f04SDimitry Andric VersionTuple Version = E->getVersion();
51420e90f04SDimitry Andric
51520e90f04SDimitry Andric // If we're checking for a platform older than our minimum deployment
51620e90f04SDimitry Andric // target, we can fold the check away.
51720e90f04SDimitry Andric if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
51820e90f04SDimitry Andric return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
51920e90f04SDimitry Andric
52020e90f04SDimitry Andric Optional<unsigned> Min = Version.getMinor(), SMin = Version.getSubminor();
52120e90f04SDimitry Andric llvm::Value *Args[] = {
52220e90f04SDimitry Andric llvm::ConstantInt::get(CGF.CGM.Int32Ty, Version.getMajor()),
52320e90f04SDimitry Andric llvm::ConstantInt::get(CGF.CGM.Int32Ty, Min ? *Min : 0),
52420e90f04SDimitry Andric llvm::ConstantInt::get(CGF.CGM.Int32Ty, SMin ? *SMin : 0),
52520e90f04SDimitry Andric };
52620e90f04SDimitry Andric
52720e90f04SDimitry Andric return CGF.EmitBuiltinAvailable(Args);
52820e90f04SDimitry Andric }
52920e90f04SDimitry Andric
530f22ef01cSRoman Divacky Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
531f22ef01cSRoman Divacky Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
532f785676fSDimitry Andric Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
533f22ef01cSRoman Divacky Value *VisitMemberExpr(MemberExpr *E);
VisitExtVectorElementExpr(Expr * E)534f22ef01cSRoman Divacky Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)535f22ef01cSRoman Divacky Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
536f22ef01cSRoman Divacky return EmitLoadOfLValue(E);
537f22ef01cSRoman Divacky }
538f22ef01cSRoman Divacky
539f22ef01cSRoman Divacky Value *VisitInitListExpr(InitListExpr *E);
540f22ef01cSRoman Divacky
VisitArrayInitIndexExpr(ArrayInitIndexExpr * E)54144290647SDimitry Andric Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
54244290647SDimitry Andric assert(CGF.getArrayInitIndex() &&
54344290647SDimitry Andric "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
54444290647SDimitry Andric return CGF.getArrayInitIndex();
54544290647SDimitry Andric }
54644290647SDimitry Andric
VisitImplicitValueInitExpr(const ImplicitValueInitExpr * E)547f22ef01cSRoman Divacky Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
548139f7f9bSDimitry Andric return EmitNullValue(E->getType());
549f22ef01cSRoman Divacky }
VisitExplicitCastExpr(ExplicitCastExpr * E)55017a519f9SDimitry Andric Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
5510623d748SDimitry Andric CGF.CGM.EmitExplicitCastExprType(E, &CGF);
55217a519f9SDimitry Andric return VisitCastExpr(E);
553f22ef01cSRoman Divacky }
55417a519f9SDimitry Andric Value *VisitCastExpr(CastExpr *E);
555f22ef01cSRoman Divacky
VisitCallExpr(const CallExpr * E)556f22ef01cSRoman Divacky Value *VisitCallExpr(const CallExpr *E) {
55733956c43SDimitry Andric if (E->getCallReturnType(CGF.getContext())->isReferenceType())
558f22ef01cSRoman Divacky return EmitLoadOfLValue(E);
559f22ef01cSRoman Divacky
56039d628a0SDimitry Andric Value *V = CGF.EmitCallExpr(E).getScalarVal();
56139d628a0SDimitry Andric
56239d628a0SDimitry Andric EmitLValueAlignmentAssumption(E, V);
56339d628a0SDimitry Andric return V;
564f22ef01cSRoman Divacky }
565f22ef01cSRoman Divacky
566f22ef01cSRoman Divacky Value *VisitStmtExpr(const StmtExpr *E);
567f22ef01cSRoman Divacky
568f22ef01cSRoman Divacky // Unary Operators.
VisitUnaryPostDec(const UnaryOperator * E)569f22ef01cSRoman Divacky Value *VisitUnaryPostDec(const UnaryOperator *E) {
570ffd1746dSEd Schouten LValue LV = EmitLValue(E->getSubExpr());
571ffd1746dSEd Schouten return EmitScalarPrePostIncDec(E, LV, false, false);
572f22ef01cSRoman Divacky }
VisitUnaryPostInc(const UnaryOperator * E)573f22ef01cSRoman Divacky Value *VisitUnaryPostInc(const UnaryOperator *E) {
574ffd1746dSEd Schouten LValue LV = EmitLValue(E->getSubExpr());
575ffd1746dSEd Schouten return EmitScalarPrePostIncDec(E, LV, true, false);
576f22ef01cSRoman Divacky }
VisitUnaryPreDec(const UnaryOperator * E)577f22ef01cSRoman Divacky Value *VisitUnaryPreDec(const UnaryOperator *E) {
578ffd1746dSEd Schouten LValue LV = EmitLValue(E->getSubExpr());
579ffd1746dSEd Schouten return EmitScalarPrePostIncDec(E, LV, false, true);
580f22ef01cSRoman Divacky }
VisitUnaryPreInc(const UnaryOperator * E)581f22ef01cSRoman Divacky Value *VisitUnaryPreInc(const UnaryOperator *E) {
582ffd1746dSEd Schouten LValue LV = EmitLValue(E->getSubExpr());
583ffd1746dSEd Schouten return EmitScalarPrePostIncDec(E, LV, true, true);
584f22ef01cSRoman Divacky }
585ffd1746dSEd Schouten
58633956c43SDimitry Andric llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E,
5872754fe60SDimitry Andric llvm::Value *InVal,
5882754fe60SDimitry Andric bool IsInc);
5892754fe60SDimitry Andric
590ffd1746dSEd Schouten llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
591ffd1746dSEd Schouten bool isInc, bool isPre);
592ffd1746dSEd Schouten
593ffd1746dSEd Schouten
VisitUnaryAddrOf(const UnaryOperator * E)594f22ef01cSRoman Divacky Value *VisitUnaryAddrOf(const UnaryOperator *E) {
5952754fe60SDimitry Andric if (isa<MemberPointerType>(E->getType())) // never sugared
5962754fe60SDimitry Andric return CGF.CGM.getMemberPointerConstant(E);
5972754fe60SDimitry Andric
5980623d748SDimitry Andric return EmitLValue(E->getSubExpr()).getPointer();
599f22ef01cSRoman Divacky }
VisitUnaryDeref(const UnaryOperator * E)6002754fe60SDimitry Andric Value *VisitUnaryDeref(const UnaryOperator *E) {
6012754fe60SDimitry Andric if (E->getType()->isVoidType())
6022754fe60SDimitry Andric return Visit(E->getSubExpr()); // the actual value should be unused
6032754fe60SDimitry Andric return EmitLoadOfLValue(E);
6042754fe60SDimitry Andric }
VisitUnaryPlus(const UnaryOperator * E)605f22ef01cSRoman Divacky Value *VisitUnaryPlus(const UnaryOperator *E) {
606f22ef01cSRoman Divacky // This differs from gcc, though, most likely due to a bug in gcc.
607f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
608f22ef01cSRoman Divacky return Visit(E->getSubExpr());
609f22ef01cSRoman Divacky }
610f22ef01cSRoman Divacky Value *VisitUnaryMinus (const UnaryOperator *E);
611f22ef01cSRoman Divacky Value *VisitUnaryNot (const UnaryOperator *E);
612f22ef01cSRoman Divacky Value *VisitUnaryLNot (const UnaryOperator *E);
613f22ef01cSRoman Divacky Value *VisitUnaryReal (const UnaryOperator *E);
614f22ef01cSRoman Divacky Value *VisitUnaryImag (const UnaryOperator *E);
VisitUnaryExtension(const UnaryOperator * E)615f22ef01cSRoman Divacky Value *VisitUnaryExtension(const UnaryOperator *E) {
616f22ef01cSRoman Divacky return Visit(E->getSubExpr());
617f22ef01cSRoman Divacky }
618f22ef01cSRoman Divacky
619f22ef01cSRoman Divacky // C++
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * E)6206122f3e6SDimitry Andric Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {
6216122f3e6SDimitry Andric return EmitLoadOfLValue(E);
6226122f3e6SDimitry Andric }
6236122f3e6SDimitry Andric
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)624f22ef01cSRoman Divacky Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
625f22ef01cSRoman Divacky return Visit(DAE->getExpr());
626f22ef01cSRoman Divacky }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)627284c1978SDimitry Andric Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
628284c1978SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
629284c1978SDimitry Andric return Visit(DIE->getExpr());
630284c1978SDimitry Andric }
VisitCXXThisExpr(CXXThisExpr * TE)631f22ef01cSRoman Divacky Value *VisitCXXThisExpr(CXXThisExpr *TE) {
632f22ef01cSRoman Divacky return CGF.LoadCXXThis();
633f22ef01cSRoman Divacky }
634f22ef01cSRoman Divacky
63520e90f04SDimitry Andric Value *VisitExprWithCleanups(ExprWithCleanups *E);
VisitCXXNewExpr(const CXXNewExpr * E)636f22ef01cSRoman Divacky Value *VisitCXXNewExpr(const CXXNewExpr *E) {
637f22ef01cSRoman Divacky return CGF.EmitCXXNewExpr(E);
638f22ef01cSRoman Divacky }
VisitCXXDeleteExpr(const CXXDeleteExpr * E)639f22ef01cSRoman Divacky Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
640f22ef01cSRoman Divacky CGF.EmitCXXDeleteExpr(E);
64159d1ed5bSDimitry Andric return nullptr;
6422754fe60SDimitry Andric }
6432754fe60SDimitry Andric
VisitTypeTraitExpr(const TypeTraitExpr * E)64459d1ed5bSDimitry Andric Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
6452754fe60SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
646f22ef01cSRoman Divacky }
647f22ef01cSRoman Divacky
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)6483b0f4066SDimitry Andric Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
6493b0f4066SDimitry Andric return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
6503b0f4066SDimitry Andric }
6513b0f4066SDimitry Andric
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)6523b0f4066SDimitry Andric Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
6533b0f4066SDimitry Andric return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
6543b0f4066SDimitry Andric }
6553b0f4066SDimitry Andric
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)656f22ef01cSRoman Divacky Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) {
657f22ef01cSRoman Divacky // C++ [expr.pseudo]p1:
658f22ef01cSRoman Divacky // The result shall only be used as the operand for the function call
659f22ef01cSRoman Divacky // operator (), and the result of such a call has type void. The only
660f22ef01cSRoman Divacky // effect is the evaluation of the postfix-expression before the dot or
661f22ef01cSRoman Divacky // arrow.
662f22ef01cSRoman Divacky CGF.EmitScalarExpr(E->getBase());
66359d1ed5bSDimitry Andric return nullptr;
664f22ef01cSRoman Divacky }
665f22ef01cSRoman Divacky
VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr * E)666f22ef01cSRoman Divacky Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
667f22ef01cSRoman Divacky return EmitNullValue(E->getType());
668f22ef01cSRoman Divacky }
669f22ef01cSRoman Divacky
VisitCXXThrowExpr(const CXXThrowExpr * E)670f22ef01cSRoman Divacky Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
671f22ef01cSRoman Divacky CGF.EmitCXXThrowExpr(E);
67259d1ed5bSDimitry Andric return nullptr;
673f22ef01cSRoman Divacky }
674f22ef01cSRoman Divacky
VisitCXXNoexceptExpr(const CXXNoexceptExpr * E)6752754fe60SDimitry Andric Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
6763b0f4066SDimitry Andric return Builder.getInt1(E->getValue());
6772754fe60SDimitry Andric }
6782754fe60SDimitry Andric
679f22ef01cSRoman Divacky // Binary Operators.
EmitMul(const BinOpInfo & Ops)680f22ef01cSRoman Divacky Value *EmitMul(const BinOpInfo &Ops) {
681bd5abe19SDimitry Andric if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
6823861d79fSDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
683ffd1746dSEd Schouten case LangOptions::SOB_Defined:
684ffd1746dSEd Schouten return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
6853861d79fSDimitry Andric case LangOptions::SOB_Undefined:
68639d628a0SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
6873861d79fSDimitry Andric return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
688*b5893f02SDimitry Andric LLVM_FALLTHROUGH;
689ffd1746dSEd Schouten case LangOptions::SOB_Trapping:
69020e90f04SDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), Ops))
69120e90f04SDimitry Andric return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
692f22ef01cSRoman Divacky return EmitOverflowCheckedBinOp(Ops);
693ffd1746dSEd Schouten }
694ffd1746dSEd Schouten }
695ffd1746dSEd Schouten
69639d628a0SDimitry Andric if (Ops.Ty->isUnsignedIntegerType() &&
69720e90f04SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
69820e90f04SDimitry Andric !CanElideOverflowCheck(CGF.getContext(), Ops))
699139f7f9bSDimitry Andric return EmitOverflowCheckedBinOp(Ops);
700139f7f9bSDimitry Andric
70120e90f04SDimitry Andric if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
70220e90f04SDimitry Andric Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
70320e90f04SDimitry Andric return propagateFMFlags(V, Ops);
70420e90f04SDimitry Andric }
705f22ef01cSRoman Divacky return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
706f22ef01cSRoman Divacky }
707f22ef01cSRoman Divacky /// Create a binary op that checks for overflow.
708f22ef01cSRoman Divacky /// Currently only supports +, - and *.
709f22ef01cSRoman Divacky Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
7103861d79fSDimitry Andric
7112754fe60SDimitry Andric // Check for undefined division and modulus behaviors.
7122754fe60SDimitry Andric void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,
7132754fe60SDimitry Andric llvm::Value *Zero,bool isDiv);
714139f7f9bSDimitry Andric // Common helper for getting how wide LHS of shift is.
715139f7f9bSDimitry Andric static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS);
716f22ef01cSRoman Divacky Value *EmitDiv(const BinOpInfo &Ops);
717f22ef01cSRoman Divacky Value *EmitRem(const BinOpInfo &Ops);
718f22ef01cSRoman Divacky Value *EmitAdd(const BinOpInfo &Ops);
719f22ef01cSRoman Divacky Value *EmitSub(const BinOpInfo &Ops);
720f22ef01cSRoman Divacky Value *EmitShl(const BinOpInfo &Ops);
721f22ef01cSRoman Divacky Value *EmitShr(const BinOpInfo &Ops);
EmitAnd(const BinOpInfo & Ops)722f22ef01cSRoman Divacky Value *EmitAnd(const BinOpInfo &Ops) {
723f22ef01cSRoman Divacky return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
724f22ef01cSRoman Divacky }
EmitXor(const BinOpInfo & Ops)725f22ef01cSRoman Divacky Value *EmitXor(const BinOpInfo &Ops) {
726f22ef01cSRoman Divacky return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
727f22ef01cSRoman Divacky }
EmitOr(const BinOpInfo & Ops)728f22ef01cSRoman Divacky Value *EmitOr (const BinOpInfo &Ops) {
729f22ef01cSRoman Divacky return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
730f22ef01cSRoman Divacky }
731f22ef01cSRoman Divacky
732f22ef01cSRoman Divacky BinOpInfo EmitBinOps(const BinaryOperator *E);
733f22ef01cSRoman Divacky LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
734f22ef01cSRoman Divacky Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
735ffd1746dSEd Schouten Value *&Result);
736f22ef01cSRoman Divacky
737f22ef01cSRoman Divacky Value *EmitCompoundAssign(const CompoundAssignOperator *E,
738f22ef01cSRoman Divacky Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
739f22ef01cSRoman Divacky
740f22ef01cSRoman Divacky // Binary operators and binary compound assignment operators.
741f22ef01cSRoman Divacky #define HANDLEBINOP(OP) \
742f22ef01cSRoman Divacky Value *VisitBin ## OP(const BinaryOperator *E) { \
743f22ef01cSRoman Divacky return Emit ## OP(EmitBinOps(E)); \
744f22ef01cSRoman Divacky } \
745f22ef01cSRoman Divacky Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
746f22ef01cSRoman Divacky return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
747f22ef01cSRoman Divacky }
748f22ef01cSRoman Divacky HANDLEBINOP(Mul)
749f22ef01cSRoman Divacky HANDLEBINOP(Div)
750f22ef01cSRoman Divacky HANDLEBINOP(Rem)
751f22ef01cSRoman Divacky HANDLEBINOP(Add)
752f22ef01cSRoman Divacky HANDLEBINOP(Sub)
753f22ef01cSRoman Divacky HANDLEBINOP(Shl)
754f22ef01cSRoman Divacky HANDLEBINOP(Shr)
755f22ef01cSRoman Divacky HANDLEBINOP(And)
756f22ef01cSRoman Divacky HANDLEBINOP(Xor)
757f22ef01cSRoman Divacky HANDLEBINOP(Or)
758f22ef01cSRoman Divacky #undef HANDLEBINOP
759f22ef01cSRoman Divacky
760f22ef01cSRoman Divacky // Comparisons.
7610623d748SDimitry Andric Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc,
7620623d748SDimitry Andric llvm::CmpInst::Predicate SICmpOpc,
7630623d748SDimitry Andric llvm::CmpInst::Predicate FCmpOpc);
764f22ef01cSRoman Divacky #define VISITCOMP(CODE, UI, SI, FP) \
765f22ef01cSRoman Divacky Value *VisitBin##CODE(const BinaryOperator *E) { \
766f22ef01cSRoman Divacky return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
767f22ef01cSRoman Divacky llvm::FCmpInst::FP); }
768f22ef01cSRoman Divacky VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT)
769f22ef01cSRoman Divacky VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT)
770f22ef01cSRoman Divacky VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE)
771f22ef01cSRoman Divacky VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE)
772f22ef01cSRoman Divacky VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ)
773f22ef01cSRoman Divacky VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE)
774f22ef01cSRoman Divacky #undef VISITCOMP
775f22ef01cSRoman Divacky
776f22ef01cSRoman Divacky Value *VisitBinAssign (const BinaryOperator *E);
777f22ef01cSRoman Divacky
778f22ef01cSRoman Divacky Value *VisitBinLAnd (const BinaryOperator *E);
779f22ef01cSRoman Divacky Value *VisitBinLOr (const BinaryOperator *E);
780f22ef01cSRoman Divacky Value *VisitBinComma (const BinaryOperator *E);
781f22ef01cSRoman Divacky
VisitBinPtrMemD(const Expr * E)782f22ef01cSRoman Divacky Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
VisitBinPtrMemI(const Expr * E)783f22ef01cSRoman Divacky Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
784f22ef01cSRoman Divacky
785f22ef01cSRoman Divacky // Other Operators.
786f22ef01cSRoman Divacky Value *VisitBlockExpr(const BlockExpr *BE);
7872754fe60SDimitry Andric Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *);
788f22ef01cSRoman Divacky Value *VisitChooseExpr(ChooseExpr *CE);
789f22ef01cSRoman Divacky Value *VisitVAArgExpr(VAArgExpr *VE);
VisitObjCStringLiteral(const ObjCStringLiteral * E)790f22ef01cSRoman Divacky Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
791f22ef01cSRoman Divacky return CGF.EmitObjCStringLiteral(E);
792f22ef01cSRoman Divacky }
VisitObjCBoxedExpr(ObjCBoxedExpr * E)7937ae0e2c9SDimitry Andric Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
7947ae0e2c9SDimitry Andric return CGF.EmitObjCBoxedExpr(E);
795dff0c46cSDimitry Andric }
VisitObjCArrayLiteral(ObjCArrayLiteral * E)796dff0c46cSDimitry Andric Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
797dff0c46cSDimitry Andric return CGF.EmitObjCArrayLiteral(E);
798dff0c46cSDimitry Andric }
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)799dff0c46cSDimitry Andric Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
800dff0c46cSDimitry Andric return CGF.EmitObjCDictionaryLiteral(E);
801dff0c46cSDimitry Andric }
802bd5abe19SDimitry Andric Value *VisitAsTypeExpr(AsTypeExpr *CE);
8036122f3e6SDimitry Andric Value *VisitAtomicExpr(AtomicExpr *AE);
804f22ef01cSRoman Divacky };
805f22ef01cSRoman Divacky } // end anonymous namespace.
806f22ef01cSRoman Divacky
807f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
808f22ef01cSRoman Divacky // Utilities
809f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
810f22ef01cSRoman Divacky
811f22ef01cSRoman Divacky /// EmitConversionToBool - Convert the specified expression value to a
812f22ef01cSRoman Divacky /// boolean (i1) truth value. This is equivalent to "Val != 0".
EmitConversionToBool(Value * Src,QualType SrcType)813f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
814f22ef01cSRoman Divacky assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
815f22ef01cSRoman Divacky
8162754fe60SDimitry Andric if (SrcType->isRealFloatingType())
8172754fe60SDimitry Andric return EmitFloatToBoolConversion(Src);
818f22ef01cSRoman Divacky
819e580952dSDimitry Andric if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
820e580952dSDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT);
821f22ef01cSRoman Divacky
822f22ef01cSRoman Divacky assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
823f22ef01cSRoman Divacky "Unknown scalar type to convert");
824f22ef01cSRoman Divacky
8252754fe60SDimitry Andric if (isa<llvm::IntegerType>(Src->getType()))
8262754fe60SDimitry Andric return EmitIntToBoolConversion(Src);
827f22ef01cSRoman Divacky
8282754fe60SDimitry Andric assert(isa<llvm::PointerType>(Src->getType()));
82944290647SDimitry Andric return EmitPointerToBoolConversion(Src, SrcType);
830f22ef01cSRoman Divacky }
831f22ef01cSRoman Divacky
EmitFloatConversionCheck(Value * OrigSrc,QualType OrigSrcType,Value * Src,QualType SrcType,QualType DstType,llvm::Type * DstTy,SourceLocation Loc)8320623d748SDimitry Andric void ScalarExprEmitter::EmitFloatConversionCheck(
8330623d748SDimitry Andric Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
8340623d748SDimitry Andric QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
83559d1ed5bSDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
8363861d79fSDimitry Andric using llvm::APFloat;
8373861d79fSDimitry Andric using llvm::APSInt;
8383861d79fSDimitry Andric
8393861d79fSDimitry Andric llvm::Type *SrcTy = Src->getType();
8403861d79fSDimitry Andric
84159d1ed5bSDimitry Andric llvm::Value *Check = nullptr;
8423861d79fSDimitry Andric if (llvm::IntegerType *IntTy = dyn_cast<llvm::IntegerType>(SrcTy)) {
8433861d79fSDimitry Andric // Integer to floating-point. This can fail for unsigned short -> __half
8443861d79fSDimitry Andric // or unsigned __int128 -> float.
8453861d79fSDimitry Andric assert(DstType->isFloatingType());
8463861d79fSDimitry Andric bool SrcIsUnsigned = OrigSrcType->isUnsignedIntegerOrEnumerationType();
8473861d79fSDimitry Andric
8483861d79fSDimitry Andric APFloat LargestFloat =
8493861d79fSDimitry Andric APFloat::getLargest(CGF.getContext().getFloatTypeSemantics(DstType));
8503861d79fSDimitry Andric APSInt LargestInt(IntTy->getBitWidth(), SrcIsUnsigned);
8513861d79fSDimitry Andric
8523861d79fSDimitry Andric bool IsExact;
8533861d79fSDimitry Andric if (LargestFloat.convertToInteger(LargestInt, APFloat::rmTowardZero,
8543861d79fSDimitry Andric &IsExact) != APFloat::opOK)
8553861d79fSDimitry Andric // The range of representable values of this floating point type includes
8563861d79fSDimitry Andric // all values of this integer type. Don't need an overflow check.
8573861d79fSDimitry Andric return;
8583861d79fSDimitry Andric
8593861d79fSDimitry Andric llvm::Value *Max = llvm::ConstantInt::get(VMContext, LargestInt);
8603861d79fSDimitry Andric if (SrcIsUnsigned)
8613861d79fSDimitry Andric Check = Builder.CreateICmpULE(Src, Max);
8623861d79fSDimitry Andric else {
8633861d79fSDimitry Andric llvm::Value *Min = llvm::ConstantInt::get(VMContext, -LargestInt);
8643861d79fSDimitry Andric llvm::Value *GE = Builder.CreateICmpSGE(Src, Min);
8653861d79fSDimitry Andric llvm::Value *LE = Builder.CreateICmpSLE(Src, Max);
8663861d79fSDimitry Andric Check = Builder.CreateAnd(GE, LE);
8673861d79fSDimitry Andric }
8683861d79fSDimitry Andric } else {
8693861d79fSDimitry Andric const llvm::fltSemantics &SrcSema =
8703861d79fSDimitry Andric CGF.getContext().getFloatTypeSemantics(OrigSrcType);
8713861d79fSDimitry Andric if (isa<llvm::IntegerType>(DstTy)) {
872139f7f9bSDimitry Andric // Floating-point to integer. This has undefined behavior if the source is
873139f7f9bSDimitry Andric // +-Inf, NaN, or doesn't fit into the destination type (after truncation
874139f7f9bSDimitry Andric // to an integer).
8753861d79fSDimitry Andric unsigned Width = CGF.getContext().getIntWidth(DstType);
8763861d79fSDimitry Andric bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
8773861d79fSDimitry Andric
8783861d79fSDimitry Andric APSInt Min = APSInt::getMinValue(Width, Unsigned);
879139f7f9bSDimitry Andric APFloat MinSrc(SrcSema, APFloat::uninitialized);
8803861d79fSDimitry Andric if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
8813861d79fSDimitry Andric APFloat::opOverflow)
8823861d79fSDimitry Andric // Don't need an overflow check for lower bound. Just check for
8833861d79fSDimitry Andric // -Inf/NaN.
884139f7f9bSDimitry Andric MinSrc = APFloat::getInf(SrcSema, true);
885139f7f9bSDimitry Andric else
886139f7f9bSDimitry Andric // Find the largest value which is too small to represent (before
887139f7f9bSDimitry Andric // truncation toward zero).
888139f7f9bSDimitry Andric MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
8893861d79fSDimitry Andric
8903861d79fSDimitry Andric APSInt Max = APSInt::getMaxValue(Width, Unsigned);
891139f7f9bSDimitry Andric APFloat MaxSrc(SrcSema, APFloat::uninitialized);
8923861d79fSDimitry Andric if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
8933861d79fSDimitry Andric APFloat::opOverflow)
8943861d79fSDimitry Andric // Don't need an overflow check for upper bound. Just check for
8953861d79fSDimitry Andric // +Inf/NaN.
896139f7f9bSDimitry Andric MaxSrc = APFloat::getInf(SrcSema, false);
897139f7f9bSDimitry Andric else
898139f7f9bSDimitry Andric // Find the smallest value which is too large to represent (before
899139f7f9bSDimitry Andric // truncation toward zero).
900139f7f9bSDimitry Andric MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
9013861d79fSDimitry Andric
9023861d79fSDimitry Andric // If we're converting from __half, convert the range to float to match
9033861d79fSDimitry Andric // the type of src.
9043861d79fSDimitry Andric if (OrigSrcType->isHalfType()) {
9053861d79fSDimitry Andric const llvm::fltSemantics &Sema =
9063861d79fSDimitry Andric CGF.getContext().getFloatTypeSemantics(SrcType);
9073861d79fSDimitry Andric bool IsInexact;
9083861d79fSDimitry Andric MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
9093861d79fSDimitry Andric MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
9103861d79fSDimitry Andric }
9113861d79fSDimitry Andric
9123861d79fSDimitry Andric llvm::Value *GE =
913139f7f9bSDimitry Andric Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
9143861d79fSDimitry Andric llvm::Value *LE =
915139f7f9bSDimitry Andric Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
9163861d79fSDimitry Andric Check = Builder.CreateAnd(GE, LE);
917139f7f9bSDimitry Andric } else {
918139f7f9bSDimitry Andric // FIXME: Maybe split this sanitizer out from float-cast-overflow.
919139f7f9bSDimitry Andric //
920139f7f9bSDimitry Andric // Floating-point to floating-point. This has undefined behavior if the
921139f7f9bSDimitry Andric // source is not in the range of representable values of the destination
922139f7f9bSDimitry Andric // type. The C and C++ standards are spectacularly unclear here. We
923139f7f9bSDimitry Andric // diagnose finite out-of-range conversions, but allow infinities and NaNs
924139f7f9bSDimitry Andric // to convert to the corresponding value in the smaller type.
925139f7f9bSDimitry Andric //
926139f7f9bSDimitry Andric // C11 Annex F gives all such conversions defined behavior for IEC 60559
927139f7f9bSDimitry Andric // conforming implementations. Unfortunately, LLVM's fptrunc instruction
928139f7f9bSDimitry Andric // does not.
929139f7f9bSDimitry Andric
930139f7f9bSDimitry Andric // Converting from a lower rank to a higher rank can never have
931139f7f9bSDimitry Andric // undefined behavior, since higher-rank types must have a superset
932139f7f9bSDimitry Andric // of values of lower-rank types.
933139f7f9bSDimitry Andric if (CGF.getContext().getFloatingTypeOrder(OrigSrcType, DstType) != 1)
934139f7f9bSDimitry Andric return;
935139f7f9bSDimitry Andric
936139f7f9bSDimitry Andric assert(!OrigSrcType->isHalfType() &&
937139f7f9bSDimitry Andric "should not check conversion from __half, it has the lowest rank");
938139f7f9bSDimitry Andric
939139f7f9bSDimitry Andric const llvm::fltSemantics &DstSema =
940139f7f9bSDimitry Andric CGF.getContext().getFloatTypeSemantics(DstType);
941139f7f9bSDimitry Andric APFloat MinBad = APFloat::getLargest(DstSema, false);
942139f7f9bSDimitry Andric APFloat MaxBad = APFloat::getInf(DstSema, false);
943139f7f9bSDimitry Andric
944139f7f9bSDimitry Andric bool IsInexact;
945139f7f9bSDimitry Andric MinBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
946139f7f9bSDimitry Andric MaxBad.convert(SrcSema, APFloat::rmTowardZero, &IsInexact);
947139f7f9bSDimitry Andric
948139f7f9bSDimitry Andric Value *AbsSrc = CGF.EmitNounwindRuntimeCall(
949139f7f9bSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Src->getType()), Src);
950139f7f9bSDimitry Andric llvm::Value *GE =
951139f7f9bSDimitry Andric Builder.CreateFCmpOGT(AbsSrc, llvm::ConstantFP::get(VMContext, MinBad));
952139f7f9bSDimitry Andric llvm::Value *LE =
953139f7f9bSDimitry Andric Builder.CreateFCmpOLT(AbsSrc, llvm::ConstantFP::get(VMContext, MaxBad));
954139f7f9bSDimitry Andric Check = Builder.CreateNot(Builder.CreateAnd(GE, LE));
955139f7f9bSDimitry Andric }
9563861d79fSDimitry Andric }
9573861d79fSDimitry Andric
9580623d748SDimitry Andric llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
9593861d79fSDimitry Andric CGF.EmitCheckTypeDescriptor(OrigSrcType),
9600623d748SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType)};
96139d628a0SDimitry Andric CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
96244290647SDimitry Andric SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
9633861d79fSDimitry Andric }
9643861d79fSDimitry Andric
965*b5893f02SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
966*b5893f02SDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
967*b5893f02SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
968*b5893f02SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)969*b5893f02SDimitry Andric EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
970*b5893f02SDimitry Andric QualType DstType, CGBuilderTy &Builder) {
971*b5893f02SDimitry Andric llvm::Type *SrcTy = Src->getType();
972*b5893f02SDimitry Andric llvm::Type *DstTy = Dst->getType();
973*b5893f02SDimitry Andric (void)DstTy; // Only used in assert()
974*b5893f02SDimitry Andric
975*b5893f02SDimitry Andric // This should be truncation of integral types.
976*b5893f02SDimitry Andric assert(Src != Dst);
977*b5893f02SDimitry Andric assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
978*b5893f02SDimitry Andric assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
979*b5893f02SDimitry Andric "non-integer llvm type");
980*b5893f02SDimitry Andric
981*b5893f02SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
982*b5893f02SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
983*b5893f02SDimitry Andric
984*b5893f02SDimitry Andric // If both (src and dst) types are unsigned, then it's an unsigned truncation.
985*b5893f02SDimitry Andric // Else, it is a signed truncation.
986*b5893f02SDimitry Andric ScalarExprEmitter::ImplicitConversionCheckKind Kind;
987*b5893f02SDimitry Andric SanitizerMask Mask;
988*b5893f02SDimitry Andric if (!SrcSigned && !DstSigned) {
989*b5893f02SDimitry Andric Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
990*b5893f02SDimitry Andric Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
991*b5893f02SDimitry Andric } else {
992*b5893f02SDimitry Andric Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
993*b5893f02SDimitry Andric Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
994*b5893f02SDimitry Andric }
995*b5893f02SDimitry Andric
996*b5893f02SDimitry Andric llvm::Value *Check = nullptr;
997*b5893f02SDimitry Andric // 1. Extend the truncated value back to the same width as the Src.
998*b5893f02SDimitry Andric Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext");
999*b5893f02SDimitry Andric // 2. Equality-compare with the original source value
1000*b5893f02SDimitry Andric Check = Builder.CreateICmpEQ(Check, Src, "truncheck");
1001*b5893f02SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1002*b5893f02SDimitry Andric return std::make_pair(Kind, std::make_pair(Check, Mask));
1003*b5893f02SDimitry Andric }
1004*b5893f02SDimitry Andric
EmitIntegerTruncationCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)10054ba319b5SDimitry Andric void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
10064ba319b5SDimitry Andric Value *Dst, QualType DstType,
10074ba319b5SDimitry Andric SourceLocation Loc) {
1008*b5893f02SDimitry Andric if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation))
1009*b5893f02SDimitry Andric return;
1010*b5893f02SDimitry Andric
1011*b5893f02SDimitry Andric // We only care about int->int conversions here.
1012*b5893f02SDimitry Andric // We ignore conversions to/from pointer and/or bool.
1013*b5893f02SDimitry Andric if (!(SrcType->isIntegerType() && DstType->isIntegerType()))
1014*b5893f02SDimitry Andric return;
1015*b5893f02SDimitry Andric
1016*b5893f02SDimitry Andric unsigned SrcBits = Src->getType()->getScalarSizeInBits();
1017*b5893f02SDimitry Andric unsigned DstBits = Dst->getType()->getScalarSizeInBits();
1018*b5893f02SDimitry Andric // This must be truncation. Else we do not care.
1019*b5893f02SDimitry Andric if (SrcBits <= DstBits)
1020*b5893f02SDimitry Andric return;
1021*b5893f02SDimitry Andric
1022*b5893f02SDimitry Andric assert(!DstType->isBooleanType() && "we should not get here with booleans.");
1023*b5893f02SDimitry Andric
1024*b5893f02SDimitry Andric // If the integer sign change sanitizer is enabled,
1025*b5893f02SDimitry Andric // and we are truncating from larger unsigned type to smaller signed type,
1026*b5893f02SDimitry Andric // let that next sanitizer deal with it.
1027*b5893f02SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1028*b5893f02SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1029*b5893f02SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) &&
1030*b5893f02SDimitry Andric (!SrcSigned && DstSigned))
1031*b5893f02SDimitry Andric return;
1032*b5893f02SDimitry Andric
1033*b5893f02SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
1034*b5893f02SDimitry Andric
1035*b5893f02SDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1036*b5893f02SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
1037*b5893f02SDimitry Andric Check =
1038*b5893f02SDimitry Andric EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
1039*b5893f02SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1040*b5893f02SDimitry Andric
1041*b5893f02SDimitry Andric // Do we care about this type of truncation?
1042*b5893f02SDimitry Andric if (!CGF.SanOpts.has(Check.second.second))
1043*b5893f02SDimitry Andric return;
1044*b5893f02SDimitry Andric
1045*b5893f02SDimitry Andric llvm::Constant *StaticArgs[] = {
1046*b5893f02SDimitry Andric CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
1047*b5893f02SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType),
1048*b5893f02SDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
1049*b5893f02SDimitry Andric CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1050*b5893f02SDimitry Andric {Src, Dst});
1051*b5893f02SDimitry Andric }
1052*b5893f02SDimitry Andric
1053*b5893f02SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
1054*b5893f02SDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
1055*b5893f02SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1056*b5893f02SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)1057*b5893f02SDimitry Andric EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
1058*b5893f02SDimitry Andric QualType DstType, CGBuilderTy &Builder) {
1059*b5893f02SDimitry Andric llvm::Type *SrcTy = Src->getType();
1060*b5893f02SDimitry Andric llvm::Type *DstTy = Dst->getType();
1061*b5893f02SDimitry Andric
1062*b5893f02SDimitry Andric assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1063*b5893f02SDimitry Andric "non-integer llvm type");
1064*b5893f02SDimitry Andric
1065*b5893f02SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1066*b5893f02SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1067*b5893f02SDimitry Andric (void)SrcSigned; // Only used in assert()
1068*b5893f02SDimitry Andric (void)DstSigned; // Only used in assert()
1069*b5893f02SDimitry Andric unsigned SrcBits = SrcTy->getScalarSizeInBits();
1070*b5893f02SDimitry Andric unsigned DstBits = DstTy->getScalarSizeInBits();
1071*b5893f02SDimitry Andric (void)SrcBits; // Only used in assert()
1072*b5893f02SDimitry Andric (void)DstBits; // Only used in assert()
1073*b5893f02SDimitry Andric
1074*b5893f02SDimitry Andric assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1075*b5893f02SDimitry Andric "either the widths should be different, or the signednesses.");
1076*b5893f02SDimitry Andric
1077*b5893f02SDimitry Andric // NOTE: zero value is considered to be non-negative.
1078*b5893f02SDimitry Andric auto EmitIsNegativeTest = [&Builder](Value *V, QualType VType,
1079*b5893f02SDimitry Andric const char *Name) -> Value * {
1080*b5893f02SDimitry Andric // Is this value a signed type?
1081*b5893f02SDimitry Andric bool VSigned = VType->isSignedIntegerOrEnumerationType();
1082*b5893f02SDimitry Andric llvm::Type *VTy = V->getType();
1083*b5893f02SDimitry Andric if (!VSigned) {
1084*b5893f02SDimitry Andric // If the value is unsigned, then it is never negative.
1085*b5893f02SDimitry Andric // FIXME: can we encounter non-scalar VTy here?
1086*b5893f02SDimitry Andric return llvm::ConstantInt::getFalse(VTy->getContext());
1087*b5893f02SDimitry Andric }
1088*b5893f02SDimitry Andric // Get the zero of the same type with which we will be comparing.
1089*b5893f02SDimitry Andric llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1090*b5893f02SDimitry Andric // %V.isnegative = icmp slt %V, 0
1091*b5893f02SDimitry Andric // I.e is %V *strictly* less than zero, does it have negative value?
1092*b5893f02SDimitry Andric return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
1093*b5893f02SDimitry Andric llvm::Twine(Name) + "." + V->getName() +
1094*b5893f02SDimitry Andric ".negativitycheck");
1095*b5893f02SDimitry Andric };
1096*b5893f02SDimitry Andric
1097*b5893f02SDimitry Andric // 1. Was the old Value negative?
1098*b5893f02SDimitry Andric llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType, "src");
1099*b5893f02SDimitry Andric // 2. Is the new Value negative?
1100*b5893f02SDimitry Andric llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst");
1101*b5893f02SDimitry Andric // 3. Now, was the 'negativity status' preserved during the conversion?
1102*b5893f02SDimitry Andric // NOTE: conversion from negative to zero is considered to change the sign.
1103*b5893f02SDimitry Andric // (We want to get 'false' when the conversion changed the sign)
1104*b5893f02SDimitry Andric // So we should just equality-compare the negativity statuses.
1105*b5893f02SDimitry Andric llvm::Value *Check = nullptr;
1106*b5893f02SDimitry Andric Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck");
1107*b5893f02SDimitry Andric // If the comparison result is 'false', then the conversion changed the sign.
1108*b5893f02SDimitry Andric return std::make_pair(
1109*b5893f02SDimitry Andric ScalarExprEmitter::ICCK_IntegerSignChange,
1110*b5893f02SDimitry Andric std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1111*b5893f02SDimitry Andric }
1112*b5893f02SDimitry Andric
EmitIntegerSignChangeCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)1113*b5893f02SDimitry Andric void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
1114*b5893f02SDimitry Andric Value *Dst, QualType DstType,
1115*b5893f02SDimitry Andric SourceLocation Loc) {
1116*b5893f02SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange))
11174ba319b5SDimitry Andric return;
11184ba319b5SDimitry Andric
11194ba319b5SDimitry Andric llvm::Type *SrcTy = Src->getType();
11204ba319b5SDimitry Andric llvm::Type *DstTy = Dst->getType();
11214ba319b5SDimitry Andric
11224ba319b5SDimitry Andric // We only care about int->int conversions here.
11234ba319b5SDimitry Andric // We ignore conversions to/from pointer and/or bool.
11244ba319b5SDimitry Andric if (!(SrcType->isIntegerType() && DstType->isIntegerType()))
11254ba319b5SDimitry Andric return;
11264ba319b5SDimitry Andric
1127*b5893f02SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1128*b5893f02SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
11294ba319b5SDimitry Andric unsigned SrcBits = SrcTy->getScalarSizeInBits();
11304ba319b5SDimitry Andric unsigned DstBits = DstTy->getScalarSizeInBits();
11314ba319b5SDimitry Andric
1132*b5893f02SDimitry Andric // Now, we do not need to emit the check in *all* of the cases.
1133*b5893f02SDimitry Andric // We can avoid emitting it in some obvious cases where it would have been
1134*b5893f02SDimitry Andric // dropped by the opt passes (instcombine) always anyways.
1135*b5893f02SDimitry Andric // If it's a cast between effectively the same type, no check.
1136*b5893f02SDimitry Andric // NOTE: this is *not* equivalent to checking the canonical types.
1137*b5893f02SDimitry Andric if (SrcSigned == DstSigned && SrcBits == DstBits)
1138*b5893f02SDimitry Andric return;
1139*b5893f02SDimitry Andric // At least one of the values needs to have signed type.
1140*b5893f02SDimitry Andric // If both are unsigned, then obviously, neither of them can be negative.
1141*b5893f02SDimitry Andric if (!SrcSigned && !DstSigned)
1142*b5893f02SDimitry Andric return;
1143*b5893f02SDimitry Andric // If the conversion is to *larger* *signed* type, then no check is needed.
1144*b5893f02SDimitry Andric // Because either sign-extension happens (so the sign will remain),
1145*b5893f02SDimitry Andric // or zero-extension will happen (the sign bit will be zero.)
1146*b5893f02SDimitry Andric if ((DstBits > SrcBits) && DstSigned)
1147*b5893f02SDimitry Andric return;
1148*b5893f02SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1149*b5893f02SDimitry Andric (SrcBits > DstBits) && SrcSigned) {
1150*b5893f02SDimitry Andric // If the signed integer truncation sanitizer is enabled,
1151*b5893f02SDimitry Andric // and this is a truncation from signed type, then no check is needed.
1152*b5893f02SDimitry Andric // Because here sign change check is interchangeable with truncation check.
1153*b5893f02SDimitry Andric return;
1154*b5893f02SDimitry Andric }
1155*b5893f02SDimitry Andric // That's it. We can't rule out any more cases with the data we have.
11564ba319b5SDimitry Andric
11574ba319b5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
11584ba319b5SDimitry Andric
1159*b5893f02SDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1160*b5893f02SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
1161*b5893f02SDimitry Andric Check;
11624ba319b5SDimitry Andric
1163*b5893f02SDimitry Andric // Each of these checks needs to return 'false' when an issue was detected.
1164*b5893f02SDimitry Andric ImplicitConversionCheckKind CheckKind;
1165*b5893f02SDimitry Andric llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
1166*b5893f02SDimitry Andric // So we can 'and' all the checks together, and still get 'false',
1167*b5893f02SDimitry Andric // if at least one of the checks detected an issue.
1168*b5893f02SDimitry Andric
1169*b5893f02SDimitry Andric Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
1170*b5893f02SDimitry Andric CheckKind = Check.first;
1171*b5893f02SDimitry Andric Checks.emplace_back(Check.second);
1172*b5893f02SDimitry Andric
1173*b5893f02SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1174*b5893f02SDimitry Andric (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1175*b5893f02SDimitry Andric // If the signed integer truncation sanitizer was enabled,
1176*b5893f02SDimitry Andric // and we are truncating from larger unsigned type to smaller signed type,
1177*b5893f02SDimitry Andric // let's handle the case we skipped in that check.
1178*b5893f02SDimitry Andric Check =
1179*b5893f02SDimitry Andric EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
1180*b5893f02SDimitry Andric CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1181*b5893f02SDimitry Andric Checks.emplace_back(Check.second);
11824ba319b5SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1183*b5893f02SDimitry Andric }
11844ba319b5SDimitry Andric
11854ba319b5SDimitry Andric llvm::Constant *StaticArgs[] = {
11864ba319b5SDimitry Andric CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
11874ba319b5SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType),
1188*b5893f02SDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
1189*b5893f02SDimitry Andric // EmitCheck() will 'and' all the checks together.
1190*b5893f02SDimitry Andric CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1191*b5893f02SDimitry Andric {Src, Dst});
11924ba319b5SDimitry Andric }
11934ba319b5SDimitry Andric
11940623d748SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
11950623d748SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcType,QualType DstType,SourceLocation Loc,ScalarConversionOpts Opts)1196f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
11970623d748SDimitry Andric QualType DstType,
11980623d748SDimitry Andric SourceLocation Loc,
11994ba319b5SDimitry Andric ScalarConversionOpts Opts) {
1200*b5893f02SDimitry Andric // All conversions involving fixed point types should be handled by the
1201*b5893f02SDimitry Andric // EmitFixedPoint family functions. This is done to prevent bloating up this
1202*b5893f02SDimitry Andric // function more, and although fixed point numbers are represented by
1203*b5893f02SDimitry Andric // integers, we do not want to follow any logic that assumes they should be
1204*b5893f02SDimitry Andric // treated as integers.
1205*b5893f02SDimitry Andric // TODO(leonardchan): When necessary, add another if statement checking for
1206*b5893f02SDimitry Andric // conversions to fixed point types from other types.
1207*b5893f02SDimitry Andric if (SrcType->isFixedPointType()) {
1208*b5893f02SDimitry Andric if (DstType->isFixedPointType()) {
1209*b5893f02SDimitry Andric return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1210*b5893f02SDimitry Andric } else if (DstType->isBooleanType()) {
1211*b5893f02SDimitry Andric // We do not need to check the padding bit on unsigned types if unsigned
1212*b5893f02SDimitry Andric // padding is enabled because overflow into this bit is undefined
1213*b5893f02SDimitry Andric // behavior.
1214*b5893f02SDimitry Andric return Builder.CreateIsNotNull(Src, "tobool");
1215*b5893f02SDimitry Andric }
1216*b5893f02SDimitry Andric
1217*b5893f02SDimitry Andric llvm_unreachable(
1218*b5893f02SDimitry Andric "Unhandled scalar conversion involving a fixed point type.");
1219*b5893f02SDimitry Andric }
1220*b5893f02SDimitry Andric
12214ba319b5SDimitry Andric QualType NoncanonicalSrcType = SrcType;
12224ba319b5SDimitry Andric QualType NoncanonicalDstType = DstType;
12234ba319b5SDimitry Andric
1224f22ef01cSRoman Divacky SrcType = CGF.getContext().getCanonicalType(SrcType);
1225f22ef01cSRoman Divacky DstType = CGF.getContext().getCanonicalType(DstType);
1226f22ef01cSRoman Divacky if (SrcType == DstType) return Src;
1227f22ef01cSRoman Divacky
122859d1ed5bSDimitry Andric if (DstType->isVoidType()) return nullptr;
1229f22ef01cSRoman Divacky
12303861d79fSDimitry Andric llvm::Value *OrigSrc = Src;
12313861d79fSDimitry Andric QualType OrigSrcType = SrcType;
12326122f3e6SDimitry Andric llvm::Type *SrcTy = Src->getType();
12336122f3e6SDimitry Andric
1234f22ef01cSRoman Divacky // Handle conversions to bool first, they are special: comparisons against 0.
1235f22ef01cSRoman Divacky if (DstType->isBooleanType())
1236f22ef01cSRoman Divacky return EmitConversionToBool(Src, SrcType);
1237f22ef01cSRoman Divacky
12386122f3e6SDimitry Andric llvm::Type *DstTy = ConvertType(DstType);
1239f22ef01cSRoman Divacky
124033956c43SDimitry Andric // Cast from half through float if half isn't a native type.
124133956c43SDimitry Andric if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
124233956c43SDimitry Andric // Cast to FP using the intrinsic if the half type itself isn't supported.
124333956c43SDimitry Andric if (DstTy->isFloatingPointTy()) {
12449a199699SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
124533956c43SDimitry Andric return Builder.CreateCall(
124633956c43SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy),
124733956c43SDimitry Andric Src);
124833956c43SDimitry Andric } else {
124933956c43SDimitry Andric // Cast to other types through float, using either the intrinsic or FPExt,
125033956c43SDimitry Andric // depending on whether the half type itself is supported
125133956c43SDimitry Andric // (as opposed to operations on half, available with NativeHalfType).
12529a199699SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
125333956c43SDimitry Andric Src = Builder.CreateCall(
125433956c43SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
125533956c43SDimitry Andric CGF.CGM.FloatTy),
125633956c43SDimitry Andric Src);
125733956c43SDimitry Andric } else {
125833956c43SDimitry Andric Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
125933956c43SDimitry Andric }
126033956c43SDimitry Andric SrcType = CGF.getContext().FloatTy;
126133956c43SDimitry Andric SrcTy = CGF.FloatTy;
126233956c43SDimitry Andric }
126333956c43SDimitry Andric }
126433956c43SDimitry Andric
1265f22ef01cSRoman Divacky // Ignore conversions like int -> uint.
1266*b5893f02SDimitry Andric if (SrcTy == DstTy) {
1267*b5893f02SDimitry Andric if (Opts.EmitImplicitIntegerSignChangeChecks)
1268*b5893f02SDimitry Andric EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1269*b5893f02SDimitry Andric NoncanonicalDstType, Loc);
1270*b5893f02SDimitry Andric
1271f22ef01cSRoman Divacky return Src;
1272*b5893f02SDimitry Andric }
1273f22ef01cSRoman Divacky
1274f22ef01cSRoman Divacky // Handle pointer conversions next: pointers can only be converted to/from
1275f22ef01cSRoman Divacky // other pointers and integers. Check for pointer types in terms of LLVM, as
1276f22ef01cSRoman Divacky // some native types (like Obj-C id) may map to a pointer type.
127744290647SDimitry Andric if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1278f22ef01cSRoman Divacky // The source value may be an integer, or a pointer.
12796122f3e6SDimitry Andric if (isa<llvm::PointerType>(SrcTy))
1280f22ef01cSRoman Divacky return Builder.CreateBitCast(Src, DstTy, "conv");
1281f22ef01cSRoman Divacky
1282f22ef01cSRoman Divacky assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
1283f22ef01cSRoman Divacky // First, convert to the correct width so that we control the kind of
1284f22ef01cSRoman Divacky // extension.
128544290647SDimitry Andric llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT);
1286bd5abe19SDimitry Andric bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
1287f22ef01cSRoman Divacky llvm::Value* IntResult =
1288f22ef01cSRoman Divacky Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
1289f22ef01cSRoman Divacky // Then, cast to pointer.
1290f22ef01cSRoman Divacky return Builder.CreateIntToPtr(IntResult, DstTy, "conv");
1291f22ef01cSRoman Divacky }
1292f22ef01cSRoman Divacky
12936122f3e6SDimitry Andric if (isa<llvm::PointerType>(SrcTy)) {
1294f22ef01cSRoman Divacky // Must be an ptr to int cast.
1295f22ef01cSRoman Divacky assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
1296f22ef01cSRoman Divacky return Builder.CreatePtrToInt(Src, DstTy, "conv");
1297f22ef01cSRoman Divacky }
1298f22ef01cSRoman Divacky
1299f22ef01cSRoman Divacky // A scalar can be splatted to an extended vector of the same element type
1300f22ef01cSRoman Divacky if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
1301444ed5c5SDimitry Andric // Sema should add casts to make sure that the source expression's type is
1302444ed5c5SDimitry Andric // the same as the vector's element type (sans qualifiers)
1303444ed5c5SDimitry Andric assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1304444ed5c5SDimitry Andric SrcType.getTypePtr() &&
1305444ed5c5SDimitry Andric "Splatted expr doesn't match with vector element type?");
1306f22ef01cSRoman Divacky
1307f22ef01cSRoman Divacky // Splat the element across to all elements
1308e7145dcbSDimitry Andric unsigned NumElements = DstTy->getVectorNumElements();
1309444ed5c5SDimitry Andric return Builder.CreateVectorSplat(NumElements, Src, "splat");
1310f22ef01cSRoman Divacky }
1311f22ef01cSRoman Divacky
13129a199699SDimitry Andric if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1313f22ef01cSRoman Divacky // Allow bitcast from vector to integer/fp of the same size.
13149a199699SDimitry Andric unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
13159a199699SDimitry Andric unsigned DstSize = DstTy->getPrimitiveSizeInBits();
13169a199699SDimitry Andric if (SrcSize == DstSize)
1317f22ef01cSRoman Divacky return Builder.CreateBitCast(Src, DstTy, "conv");
1318f22ef01cSRoman Divacky
13199a199699SDimitry Andric // Conversions between vectors of different sizes are not allowed except
13209a199699SDimitry Andric // when vectors of half are involved. Operations on storage-only half
13219a199699SDimitry Andric // vectors require promoting half vector operands to float vectors and
13229a199699SDimitry Andric // truncating the result, which is either an int or float vector, to a
13239a199699SDimitry Andric // short or half vector.
13249a199699SDimitry Andric
13259a199699SDimitry Andric // Source and destination are both expected to be vectors.
13269a199699SDimitry Andric llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
13279a199699SDimitry Andric llvm::Type *DstElementTy = DstTy->getVectorElementType();
13289a199699SDimitry Andric (void)DstElementTy;
13299a199699SDimitry Andric
13309a199699SDimitry Andric assert(((SrcElementTy->isIntegerTy() &&
13319a199699SDimitry Andric DstElementTy->isIntegerTy()) ||
13329a199699SDimitry Andric (SrcElementTy->isFloatingPointTy() &&
13339a199699SDimitry Andric DstElementTy->isFloatingPointTy())) &&
13349a199699SDimitry Andric "unexpected conversion between a floating-point vector and an "
13359a199699SDimitry Andric "integer vector");
13369a199699SDimitry Andric
13379a199699SDimitry Andric // Truncate an i32 vector to an i16 vector.
13389a199699SDimitry Andric if (SrcElementTy->isIntegerTy())
13399a199699SDimitry Andric return Builder.CreateIntCast(Src, DstTy, false, "conv");
13409a199699SDimitry Andric
13419a199699SDimitry Andric // Truncate a float vector to a half vector.
13429a199699SDimitry Andric if (SrcSize > DstSize)
13439a199699SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy, "conv");
13449a199699SDimitry Andric
13459a199699SDimitry Andric // Promote a half vector to a float vector.
13469a199699SDimitry Andric return Builder.CreateFPExt(Src, DstTy, "conv");
13479a199699SDimitry Andric }
13489a199699SDimitry Andric
1349f22ef01cSRoman Divacky // Finally, we have the arithmetic types: real int/float.
135059d1ed5bSDimitry Andric Value *Res = nullptr;
13516122f3e6SDimitry Andric llvm::Type *ResTy = DstTy;
13526122f3e6SDimitry Andric
13533861d79fSDimitry Andric // An overflowing conversion has undefined behavior if either the source type
13543861d79fSDimitry Andric // or the destination type is a floating-point type.
135539d628a0SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
13563861d79fSDimitry Andric (OrigSrcType->isFloatingType() || DstType->isFloatingType()))
13570623d748SDimitry Andric EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
13580623d748SDimitry Andric Loc);
13593861d79fSDimitry Andric
136033956c43SDimitry Andric // Cast to half through float if half isn't a native type.
136133956c43SDimitry Andric if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
136233956c43SDimitry Andric // Make sure we cast in a single step if from another FP type.
136333956c43SDimitry Andric if (SrcTy->isFloatingPointTy()) {
136433956c43SDimitry Andric // Use the intrinsic if the half type itself isn't supported
136533956c43SDimitry Andric // (as opposed to operations on half, available with NativeHalfType).
13669a199699SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
136733956c43SDimitry Andric return Builder.CreateCall(
136833956c43SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src);
136933956c43SDimitry Andric // If the half type is supported, just use an fptrunc.
137033956c43SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy);
137133956c43SDimitry Andric }
1372dff0c46cSDimitry Andric DstTy = CGF.FloatTy;
137333956c43SDimitry Andric }
13746122f3e6SDimitry Andric
13756122f3e6SDimitry Andric if (isa<llvm::IntegerType>(SrcTy)) {
1376bd5abe19SDimitry Andric bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
13774ba319b5SDimitry Andric if (SrcType->isBooleanType() && Opts.TreatBooleanAsSigned) {
13780623d748SDimitry Andric InputSigned = true;
13790623d748SDimitry Andric }
1380f22ef01cSRoman Divacky if (isa<llvm::IntegerType>(DstTy))
13816122f3e6SDimitry Andric Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1382f22ef01cSRoman Divacky else if (InputSigned)
13836122f3e6SDimitry Andric Res = Builder.CreateSIToFP(Src, DstTy, "conv");
1384f22ef01cSRoman Divacky else
13856122f3e6SDimitry Andric Res = Builder.CreateUIToFP(Src, DstTy, "conv");
13866122f3e6SDimitry Andric } else if (isa<llvm::IntegerType>(DstTy)) {
13876122f3e6SDimitry Andric assert(SrcTy->isFloatingPointTy() && "Unknown real conversion");
1388bd5abe19SDimitry Andric if (DstType->isSignedIntegerOrEnumerationType())
13896122f3e6SDimitry Andric Res = Builder.CreateFPToSI(Src, DstTy, "conv");
1390f22ef01cSRoman Divacky else
13916122f3e6SDimitry Andric Res = Builder.CreateFPToUI(Src, DstTy, "conv");
13926122f3e6SDimitry Andric } else {
13936122f3e6SDimitry Andric assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() &&
13946122f3e6SDimitry Andric "Unknown real conversion");
13956122f3e6SDimitry Andric if (DstTy->getTypeID() < SrcTy->getTypeID())
13966122f3e6SDimitry Andric Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
13976122f3e6SDimitry Andric else
13986122f3e6SDimitry Andric Res = Builder.CreateFPExt(Src, DstTy, "conv");
1399f22ef01cSRoman Divacky }
1400f22ef01cSRoman Divacky
14016122f3e6SDimitry Andric if (DstTy != ResTy) {
14029a199699SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
14036122f3e6SDimitry Andric assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion");
140459d1ed5bSDimitry Andric Res = Builder.CreateCall(
140559d1ed5bSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy),
140659d1ed5bSDimitry Andric Res);
140733956c43SDimitry Andric } else {
140833956c43SDimitry Andric Res = Builder.CreateFPTrunc(Res, ResTy, "conv");
140933956c43SDimitry Andric }
14106122f3e6SDimitry Andric }
14116122f3e6SDimitry Andric
14124ba319b5SDimitry Andric if (Opts.EmitImplicitIntegerTruncationChecks)
14134ba319b5SDimitry Andric EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
14144ba319b5SDimitry Andric NoncanonicalDstType, Loc);
14154ba319b5SDimitry Andric
1416*b5893f02SDimitry Andric if (Opts.EmitImplicitIntegerSignChangeChecks)
1417*b5893f02SDimitry Andric EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1418*b5893f02SDimitry Andric NoncanonicalDstType, Loc);
1419*b5893f02SDimitry Andric
14206122f3e6SDimitry Andric return Res;
1421f22ef01cSRoman Divacky }
1422f22ef01cSRoman Divacky
EmitFixedPointConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)1423*b5893f02SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
1424*b5893f02SDimitry Andric QualType DstTy,
1425*b5893f02SDimitry Andric SourceLocation Loc) {
1426*b5893f02SDimitry Andric using llvm::APInt;
1427*b5893f02SDimitry Andric using llvm::ConstantInt;
1428*b5893f02SDimitry Andric using llvm::Value;
1429*b5893f02SDimitry Andric
1430*b5893f02SDimitry Andric assert(SrcTy->isFixedPointType());
1431*b5893f02SDimitry Andric assert(DstTy->isFixedPointType());
1432*b5893f02SDimitry Andric
1433*b5893f02SDimitry Andric FixedPointSemantics SrcFPSema =
1434*b5893f02SDimitry Andric CGF.getContext().getFixedPointSemantics(SrcTy);
1435*b5893f02SDimitry Andric FixedPointSemantics DstFPSema =
1436*b5893f02SDimitry Andric CGF.getContext().getFixedPointSemantics(DstTy);
1437*b5893f02SDimitry Andric unsigned SrcWidth = SrcFPSema.getWidth();
1438*b5893f02SDimitry Andric unsigned DstWidth = DstFPSema.getWidth();
1439*b5893f02SDimitry Andric unsigned SrcScale = SrcFPSema.getScale();
1440*b5893f02SDimitry Andric unsigned DstScale = DstFPSema.getScale();
1441*b5893f02SDimitry Andric bool SrcIsSigned = SrcFPSema.isSigned();
1442*b5893f02SDimitry Andric bool DstIsSigned = DstFPSema.isSigned();
1443*b5893f02SDimitry Andric
1444*b5893f02SDimitry Andric llvm::Type *DstIntTy = Builder.getIntNTy(DstWidth);
1445*b5893f02SDimitry Andric
1446*b5893f02SDimitry Andric Value *Result = Src;
1447*b5893f02SDimitry Andric unsigned ResultWidth = SrcWidth;
1448*b5893f02SDimitry Andric
1449*b5893f02SDimitry Andric if (!DstFPSema.isSaturated()) {
1450*b5893f02SDimitry Andric // Downscale.
1451*b5893f02SDimitry Andric if (DstScale < SrcScale)
1452*b5893f02SDimitry Andric Result = SrcIsSigned ?
1453*b5893f02SDimitry Andric Builder.CreateAShr(Result, SrcScale - DstScale, "downscale") :
1454*b5893f02SDimitry Andric Builder.CreateLShr(Result, SrcScale - DstScale, "downscale");
1455*b5893f02SDimitry Andric
1456*b5893f02SDimitry Andric // Resize.
1457*b5893f02SDimitry Andric Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
1458*b5893f02SDimitry Andric
1459*b5893f02SDimitry Andric // Upscale.
1460*b5893f02SDimitry Andric if (DstScale > SrcScale)
1461*b5893f02SDimitry Andric Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale");
1462*b5893f02SDimitry Andric } else {
1463*b5893f02SDimitry Andric // Adjust the number of fractional bits.
1464*b5893f02SDimitry Andric if (DstScale > SrcScale) {
1465*b5893f02SDimitry Andric ResultWidth = SrcWidth + DstScale - SrcScale;
1466*b5893f02SDimitry Andric llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth);
1467*b5893f02SDimitry Andric Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize");
1468*b5893f02SDimitry Andric Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale");
1469*b5893f02SDimitry Andric } else if (DstScale < SrcScale) {
1470*b5893f02SDimitry Andric Result = SrcIsSigned ?
1471*b5893f02SDimitry Andric Builder.CreateAShr(Result, SrcScale - DstScale, "downscale") :
1472*b5893f02SDimitry Andric Builder.CreateLShr(Result, SrcScale - DstScale, "downscale");
1473*b5893f02SDimitry Andric }
1474*b5893f02SDimitry Andric
1475*b5893f02SDimitry Andric // Handle saturation.
1476*b5893f02SDimitry Andric bool LessIntBits = DstFPSema.getIntegralBits() < SrcFPSema.getIntegralBits();
1477*b5893f02SDimitry Andric if (LessIntBits) {
1478*b5893f02SDimitry Andric Value *Max = ConstantInt::get(
1479*b5893f02SDimitry Andric CGF.getLLVMContext(),
1480*b5893f02SDimitry Andric APFixedPoint::getMax(DstFPSema).getValue().extOrTrunc(ResultWidth));
1481*b5893f02SDimitry Andric Value *TooHigh = SrcIsSigned ? Builder.CreateICmpSGT(Result, Max)
1482*b5893f02SDimitry Andric : Builder.CreateICmpUGT(Result, Max);
1483*b5893f02SDimitry Andric Result = Builder.CreateSelect(TooHigh, Max, Result, "satmax");
1484*b5893f02SDimitry Andric }
1485*b5893f02SDimitry Andric // Cannot overflow min to dest type if src is unsigned since all fixed
1486*b5893f02SDimitry Andric // point types can cover the unsigned min of 0.
1487*b5893f02SDimitry Andric if (SrcIsSigned && (LessIntBits || !DstIsSigned)) {
1488*b5893f02SDimitry Andric Value *Min = ConstantInt::get(
1489*b5893f02SDimitry Andric CGF.getLLVMContext(),
1490*b5893f02SDimitry Andric APFixedPoint::getMin(DstFPSema).getValue().extOrTrunc(ResultWidth));
1491*b5893f02SDimitry Andric Value *TooLow = Builder.CreateICmpSLT(Result, Min);
1492*b5893f02SDimitry Andric Result = Builder.CreateSelect(TooLow, Min, Result, "satmin");
1493*b5893f02SDimitry Andric }
1494*b5893f02SDimitry Andric
1495*b5893f02SDimitry Andric // Resize the integer part to get the final destination size.
1496*b5893f02SDimitry Andric Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
1497*b5893f02SDimitry Andric }
1498*b5893f02SDimitry Andric return Result;
1499*b5893f02SDimitry Andric }
1500*b5893f02SDimitry Andric
15010623d748SDimitry Andric /// Emit a conversion from the specified complex type to the specified
15020623d748SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)15030623d748SDimitry Andric Value *ScalarExprEmitter::EmitComplexToScalarConversion(
15040623d748SDimitry Andric CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
15050623d748SDimitry Andric SourceLocation Loc) {
1506f22ef01cSRoman Divacky // Get the source element type.
1507139f7f9bSDimitry Andric SrcTy = SrcTy->castAs<ComplexType>()->getElementType();
1508f22ef01cSRoman Divacky
1509f22ef01cSRoman Divacky // Handle conversions to bool first, they are special: comparisons against 0.
1510f22ef01cSRoman Divacky if (DstTy->isBooleanType()) {
1511f22ef01cSRoman Divacky // Complex != 0 -> (Real != 0) | (Imag != 0)
15120623d748SDimitry Andric Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
15130623d748SDimitry Andric Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1514f22ef01cSRoman Divacky return Builder.CreateOr(Src.first, Src.second, "tobool");
1515f22ef01cSRoman Divacky }
1516f22ef01cSRoman Divacky
1517f22ef01cSRoman Divacky // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
1518f22ef01cSRoman Divacky // the imaginary part of the complex value is discarded and the value of the
1519f22ef01cSRoman Divacky // real part is converted according to the conversion rules for the
1520f22ef01cSRoman Divacky // corresponding real type.
15210623d748SDimitry Andric return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1522f22ef01cSRoman Divacky }
1523f22ef01cSRoman Divacky
EmitNullValue(QualType Ty)1524f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1525139f7f9bSDimitry Andric return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty);
1526f22ef01cSRoman Divacky }
1527f22ef01cSRoman Divacky
15284ba319b5SDimitry Andric /// Emit a sanitization check for the given "binary" operation (which
15293861d79fSDimitry Andric /// might actually be a unary increment which has been lowered to a binary
153039d628a0SDimitry Andric /// operation). The check passes if all values in \p Checks (which are \c i1),
153139d628a0SDimitry Andric /// are \c true.
EmitBinOpCheck(ArrayRef<std::pair<Value *,SanitizerMask>> Checks,const BinOpInfo & Info)153239d628a0SDimitry Andric void ScalarExprEmitter::EmitBinOpCheck(
153333956c43SDimitry Andric ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {
153459d1ed5bSDimitry Andric assert(CGF.IsSanitizerScope);
153544290647SDimitry Andric SanitizerHandler Check;
1536139f7f9bSDimitry Andric SmallVector<llvm::Constant *, 4> StaticData;
1537139f7f9bSDimitry Andric SmallVector<llvm::Value *, 2> DynamicData;
15383861d79fSDimitry Andric
15393861d79fSDimitry Andric BinaryOperatorKind Opcode = Info.Opcode;
15403861d79fSDimitry Andric if (BinaryOperator::isCompoundAssignmentOp(Opcode))
15413861d79fSDimitry Andric Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode);
15423861d79fSDimitry Andric
15433861d79fSDimitry Andric StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc()));
15443861d79fSDimitry Andric const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
15453861d79fSDimitry Andric if (UO && UO->getOpcode() == UO_Minus) {
154644290647SDimitry Andric Check = SanitizerHandler::NegateOverflow;
15473861d79fSDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
15483861d79fSDimitry Andric DynamicData.push_back(Info.RHS);
15493861d79fSDimitry Andric } else {
15503861d79fSDimitry Andric if (BinaryOperator::isShiftOp(Opcode)) {
15513861d79fSDimitry Andric // Shift LHS negative or too large, or RHS out of bounds.
155244290647SDimitry Andric Check = SanitizerHandler::ShiftOutOfBounds;
15533861d79fSDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(Info.E);
15543861d79fSDimitry Andric StaticData.push_back(
15553861d79fSDimitry Andric CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType()));
15563861d79fSDimitry Andric StaticData.push_back(
15573861d79fSDimitry Andric CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType()));
15583861d79fSDimitry Andric } else if (Opcode == BO_Div || Opcode == BO_Rem) {
15593861d79fSDimitry Andric // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1).
156044290647SDimitry Andric Check = SanitizerHandler::DivremOverflow;
1561139f7f9bSDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
15623861d79fSDimitry Andric } else {
156339d628a0SDimitry Andric // Arithmetic overflow (+, -, *).
15643861d79fSDimitry Andric switch (Opcode) {
156544290647SDimitry Andric case BO_Add: Check = SanitizerHandler::AddOverflow; break;
156644290647SDimitry Andric case BO_Sub: Check = SanitizerHandler::SubOverflow; break;
156744290647SDimitry Andric case BO_Mul: Check = SanitizerHandler::MulOverflow; break;
15683861d79fSDimitry Andric default: llvm_unreachable("unexpected opcode for bin op check");
15693861d79fSDimitry Andric }
1570139f7f9bSDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
15713861d79fSDimitry Andric }
15723861d79fSDimitry Andric DynamicData.push_back(Info.LHS);
15733861d79fSDimitry Andric DynamicData.push_back(Info.RHS);
15743861d79fSDimitry Andric }
15753861d79fSDimitry Andric
157644290647SDimitry Andric CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
15773861d79fSDimitry Andric }
15783861d79fSDimitry Andric
1579f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
1580f22ef01cSRoman Divacky // Visitor Methods
1581f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
1582f22ef01cSRoman Divacky
VisitExpr(Expr * E)1583f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1584f22ef01cSRoman Divacky CGF.ErrorUnsupported(E, "scalar expression");
1585f22ef01cSRoman Divacky if (E->getType()->isVoidType())
158659d1ed5bSDimitry Andric return nullptr;
1587f22ef01cSRoman Divacky return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
1588f22ef01cSRoman Divacky }
1589f22ef01cSRoman Divacky
VisitShuffleVectorExpr(ShuffleVectorExpr * E)1590f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1591ffd1746dSEd Schouten // Vector Mask Case
1592e7145dcbSDimitry Andric if (E->getNumSubExprs() == 2) {
1593ffd1746dSEd Schouten Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));
1594ffd1746dSEd Schouten Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));
1595ffd1746dSEd Schouten Value *Mask;
1596ffd1746dSEd Schouten
15976122f3e6SDimitry Andric llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType());
1598ffd1746dSEd Schouten unsigned LHSElts = LTy->getNumElements();
1599ffd1746dSEd Schouten
1600ffd1746dSEd Schouten Mask = RHS;
1601ffd1746dSEd Schouten
16026122f3e6SDimitry Andric llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType());
1603ffd1746dSEd Schouten
1604ffd1746dSEd Schouten // Mask off the high bits of each shuffle index.
16050623d748SDimitry Andric Value *MaskBits =
16060623d748SDimitry Andric llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1607ffd1746dSEd Schouten Mask = Builder.CreateAnd(Mask, MaskBits, "mask");
1608ffd1746dSEd Schouten
1609ffd1746dSEd Schouten // newv = undef
1610ffd1746dSEd Schouten // mask = mask & maskbits
1611ffd1746dSEd Schouten // for each elt
1612ffd1746dSEd Schouten // n = extract mask i
1613ffd1746dSEd Schouten // x = extract val n
1614ffd1746dSEd Schouten // newv = insert newv, x, i
16156122f3e6SDimitry Andric llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(),
1616ffd1746dSEd Schouten MTy->getNumElements());
1617ffd1746dSEd Schouten Value* NewV = llvm::UndefValue::get(RTy);
1618ffd1746dSEd Schouten for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
161959d1ed5bSDimitry Andric Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
1620dff0c46cSDimitry Andric Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
1621ffd1746dSEd Schouten
1622ffd1746dSEd Schouten Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
1623dff0c46cSDimitry Andric NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
1624ffd1746dSEd Schouten }
1625ffd1746dSEd Schouten return NewV;
1626ffd1746dSEd Schouten }
1627ffd1746dSEd Schouten
1628f22ef01cSRoman Divacky Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
1629f22ef01cSRoman Divacky Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
1630ffd1746dSEd Schouten
16316122f3e6SDimitry Andric SmallVector<llvm::Constant*, 32> indices;
1632f785676fSDimitry Andric for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
1633f785676fSDimitry Andric llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
1634f785676fSDimitry Andric // Check for -1 and output it as undef in the IR.
1635f785676fSDimitry Andric if (Idx.isSigned() && Idx.isAllOnesValue())
1636f785676fSDimitry Andric indices.push_back(llvm::UndefValue::get(CGF.Int32Ty));
1637f785676fSDimitry Andric else
1638f785676fSDimitry Andric indices.push_back(Builder.getInt32(Idx.getZExtValue()));
1639ffd1746dSEd Schouten }
1640ffd1746dSEd Schouten
16412754fe60SDimitry Andric Value *SV = llvm::ConstantVector::get(indices);
1642f22ef01cSRoman Divacky return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
1643f22ef01cSRoman Divacky }
1644f785676fSDimitry Andric
VisitConvertVectorExpr(ConvertVectorExpr * E)1645f785676fSDimitry Andric Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1646f785676fSDimitry Andric QualType SrcType = E->getSrcExpr()->getType(),
1647f785676fSDimitry Andric DstType = E->getType();
1648f785676fSDimitry Andric
1649f785676fSDimitry Andric Value *Src = CGF.EmitScalarExpr(E->getSrcExpr());
1650f785676fSDimitry Andric
1651f785676fSDimitry Andric SrcType = CGF.getContext().getCanonicalType(SrcType);
1652f785676fSDimitry Andric DstType = CGF.getContext().getCanonicalType(DstType);
1653f785676fSDimitry Andric if (SrcType == DstType) return Src;
1654f785676fSDimitry Andric
1655f785676fSDimitry Andric assert(SrcType->isVectorType() &&
1656f785676fSDimitry Andric "ConvertVector source type must be a vector");
1657f785676fSDimitry Andric assert(DstType->isVectorType() &&
1658f785676fSDimitry Andric "ConvertVector destination type must be a vector");
1659f785676fSDimitry Andric
1660f785676fSDimitry Andric llvm::Type *SrcTy = Src->getType();
1661f785676fSDimitry Andric llvm::Type *DstTy = ConvertType(DstType);
1662f785676fSDimitry Andric
1663f785676fSDimitry Andric // Ignore conversions like int -> uint.
1664f785676fSDimitry Andric if (SrcTy == DstTy)
1665f785676fSDimitry Andric return Src;
1666f785676fSDimitry Andric
1667f785676fSDimitry Andric QualType SrcEltType = SrcType->getAs<VectorType>()->getElementType(),
1668f785676fSDimitry Andric DstEltType = DstType->getAs<VectorType>()->getElementType();
1669f785676fSDimitry Andric
1670f785676fSDimitry Andric assert(SrcTy->isVectorTy() &&
1671f785676fSDimitry Andric "ConvertVector source IR type must be a vector");
1672f785676fSDimitry Andric assert(DstTy->isVectorTy() &&
1673f785676fSDimitry Andric "ConvertVector destination IR type must be a vector");
1674f785676fSDimitry Andric
1675f785676fSDimitry Andric llvm::Type *SrcEltTy = SrcTy->getVectorElementType(),
1676f785676fSDimitry Andric *DstEltTy = DstTy->getVectorElementType();
1677f785676fSDimitry Andric
1678f785676fSDimitry Andric if (DstEltType->isBooleanType()) {
1679f785676fSDimitry Andric assert((SrcEltTy->isFloatingPointTy() ||
1680f785676fSDimitry Andric isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion");
1681f785676fSDimitry Andric
1682f785676fSDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1683f785676fSDimitry Andric if (SrcEltTy->isFloatingPointTy()) {
1684f785676fSDimitry Andric return Builder.CreateFCmpUNE(Src, Zero, "tobool");
1685f785676fSDimitry Andric } else {
1686f785676fSDimitry Andric return Builder.CreateICmpNE(Src, Zero, "tobool");
1687f785676fSDimitry Andric }
1688f785676fSDimitry Andric }
1689f785676fSDimitry Andric
1690f785676fSDimitry Andric // We have the arithmetic types: real int/float.
169159d1ed5bSDimitry Andric Value *Res = nullptr;
1692f785676fSDimitry Andric
1693f785676fSDimitry Andric if (isa<llvm::IntegerType>(SrcEltTy)) {
1694f785676fSDimitry Andric bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType();
1695f785676fSDimitry Andric if (isa<llvm::IntegerType>(DstEltTy))
1696f785676fSDimitry Andric Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1697f785676fSDimitry Andric else if (InputSigned)
1698f785676fSDimitry Andric Res = Builder.CreateSIToFP(Src, DstTy, "conv");
1699f785676fSDimitry Andric else
1700f785676fSDimitry Andric Res = Builder.CreateUIToFP(Src, DstTy, "conv");
1701f785676fSDimitry Andric } else if (isa<llvm::IntegerType>(DstEltTy)) {
1702f785676fSDimitry Andric assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion");
1703f785676fSDimitry Andric if (DstEltType->isSignedIntegerOrEnumerationType())
1704f785676fSDimitry Andric Res = Builder.CreateFPToSI(Src, DstTy, "conv");
1705f785676fSDimitry Andric else
1706f785676fSDimitry Andric Res = Builder.CreateFPToUI(Src, DstTy, "conv");
1707f785676fSDimitry Andric } else {
1708f785676fSDimitry Andric assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1709f785676fSDimitry Andric "Unknown real conversion");
1710f785676fSDimitry Andric if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1711f785676fSDimitry Andric Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
1712f785676fSDimitry Andric else
1713f785676fSDimitry Andric Res = Builder.CreateFPExt(Src, DstTy, "conv");
1714f785676fSDimitry Andric }
1715f785676fSDimitry Andric
1716f785676fSDimitry Andric return Res;
1717f785676fSDimitry Andric }
1718f785676fSDimitry Andric
VisitMemberExpr(MemberExpr * E)1719f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
17209a199699SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) {
17219a199699SDimitry Andric CGF.EmitIgnoredExpr(E->getBase());
1722*b5893f02SDimitry Andric return CGF.emitScalarConstant(Constant, E);
17239a199699SDimitry Andric } else {
1724*b5893f02SDimitry Andric Expr::EvalResult Result;
1725*b5893f02SDimitry Andric if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) {
1726*b5893f02SDimitry Andric llvm::APSInt Value = Result.Val.getInt();
17279a199699SDimitry Andric CGF.EmitIgnoredExpr(E->getBase());
1728dff0c46cSDimitry Andric return Builder.getInt(Value);
1729f22ef01cSRoman Divacky }
17309a199699SDimitry Andric }
17312754fe60SDimitry Andric
1732f22ef01cSRoman Divacky return EmitLoadOfLValue(E);
1733f22ef01cSRoman Divacky }
1734f22ef01cSRoman Divacky
VisitArraySubscriptExpr(ArraySubscriptExpr * E)1735f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
1736f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
1737f22ef01cSRoman Divacky
1738f22ef01cSRoman Divacky // Emit subscript expressions in rvalue context's. For most cases, this just
1739f22ef01cSRoman Divacky // loads the lvalue formed by the subscript expr. However, we have to be
1740f22ef01cSRoman Divacky // careful, because the base of a vector subscript is occasionally an rvalue,
1741f22ef01cSRoman Divacky // so we can't get it as an lvalue.
1742f22ef01cSRoman Divacky if (!E->getBase()->getType()->isVectorType())
1743f22ef01cSRoman Divacky return EmitLoadOfLValue(E);
1744f22ef01cSRoman Divacky
1745f22ef01cSRoman Divacky // Handle the vector case. The base must be a vector, the index must be an
1746f22ef01cSRoman Divacky // integer value.
1747f22ef01cSRoman Divacky Value *Base = Visit(E->getBase());
1748f22ef01cSRoman Divacky Value *Idx = Visit(E->getIdx());
1749139f7f9bSDimitry Andric QualType IdxTy = E->getIdx()->getType();
1750139f7f9bSDimitry Andric
175139d628a0SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
1752139f7f9bSDimitry Andric CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
1753139f7f9bSDimitry Andric
1754f22ef01cSRoman Divacky return Builder.CreateExtractElement(Base, Idx, "vecext");
1755f22ef01cSRoman Divacky }
1756f22ef01cSRoman Divacky
getMaskElt(llvm::ShuffleVectorInst * SVI,unsigned Idx,unsigned Off,llvm::Type * I32Ty)1757f22ef01cSRoman Divacky static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
17586122f3e6SDimitry Andric unsigned Off, llvm::Type *I32Ty) {
1759f22ef01cSRoman Divacky int MV = SVI->getMaskValue(Idx);
1760f22ef01cSRoman Divacky if (MV == -1)
1761f22ef01cSRoman Divacky return llvm::UndefValue::get(I32Ty);
1762f22ef01cSRoman Divacky return llvm::ConstantInt::get(I32Ty, Off+MV);
1763f22ef01cSRoman Divacky }
1764f22ef01cSRoman Divacky
getAsInt32(llvm::ConstantInt * C,llvm::Type * I32Ty)1765b6c25e0eSDimitry Andric static llvm::Constant *getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {
1766b6c25e0eSDimitry Andric if (C->getBitWidth() != 32) {
1767b6c25e0eSDimitry Andric assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1768b6c25e0eSDimitry Andric C->getZExtValue()) &&
1769b6c25e0eSDimitry Andric "Index operand too large for shufflevector mask!");
1770b6c25e0eSDimitry Andric return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1771b6c25e0eSDimitry Andric }
1772b6c25e0eSDimitry Andric return C;
1773b6c25e0eSDimitry Andric }
1774b6c25e0eSDimitry Andric
VisitInitListExpr(InitListExpr * E)1775f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
1776f22ef01cSRoman Divacky bool Ignore = TestAndClearIgnoreResultAssign();
1777f22ef01cSRoman Divacky (void)Ignore;
1778f22ef01cSRoman Divacky assert (Ignore == false && "init list ignored");
1779f22ef01cSRoman Divacky unsigned NumInitElements = E->getNumInits();
1780f22ef01cSRoman Divacky
1781f22ef01cSRoman Divacky if (E->hadArrayRangeDesignator())
1782f22ef01cSRoman Divacky CGF.ErrorUnsupported(E, "GNU array range designator extension");
1783f22ef01cSRoman Divacky
17846122f3e6SDimitry Andric llvm::VectorType *VType =
1785f22ef01cSRoman Divacky dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
1786f22ef01cSRoman Divacky
17876122f3e6SDimitry Andric if (!VType) {
17886122f3e6SDimitry Andric if (NumInitElements == 0) {
17896122f3e6SDimitry Andric // C++11 value-initialization for the scalar.
17906122f3e6SDimitry Andric return EmitNullValue(E->getType());
17916122f3e6SDimitry Andric }
1792f22ef01cSRoman Divacky // We have a scalar in braces. Just use the first element.
1793f22ef01cSRoman Divacky return Visit(E->getInit(0));
17946122f3e6SDimitry Andric }
1795f22ef01cSRoman Divacky
1796f22ef01cSRoman Divacky unsigned ResElts = VType->getNumElements();
1797f22ef01cSRoman Divacky
1798f22ef01cSRoman Divacky // Loop over initializers collecting the Value for each, and remembering
1799f22ef01cSRoman Divacky // whether the source was swizzle (ExtVectorElementExpr). This will allow
1800f22ef01cSRoman Divacky // us to fold the shuffle for the swizzle into the shuffle for the vector
1801f22ef01cSRoman Divacky // initializer, since LLVM optimizers generally do not want to touch
1802f22ef01cSRoman Divacky // shuffles.
1803f22ef01cSRoman Divacky unsigned CurIdx = 0;
1804f22ef01cSRoman Divacky bool VIsUndefShuffle = false;
1805f22ef01cSRoman Divacky llvm::Value *V = llvm::UndefValue::get(VType);
1806f22ef01cSRoman Divacky for (unsigned i = 0; i != NumInitElements; ++i) {
1807f22ef01cSRoman Divacky Expr *IE = E->getInit(i);
1808f22ef01cSRoman Divacky Value *Init = Visit(IE);
18096122f3e6SDimitry Andric SmallVector<llvm::Constant*, 16> Args;
1810f22ef01cSRoman Divacky
18116122f3e6SDimitry Andric llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
1812f22ef01cSRoman Divacky
1813f22ef01cSRoman Divacky // Handle scalar elements. If the scalar initializer is actually one
1814f22ef01cSRoman Divacky // element of a different vector of the same width, use shuffle instead of
1815f22ef01cSRoman Divacky // extract+insert.
1816f22ef01cSRoman Divacky if (!VVT) {
1817f22ef01cSRoman Divacky if (isa<ExtVectorElementExpr>(IE)) {
1818f22ef01cSRoman Divacky llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
1819f22ef01cSRoman Divacky
1820f22ef01cSRoman Divacky if (EI->getVectorOperandType()->getNumElements() == ResElts) {
1821f22ef01cSRoman Divacky llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
182259d1ed5bSDimitry Andric Value *LHS = nullptr, *RHS = nullptr;
1823f22ef01cSRoman Divacky if (CurIdx == 0) {
1824f22ef01cSRoman Divacky // insert into undef -> shuffle (src, undef)
1825b6c25e0eSDimitry Andric // shufflemask must use an i32
1826b6c25e0eSDimitry Andric Args.push_back(getAsInt32(C, CGF.Int32Ty));
1827dff0c46cSDimitry Andric Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
1828f22ef01cSRoman Divacky
1829f22ef01cSRoman Divacky LHS = EI->getVectorOperand();
1830f22ef01cSRoman Divacky RHS = V;
1831f22ef01cSRoman Divacky VIsUndefShuffle = true;
1832f22ef01cSRoman Divacky } else if (VIsUndefShuffle) {
1833f22ef01cSRoman Divacky // insert into undefshuffle && size match -> shuffle (v, src)
1834f22ef01cSRoman Divacky llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
1835f22ef01cSRoman Divacky for (unsigned j = 0; j != CurIdx; ++j)
1836ffd1746dSEd Schouten Args.push_back(getMaskElt(SVV, j, 0, CGF.Int32Ty));
18373b0f4066SDimitry Andric Args.push_back(Builder.getInt32(ResElts + C->getZExtValue()));
1838dff0c46cSDimitry Andric Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
1839f22ef01cSRoman Divacky
1840f22ef01cSRoman Divacky LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1841f22ef01cSRoman Divacky RHS = EI->getVectorOperand();
1842f22ef01cSRoman Divacky VIsUndefShuffle = false;
1843f22ef01cSRoman Divacky }
1844f22ef01cSRoman Divacky if (!Args.empty()) {
18452754fe60SDimitry Andric llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1846f22ef01cSRoman Divacky V = Builder.CreateShuffleVector(LHS, RHS, Mask);
1847f22ef01cSRoman Divacky ++CurIdx;
1848f22ef01cSRoman Divacky continue;
1849f22ef01cSRoman Divacky }
1850f22ef01cSRoman Divacky }
1851f22ef01cSRoman Divacky }
18523b0f4066SDimitry Andric V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
18533b0f4066SDimitry Andric "vecinit");
1854f22ef01cSRoman Divacky VIsUndefShuffle = false;
1855f22ef01cSRoman Divacky ++CurIdx;
1856f22ef01cSRoman Divacky continue;
1857f22ef01cSRoman Divacky }
1858f22ef01cSRoman Divacky
1859f22ef01cSRoman Divacky unsigned InitElts = VVT->getNumElements();
1860f22ef01cSRoman Divacky
1861f22ef01cSRoman Divacky // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's
1862f22ef01cSRoman Divacky // input is the same width as the vector being constructed, generate an
1863f22ef01cSRoman Divacky // optimized shuffle of the swizzle input into the result.
1864f22ef01cSRoman Divacky unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
1865f22ef01cSRoman Divacky if (isa<ExtVectorElementExpr>(IE)) {
1866f22ef01cSRoman Divacky llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
1867f22ef01cSRoman Divacky Value *SVOp = SVI->getOperand(0);
18686122f3e6SDimitry Andric llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType());
1869f22ef01cSRoman Divacky
1870f22ef01cSRoman Divacky if (OpTy->getNumElements() == ResElts) {
1871f22ef01cSRoman Divacky for (unsigned j = 0; j != CurIdx; ++j) {
1872f22ef01cSRoman Divacky // If the current vector initializer is a shuffle with undef, merge
1873f22ef01cSRoman Divacky // this shuffle directly into it.
1874f22ef01cSRoman Divacky if (VIsUndefShuffle) {
1875f22ef01cSRoman Divacky Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0,
1876ffd1746dSEd Schouten CGF.Int32Ty));
1877f22ef01cSRoman Divacky } else {
18783b0f4066SDimitry Andric Args.push_back(Builder.getInt32(j));
1879f22ef01cSRoman Divacky }
1880f22ef01cSRoman Divacky }
1881f22ef01cSRoman Divacky for (unsigned j = 0, je = InitElts; j != je; ++j)
1882ffd1746dSEd Schouten Args.push_back(getMaskElt(SVI, j, Offset, CGF.Int32Ty));
1883dff0c46cSDimitry Andric Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
1884f22ef01cSRoman Divacky
1885f22ef01cSRoman Divacky if (VIsUndefShuffle)
1886f22ef01cSRoman Divacky V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
1887f22ef01cSRoman Divacky
1888f22ef01cSRoman Divacky Init = SVOp;
1889f22ef01cSRoman Divacky }
1890f22ef01cSRoman Divacky }
1891f22ef01cSRoman Divacky
1892f22ef01cSRoman Divacky // Extend init to result vector length, and then shuffle its contribution
1893f22ef01cSRoman Divacky // to the vector initializer into V.
1894f22ef01cSRoman Divacky if (Args.empty()) {
1895f22ef01cSRoman Divacky for (unsigned j = 0; j != InitElts; ++j)
18963b0f4066SDimitry Andric Args.push_back(Builder.getInt32(j));
1897dff0c46cSDimitry Andric Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
18982754fe60SDimitry Andric llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1899f22ef01cSRoman Divacky Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT),
1900f22ef01cSRoman Divacky Mask, "vext");
1901f22ef01cSRoman Divacky
1902f22ef01cSRoman Divacky Args.clear();
1903f22ef01cSRoman Divacky for (unsigned j = 0; j != CurIdx; ++j)
19043b0f4066SDimitry Andric Args.push_back(Builder.getInt32(j));
1905f22ef01cSRoman Divacky for (unsigned j = 0; j != InitElts; ++j)
19063b0f4066SDimitry Andric Args.push_back(Builder.getInt32(j+Offset));
1907dff0c46cSDimitry Andric Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
1908f22ef01cSRoman Divacky }
1909f22ef01cSRoman Divacky
1910f22ef01cSRoman Divacky // If V is undef, make sure it ends up on the RHS of the shuffle to aid
1911f22ef01cSRoman Divacky // merging subsequent shuffles into this one.
1912f22ef01cSRoman Divacky if (CurIdx == 0)
1913f22ef01cSRoman Divacky std::swap(V, Init);
19142754fe60SDimitry Andric llvm::Constant *Mask = llvm::ConstantVector::get(Args);
1915f22ef01cSRoman Divacky V = Builder.CreateShuffleVector(V, Init, Mask, "vecinit");
1916f22ef01cSRoman Divacky VIsUndefShuffle = isa<llvm::UndefValue>(Init);
1917f22ef01cSRoman Divacky CurIdx += InitElts;
1918f22ef01cSRoman Divacky }
1919f22ef01cSRoman Divacky
1920f22ef01cSRoman Divacky // FIXME: evaluate codegen vs. shuffling against constant null vector.
1921f22ef01cSRoman Divacky // Emit remaining default initializers.
19226122f3e6SDimitry Andric llvm::Type *EltTy = VType->getElementType();
1923f22ef01cSRoman Divacky
1924f22ef01cSRoman Divacky // Emit remaining default initializers
1925f22ef01cSRoman Divacky for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
19263b0f4066SDimitry Andric Value *Idx = Builder.getInt32(CurIdx);
1927f22ef01cSRoman Divacky llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
1928f22ef01cSRoman Divacky V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
1929f22ef01cSRoman Divacky }
1930f22ef01cSRoman Divacky return V;
1931f22ef01cSRoman Divacky }
1932f22ef01cSRoman Divacky
ShouldNullCheckClassCastValue(const CastExpr * CE)19330623d748SDimitry Andric bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) {
1934f22ef01cSRoman Divacky const Expr *E = CE->getSubExpr();
1935f22ef01cSRoman Divacky
1936e580952dSDimitry Andric if (CE->getCastKind() == CK_UncheckedDerivedToBase)
1937f22ef01cSRoman Divacky return false;
1938f22ef01cSRoman Divacky
19390623d748SDimitry Andric if (isa<CXXThisExpr>(E->IgnoreParens())) {
1940f22ef01cSRoman Divacky // We always assume that 'this' is never null.
1941f22ef01cSRoman Divacky return false;
1942f22ef01cSRoman Divacky }
1943f22ef01cSRoman Divacky
1944f22ef01cSRoman Divacky if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
1945e580952dSDimitry Andric // And that glvalue casts are never null.
1946e580952dSDimitry Andric if (ICE->getValueKind() != VK_RValue)
1947f22ef01cSRoman Divacky return false;
1948f22ef01cSRoman Divacky }
1949f22ef01cSRoman Divacky
1950f22ef01cSRoman Divacky return true;
1951f22ef01cSRoman Divacky }
1952f22ef01cSRoman Divacky
1953f22ef01cSRoman Divacky // VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts
1954f22ef01cSRoman Divacky // have to handle a more broad range of conversions than explicit casts, as they
1955f22ef01cSRoman Divacky // handle things like function to ptr-to-function decay etc.
VisitCastExpr(CastExpr * CE)195617a519f9SDimitry Andric Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
1957f22ef01cSRoman Divacky Expr *E = CE->getSubExpr();
1958f22ef01cSRoman Divacky QualType DestTy = CE->getType();
1959e580952dSDimitry Andric CastKind Kind = CE->getCastKind();
1960f22ef01cSRoman Divacky
1961e7145dcbSDimitry Andric // These cases are generally not written to ignore the result of
1962e7145dcbSDimitry Andric // evaluating their sub-expressions, so we clear this now.
1963e7145dcbSDimitry Andric bool Ignored = TestAndClearIgnoreResultAssign();
1964f22ef01cSRoman Divacky
1965f22ef01cSRoman Divacky // Since almost all cast kinds apply to scalars, this switch doesn't have
1966f22ef01cSRoman Divacky // a default case, so the compiler will warn on a missing case. The cases
1967f22ef01cSRoman Divacky // are in the same order as in the CastKind enum.
1968f22ef01cSRoman Divacky switch (Kind) {
19692754fe60SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
19703861d79fSDimitry Andric case CK_BuiltinFnToFnPtr:
19713861d79fSDimitry Andric llvm_unreachable("builtin functions are handled elsewhere");
1972f22ef01cSRoman Divacky
1973e580952dSDimitry Andric case CK_LValueBitCast:
1974e580952dSDimitry Andric case CK_ObjCObjectLValueCast: {
19750623d748SDimitry Andric Address Addr = EmitLValue(E).getAddress();
19760623d748SDimitry Andric Addr = Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(DestTy));
19770623d748SDimitry Andric LValue LV = CGF.MakeAddrLValue(Addr, DestTy);
19780623d748SDimitry Andric return EmitLoadOfLValue(LV, CE->getExprLoc());
1979ffd1746dSEd Schouten }
1980ffd1746dSEd Schouten
19816122f3e6SDimitry Andric case CK_CPointerToObjCPointerCast:
19826122f3e6SDimitry Andric case CK_BlockPointerToObjCPointerCast:
1983e580952dSDimitry Andric case CK_AnyPointerToBlockPointerCast:
1984e580952dSDimitry Andric case CK_BitCast: {
1985f22ef01cSRoman Divacky Value *Src = Visit(const_cast<Expr*>(E));
198659d1ed5bSDimitry Andric llvm::Type *SrcTy = Src->getType();
198759d1ed5bSDimitry Andric llvm::Type *DstTy = ConvertType(DestTy);
198859d1ed5bSDimitry Andric if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
198959d1ed5bSDimitry Andric SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
199039d628a0SDimitry Andric llvm_unreachable("wrong cast for pointers in different address spaces"
199139d628a0SDimitry Andric "(must be an address space cast)!");
199259d1ed5bSDimitry Andric }
199333956c43SDimitry Andric
199433956c43SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
199533956c43SDimitry Andric if (auto PT = DestTy->getAs<PointerType>())
199633956c43SDimitry Andric CGF.EmitVTablePtrCheckForCast(PT->getPointeeType(), Src,
19978f0fd8f6SDimitry Andric /*MayBeNull=*/true,
19988f0fd8f6SDimitry Andric CodeGenFunction::CFITCK_UnrelatedCast,
1999*b5893f02SDimitry Andric CE->getBeginLoc());
200033956c43SDimitry Andric }
200133956c43SDimitry Andric
20024ba319b5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
20034ba319b5SDimitry Andric const QualType SrcType = E->getType();
20044ba319b5SDimitry Andric
20054ba319b5SDimitry Andric if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) {
20064ba319b5SDimitry Andric // Casting to pointer that could carry dynamic information (provided by
20074ba319b5SDimitry Andric // invariant.group) requires launder.
20084ba319b5SDimitry Andric Src = Builder.CreateLaunderInvariantGroup(Src);
20094ba319b5SDimitry Andric } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) {
20104ba319b5SDimitry Andric // Casting to pointer that does not carry dynamic information (provided
20114ba319b5SDimitry Andric // by invariant.group) requires stripping it. Note that we don't do it
20124ba319b5SDimitry Andric // if the source could not be dynamic type and destination could be
20134ba319b5SDimitry Andric // dynamic because dynamic information is already laundered. It is
20144ba319b5SDimitry Andric // because launder(strip(src)) == launder(src), so there is no need to
20154ba319b5SDimitry Andric // add extra strip before launder.
20164ba319b5SDimitry Andric Src = Builder.CreateStripInvariantGroup(Src);
20174ba319b5SDimitry Andric }
20184ba319b5SDimitry Andric }
20194ba319b5SDimitry Andric
202059d1ed5bSDimitry Andric return Builder.CreateBitCast(Src, DstTy);
202159d1ed5bSDimitry Andric }
202259d1ed5bSDimitry Andric case CK_AddressSpaceConversion: {
202344290647SDimitry Andric Expr::EvalResult Result;
202444290647SDimitry Andric if (E->EvaluateAsRValue(Result, CGF.getContext()) &&
202544290647SDimitry Andric Result.Val.isNullPointer()) {
202644290647SDimitry Andric // If E has side effect, it is emitted even if its final result is a
202744290647SDimitry Andric // null pointer. In that case, a DCE pass should be able to
202844290647SDimitry Andric // eliminate the useless instructions emitted during translating E.
202944290647SDimitry Andric if (Result.HasSideEffects)
203044290647SDimitry Andric Visit(E);
203144290647SDimitry Andric return CGF.CGM.getNullPointer(cast<llvm::PointerType>(
203244290647SDimitry Andric ConvertType(DestTy)), DestTy);
203344290647SDimitry Andric }
2034e7145dcbSDimitry Andric // Since target may map different address spaces in AST to the same address
2035e7145dcbSDimitry Andric // space, an address space conversion may end up as a bitcast.
2036d8866befSDimitry Andric return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
2037d8866befSDimitry Andric CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
2038d8866befSDimitry Andric DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
2039f22ef01cSRoman Divacky }
2040dff0c46cSDimitry Andric case CK_AtomicToNonAtomic:
2041dff0c46cSDimitry Andric case CK_NonAtomicToAtomic:
2042e580952dSDimitry Andric case CK_NoOp:
2043e580952dSDimitry Andric case CK_UserDefinedConversion:
2044f22ef01cSRoman Divacky return Visit(const_cast<Expr*>(E));
2045f22ef01cSRoman Divacky
2046e580952dSDimitry Andric case CK_BaseToDerived: {
20473861d79fSDimitry Andric const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl();
20483861d79fSDimitry Andric assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!");
2049f22ef01cSRoman Divacky
20500623d748SDimitry Andric Address Base = CGF.EmitPointerWithAlignment(E);
20510623d748SDimitry Andric Address Derived =
20520623d748SDimitry Andric CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl,
2053f785676fSDimitry Andric CE->path_begin(), CE->path_end(),
20540623d748SDimitry Andric CGF.ShouldNullCheckClassCastValue(CE));
2055f785676fSDimitry Andric
2056139f7f9bSDimitry Andric // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
2057139f7f9bSDimitry Andric // performed and the object is not of the derived type.
205859d1ed5bSDimitry Andric if (CGF.sanitizePerformTypeCheck())
2059139f7f9bSDimitry Andric CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
20600623d748SDimitry Andric Derived.getPointer(), DestTy->getPointeeType());
2061139f7f9bSDimitry Andric
206233956c43SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast))
2063*b5893f02SDimitry Andric CGF.EmitVTablePtrCheckForCast(
2064*b5893f02SDimitry Andric DestTy->getPointeeType(), Derived.getPointer(),
2065*b5893f02SDimitry Andric /*MayBeNull=*/true, CodeGenFunction::CFITCK_DerivedCast,
2066*b5893f02SDimitry Andric CE->getBeginLoc());
206733956c43SDimitry Andric
20680623d748SDimitry Andric return Derived.getPointer();
2069f22ef01cSRoman Divacky }
2070e580952dSDimitry Andric case CK_UncheckedDerivedToBase:
2071e580952dSDimitry Andric case CK_DerivedToBase: {
20720623d748SDimitry Andric // The EmitPointerWithAlignment path does this fine; just discard
20730623d748SDimitry Andric // the alignment.
20740623d748SDimitry Andric return CGF.EmitPointerWithAlignment(CE).getPointer();
2075f22ef01cSRoman Divacky }
20760623d748SDimitry Andric
2077e580952dSDimitry Andric case CK_Dynamic: {
20780623d748SDimitry Andric Address V = CGF.EmitPointerWithAlignment(E);
2079f22ef01cSRoman Divacky const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
2080f22ef01cSRoman Divacky return CGF.EmitDynamicCast(V, DCE);
2081f22ef01cSRoman Divacky }
2082f22ef01cSRoman Divacky
20830623d748SDimitry Andric case CK_ArrayToPointerDecay:
20840623d748SDimitry Andric return CGF.EmitArrayToPointerDecay(E).getPointer();
2085e580952dSDimitry Andric case CK_FunctionToPointerDecay:
20860623d748SDimitry Andric return EmitLValue(E).getPointer();
2087f22ef01cSRoman Divacky
20882754fe60SDimitry Andric case CK_NullToPointer:
20892754fe60SDimitry Andric if (MustVisitNullValue(E))
20902754fe60SDimitry Andric (void) Visit(E);
20912754fe60SDimitry Andric
209244290647SDimitry Andric return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
209344290647SDimitry Andric DestTy);
20942754fe60SDimitry Andric
2095e580952dSDimitry Andric case CK_NullToMemberPointer: {
20962754fe60SDimitry Andric if (MustVisitNullValue(E))
2097e580952dSDimitry Andric (void) Visit(E);
2098f22ef01cSRoman Divacky
2099e580952dSDimitry Andric const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
2100e580952dSDimitry Andric return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
2101e580952dSDimitry Andric }
2102e580952dSDimitry Andric
2103dff0c46cSDimitry Andric case CK_ReinterpretMemberPointer:
2104e580952dSDimitry Andric case CK_BaseToDerivedMemberPointer:
2105e580952dSDimitry Andric case CK_DerivedToBaseMemberPointer: {
2106f22ef01cSRoman Divacky Value *Src = Visit(E);
2107f22ef01cSRoman Divacky
2108e580952dSDimitry Andric // Note that the AST doesn't distinguish between checked and
2109e580952dSDimitry Andric // unchecked member pointer conversions, so we always have to
2110e580952dSDimitry Andric // implement checked conversions here. This is inefficient when
2111e580952dSDimitry Andric // actual control flow may be required in order to perform the
2112e580952dSDimitry Andric // check, which it is for data member pointers (but not member
2113e580952dSDimitry Andric // function pointers on Itanium and ARM).
2114e580952dSDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);
2115f22ef01cSRoman Divacky }
2116ffd1746dSEd Schouten
21176122f3e6SDimitry Andric case CK_ARCProduceObject:
211817a519f9SDimitry Andric return CGF.EmitARCRetainScalarExpr(E);
21196122f3e6SDimitry Andric case CK_ARCConsumeObject:
212017a519f9SDimitry Andric return CGF.EmitObjCConsumeObject(E->getType(), Visit(E));
2121e7145dcbSDimitry Andric case CK_ARCReclaimReturnedObject:
2122e7145dcbSDimitry Andric return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored);
21236122f3e6SDimitry Andric case CK_ARCExtendBlockObject:
21246122f3e6SDimitry Andric return CGF.EmitARCExtendBlockObject(E);
212517a519f9SDimitry Andric
2126dff0c46cSDimitry Andric case CK_CopyAndAutoreleaseBlockObject:
2127dff0c46cSDimitry Andric return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType());
2128dff0c46cSDimitry Andric
21292754fe60SDimitry Andric case CK_FloatingRealToComplex:
21302754fe60SDimitry Andric case CK_FloatingComplexCast:
21312754fe60SDimitry Andric case CK_IntegralRealToComplex:
21322754fe60SDimitry Andric case CK_IntegralComplexCast:
21332754fe60SDimitry Andric case CK_IntegralComplexToFloatingComplex:
21342754fe60SDimitry Andric case CK_FloatingComplexToIntegralComplex:
2135e580952dSDimitry Andric case CK_ConstructorConversion:
21362754fe60SDimitry Andric case CK_ToUnion:
21372754fe60SDimitry Andric llvm_unreachable("scalar cast to non-scalar value");
21382754fe60SDimitry Andric
21392754fe60SDimitry Andric case CK_LValueToRValue:
21402754fe60SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
21412754fe60SDimitry Andric assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!");
21422754fe60SDimitry Andric return Visit(const_cast<Expr*>(E));
21432754fe60SDimitry Andric
2144e580952dSDimitry Andric case CK_IntegralToPointer: {
2145f22ef01cSRoman Divacky Value *Src = Visit(const_cast<Expr*>(E));
2146f22ef01cSRoman Divacky
2147f22ef01cSRoman Divacky // First, convert to the correct width so that we control the kind of
2148f22ef01cSRoman Divacky // extension.
214944290647SDimitry Andric auto DestLLVMTy = ConvertType(DestTy);
215044290647SDimitry Andric llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy);
2151bd5abe19SDimitry Andric bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType();
2152f22ef01cSRoman Divacky llvm::Value* IntResult =
2153f22ef01cSRoman Divacky Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
2154f22ef01cSRoman Divacky
21554ba319b5SDimitry Andric auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2156e580952dSDimitry Andric
21574ba319b5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
21584ba319b5SDimitry Andric // Going from integer to pointer that could be dynamic requires reloading
21594ba319b5SDimitry Andric // dynamic information from invariant.group.
21604ba319b5SDimitry Andric if (DestTy.mayBeDynamicClass())
21614ba319b5SDimitry Andric IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
21624ba319b5SDimitry Andric }
21634ba319b5SDimitry Andric return IntToPtr;
21644ba319b5SDimitry Andric }
21654ba319b5SDimitry Andric case CK_PointerToIntegral: {
21664ba319b5SDimitry Andric assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
21674ba319b5SDimitry Andric auto *PtrExpr = Visit(E);
21684ba319b5SDimitry Andric
21694ba319b5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
21704ba319b5SDimitry Andric const QualType SrcType = E->getType();
21714ba319b5SDimitry Andric
21724ba319b5SDimitry Andric // Casting to integer requires stripping dynamic information as it does
21734ba319b5SDimitry Andric // not carries it.
21744ba319b5SDimitry Andric if (SrcType.mayBeDynamicClass())
21754ba319b5SDimitry Andric PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
21764ba319b5SDimitry Andric }
21774ba319b5SDimitry Andric
21784ba319b5SDimitry Andric return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
21794ba319b5SDimitry Andric }
2180e580952dSDimitry Andric case CK_ToVoid: {
21812754fe60SDimitry Andric CGF.EmitIgnoredExpr(E);
218259d1ed5bSDimitry Andric return nullptr;
2183f22ef01cSRoman Divacky }
2184e580952dSDimitry Andric case CK_VectorSplat: {
21856122f3e6SDimitry Andric llvm::Type *DstTy = ConvertType(DestTy);
2186444ed5c5SDimitry Andric Value *Elt = Visit(const_cast<Expr*>(E));
2187f22ef01cSRoman Divacky // Splat the element across to all elements
2188e7145dcbSDimitry Andric unsigned NumElements = DstTy->getVectorNumElements();
218959d1ed5bSDimitry Andric return Builder.CreateVectorSplat(NumElements, Elt, "splat");
2190f22ef01cSRoman Divacky }
21912754fe60SDimitry Andric
2192*b5893f02SDimitry Andric case CK_FixedPointCast:
2193*b5893f02SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2194*b5893f02SDimitry Andric CE->getExprLoc());
2195*b5893f02SDimitry Andric
2196*b5893f02SDimitry Andric case CK_FixedPointToBoolean:
2197*b5893f02SDimitry Andric assert(E->getType()->isFixedPointType() &&
2198*b5893f02SDimitry Andric "Expected src type to be fixed point type");
2199*b5893f02SDimitry Andric assert(DestTy->isBooleanType() && "Expected dest type to be boolean type");
2200*b5893f02SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2201*b5893f02SDimitry Andric CE->getExprLoc());
2202*b5893f02SDimitry Andric
22034ba319b5SDimitry Andric case CK_IntegralCast: {
22044ba319b5SDimitry Andric ScalarConversionOpts Opts;
2205*b5893f02SDimitry Andric if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2206*b5893f02SDimitry Andric if (!ICE->isPartOfExplicitCast())
2207*b5893f02SDimitry Andric Opts = ScalarConversionOpts(CGF.SanOpts);
22084ba319b5SDimitry Andric }
22094ba319b5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
22104ba319b5SDimitry Andric CE->getExprLoc(), Opts);
22114ba319b5SDimitry Andric }
2212e580952dSDimitry Andric case CK_IntegralToFloating:
2213e580952dSDimitry Andric case CK_FloatingToIntegral:
2214e580952dSDimitry Andric case CK_FloatingCast:
22150623d748SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
22160623d748SDimitry Andric CE->getExprLoc());
22174ba319b5SDimitry Andric case CK_BooleanToSignedIntegral: {
22184ba319b5SDimitry Andric ScalarConversionOpts Opts;
22194ba319b5SDimitry Andric Opts.TreatBooleanAsSigned = true;
2220444ed5c5SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
22214ba319b5SDimitry Andric CE->getExprLoc(), Opts);
22224ba319b5SDimitry Andric }
22232754fe60SDimitry Andric case CK_IntegralToBoolean:
22242754fe60SDimitry Andric return EmitIntToBoolConversion(Visit(E));
22252754fe60SDimitry Andric case CK_PointerToBoolean:
222644290647SDimitry Andric return EmitPointerToBoolConversion(Visit(E), E->getType());
22272754fe60SDimitry Andric case CK_FloatingToBoolean:
22282754fe60SDimitry Andric return EmitFloatToBoolConversion(Visit(E));
2229e580952dSDimitry Andric case CK_MemberPointerToBoolean: {
2230e580952dSDimitry Andric llvm::Value *MemPtr = Visit(E);
2231e580952dSDimitry Andric const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
2232e580952dSDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
2233e580952dSDimitry Andric }
2234f22ef01cSRoman Divacky
22352754fe60SDimitry Andric case CK_FloatingComplexToReal:
22362754fe60SDimitry Andric case CK_IntegralComplexToReal:
22372754fe60SDimitry Andric return CGF.EmitComplexExpr(E, false, true).first;
2238f22ef01cSRoman Divacky
22392754fe60SDimitry Andric case CK_FloatingComplexToBoolean:
22402754fe60SDimitry Andric case CK_IntegralComplexToBoolean: {
22412754fe60SDimitry Andric CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
2242f22ef01cSRoman Divacky
22432754fe60SDimitry Andric // TODO: kill this function off, inline appropriate case here
22440623d748SDimitry Andric return EmitComplexToScalarConversion(V, E->getType(), DestTy,
22450623d748SDimitry Andric CE->getExprLoc());
2246f22ef01cSRoman Divacky }
2247f22ef01cSRoman Divacky
2248*b5893f02SDimitry Andric case CK_ZeroToOCLOpaqueType: {
2249*b5893f02SDimitry Andric assert((DestTy->isEventT() || DestTy->isQueueT() ||
2250*b5893f02SDimitry Andric DestTy->isOCLIntelSubgroupAVCType()) &&
2251*b5893f02SDimitry Andric "CK_ZeroToOCLEvent cast on non-event type");
225244290647SDimitry Andric return llvm::Constant::getNullValue(ConvertType(DestTy));
22532754fe60SDimitry Andric }
22542754fe60SDimitry Andric
225544290647SDimitry Andric case CK_IntToOCLSampler:
225644290647SDimitry Andric return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
225744290647SDimitry Andric
225844290647SDimitry Andric } // end of switch
225944290647SDimitry Andric
22602754fe60SDimitry Andric llvm_unreachable("unknown scalar cast");
2261f22ef01cSRoman Divacky }
2262f22ef01cSRoman Divacky
VisitStmtExpr(const StmtExpr * E)2263f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
22642754fe60SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF);
22650623d748SDimitry Andric Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(),
2266f785676fSDimitry Andric !E->getType()->isVoidType());
22670623d748SDimitry Andric if (!RetAlloca.isValid())
226859d1ed5bSDimitry Andric return nullptr;
2269f785676fSDimitry Andric return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()),
2270f785676fSDimitry Andric E->getExprLoc());
2271f22ef01cSRoman Divacky }
2272f22ef01cSRoman Divacky
VisitExprWithCleanups(ExprWithCleanups * E)227320e90f04SDimitry Andric Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
227420e90f04SDimitry Andric CGF.enterFullExpression(E);
227520e90f04SDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF);
227620e90f04SDimitry Andric Value *V = Visit(E->getSubExpr());
227720e90f04SDimitry Andric // Defend against dominance problems caused by jumps out of expression
227820e90f04SDimitry Andric // evaluation through the shared cleanup block.
227920e90f04SDimitry Andric Scope.ForceCleanup({&V});
228020e90f04SDimitry Andric return V;
228120e90f04SDimitry Andric }
228220e90f04SDimitry Andric
2283f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
2284f22ef01cSRoman Divacky // Unary Operators
2285f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
2286f22ef01cSRoman Divacky
createBinOpInfoFromIncDec(const UnaryOperator * E,llvm::Value * InVal,bool IsInc)228733956c43SDimitry Andric static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
228833956c43SDimitry Andric llvm::Value *InVal, bool IsInc) {
2289ffd1746dSEd Schouten BinOpInfo BinOp;
2290ffd1746dSEd Schouten BinOp.LHS = InVal;
229133956c43SDimitry Andric BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
2292ffd1746dSEd Schouten BinOp.Ty = E->getType();
229333956c43SDimitry Andric BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
229420e90f04SDimitry Andric // FIXME: once UnaryOperator carries FPFeatures, copy it here.
2295ffd1746dSEd Schouten BinOp.E = E;
229633956c43SDimitry Andric return BinOp;
229733956c43SDimitry Andric }
229833956c43SDimitry Andric
EmitIncDecConsiderOverflowBehavior(const UnaryOperator * E,llvm::Value * InVal,bool IsInc)229933956c43SDimitry Andric llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
230033956c43SDimitry Andric const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {
230133956c43SDimitry Andric llvm::Value *Amount =
230233956c43SDimitry Andric llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true);
230333956c43SDimitry Andric StringRef Name = IsInc ? "inc" : "dec";
230433956c43SDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
230533956c43SDimitry Andric case LangOptions::SOB_Defined:
230633956c43SDimitry Andric return Builder.CreateAdd(InVal, Amount, Name);
230733956c43SDimitry Andric case LangOptions::SOB_Undefined:
230833956c43SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
230933956c43SDimitry Andric return Builder.CreateNSWAdd(InVal, Amount, Name);
2310*b5893f02SDimitry Andric LLVM_FALLTHROUGH;
231133956c43SDimitry Andric case LangOptions::SOB_Trapping:
23124ba319b5SDimitry Andric if (!E->canOverflow())
231320e90f04SDimitry Andric return Builder.CreateNSWAdd(InVal, Amount, Name);
231433956c43SDimitry Andric return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc));
2315ffd1746dSEd Schouten }
23166122f3e6SDimitry Andric llvm_unreachable("Unknown SignedOverflowBehaviorTy");
2317ffd1746dSEd Schouten }
23182754fe60SDimitry Andric
23192754fe60SDimitry Andric llvm::Value *
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)23202754fe60SDimitry Andric ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
23212754fe60SDimitry Andric bool isInc, bool isPre) {
23222754fe60SDimitry Andric
23232754fe60SDimitry Andric QualType type = E->getSubExpr()->getType();
232459d1ed5bSDimitry Andric llvm::PHINode *atomicPHI = nullptr;
2325139f7f9bSDimitry Andric llvm::Value *value;
2326139f7f9bSDimitry Andric llvm::Value *input;
23272754fe60SDimitry Andric
23282754fe60SDimitry Andric int amount = (isInc ? 1 : -1);
2329b40b48b8SDimitry Andric bool isSubtraction = !isInc;
23302754fe60SDimitry Andric
2331dff0c46cSDimitry Andric if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
2332139f7f9bSDimitry Andric type = atomicTy->getValueType();
2333139f7f9bSDimitry Andric if (isInc && type->isBooleanType()) {
2334139f7f9bSDimitry Andric llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type);
2335139f7f9bSDimitry Andric if (isPre) {
23360623d748SDimitry Andric Builder.CreateStore(True, LV.getAddress(), LV.isVolatileQualified())
2337e7145dcbSDimitry Andric ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2338139f7f9bSDimitry Andric return Builder.getTrue();
2339139f7f9bSDimitry Andric }
2340139f7f9bSDimitry Andric // For atomic bool increment, we just store true and return it for
2341139f7f9bSDimitry Andric // preincrement, do an atomic swap with true for postincrement
2342e7145dcbSDimitry Andric return Builder.CreateAtomicRMW(
2343e7145dcbSDimitry Andric llvm::AtomicRMWInst::Xchg, LV.getPointer(), True,
2344e7145dcbSDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
2345139f7f9bSDimitry Andric }
2346139f7f9bSDimitry Andric // Special case for atomic increment / decrement on integers, emit
2347139f7f9bSDimitry Andric // atomicrmw instructions. We skip this if we want to be doing overflow
2348139f7f9bSDimitry Andric // checking, and fall into the slow path with the atomic cmpxchg loop.
2349139f7f9bSDimitry Andric if (!type->isBooleanType() && type->isIntegerType() &&
2350139f7f9bSDimitry Andric !(type->isUnsignedIntegerType() &&
235139d628a0SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
2352139f7f9bSDimitry Andric CGF.getLangOpts().getSignedOverflowBehavior() !=
2353139f7f9bSDimitry Andric LangOptions::SOB_Trapping) {
2354139f7f9bSDimitry Andric llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2355139f7f9bSDimitry Andric llvm::AtomicRMWInst::Sub;
2356139f7f9bSDimitry Andric llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2357139f7f9bSDimitry Andric llvm::Instruction::Sub;
2358139f7f9bSDimitry Andric llvm::Value *amt = CGF.EmitToMemory(
2359139f7f9bSDimitry Andric llvm::ConstantInt::get(ConvertType(type), 1, true), type);
2360139f7f9bSDimitry Andric llvm::Value *old = Builder.CreateAtomicRMW(aop,
2361e7145dcbSDimitry Andric LV.getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent);
2362139f7f9bSDimitry Andric return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2363139f7f9bSDimitry Andric }
2364f785676fSDimitry Andric value = EmitLoadOfLValue(LV, E->getExprLoc());
2365139f7f9bSDimitry Andric input = value;
2366139f7f9bSDimitry Andric // For every other atomic operation, we need to emit a load-op-cmpxchg loop
2367dff0c46cSDimitry Andric llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2368dff0c46cSDimitry Andric llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
2369139f7f9bSDimitry Andric value = CGF.EmitToMemory(value, type);
2370dff0c46cSDimitry Andric Builder.CreateBr(opBB);
2371dff0c46cSDimitry Andric Builder.SetInsertPoint(opBB);
2372dff0c46cSDimitry Andric atomicPHI = Builder.CreatePHI(value->getType(), 2);
2373dff0c46cSDimitry Andric atomicPHI->addIncoming(value, startBB);
2374dff0c46cSDimitry Andric value = atomicPHI;
2375139f7f9bSDimitry Andric } else {
2376f785676fSDimitry Andric value = EmitLoadOfLValue(LV, E->getExprLoc());
2377139f7f9bSDimitry Andric input = value;
2378dff0c46cSDimitry Andric }
2379dff0c46cSDimitry Andric
23802754fe60SDimitry Andric // Special case of integer increment that we have to check first: bool++.
23812754fe60SDimitry Andric // Due to promotion rules, we get:
23822754fe60SDimitry Andric // bool++ -> bool = bool + 1
23832754fe60SDimitry Andric // -> bool = (int)bool + 1
23842754fe60SDimitry Andric // -> bool = ((int)bool + 1 != 0)
23852754fe60SDimitry Andric // An interesting aspect of this is that increment is always true.
23862754fe60SDimitry Andric // Decrement does not have this property.
23872754fe60SDimitry Andric if (isInc && type->isBooleanType()) {
23882754fe60SDimitry Andric value = Builder.getTrue();
23892754fe60SDimitry Andric
23902754fe60SDimitry Andric // Most common case by far: integer increment.
23912754fe60SDimitry Andric } else if (type->isIntegerType()) {
23923b0f4066SDimitry Andric // Note that signed integer inc/dec with width less than int can't
23933b0f4066SDimitry Andric // overflow because of promotion rules; we're just eliding a few steps here.
23944ba319b5SDimitry Andric if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
239533956c43SDimitry Andric value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
23964ba319b5SDimitry Andric } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
239739d628a0SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
239833956c43SDimitry Andric value =
239933956c43SDimitry Andric EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc));
240033956c43SDimitry Andric } else {
240133956c43SDimitry Andric llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
24022754fe60SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
240333956c43SDimitry Andric }
24042754fe60SDimitry Andric
24052754fe60SDimitry Andric // Next most common: pointer increment.
24062754fe60SDimitry Andric } else if (const PointerType *ptr = type->getAs<PointerType>()) {
24072754fe60SDimitry Andric QualType type = ptr->getPointeeType();
24082754fe60SDimitry Andric
24092754fe60SDimitry Andric // VLA types don't have constant size.
241017a519f9SDimitry Andric if (const VariableArrayType *vla
241117a519f9SDimitry Andric = CGF.getContext().getAsVariableArrayType(type)) {
24124ba319b5SDimitry Andric llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
241317a519f9SDimitry Andric if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
24143861d79fSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
241517a519f9SDimitry Andric value = Builder.CreateGEP(value, numElts, "vla.inc");
24163b0f4066SDimitry Andric else
2417b40b48b8SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(
2418b40b48b8SDimitry Andric value, numElts, /*SignedIndices=*/false, isSubtraction,
241924d58133SDimitry Andric E->getExprLoc(), "vla.inc");
24202754fe60SDimitry Andric
24212754fe60SDimitry Andric // Arithmetic on function pointers (!) is just +-1.
24222754fe60SDimitry Andric } else if (type->isFunctionType()) {
24233b0f4066SDimitry Andric llvm::Value *amt = Builder.getInt32(amount);
24242754fe60SDimitry Andric
24252754fe60SDimitry Andric value = CGF.EmitCastToVoidPtr(value);
24263861d79fSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
24273b0f4066SDimitry Andric value = Builder.CreateGEP(value, amt, "incdec.funcptr");
24283b0f4066SDimitry Andric else
2429b40b48b8SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false,
2430b40b48b8SDimitry Andric isSubtraction, E->getExprLoc(),
2431b40b48b8SDimitry Andric "incdec.funcptr");
24322754fe60SDimitry Andric value = Builder.CreateBitCast(value, input->getType());
24332754fe60SDimitry Andric
24342754fe60SDimitry Andric // For everything else, we can just do a simple increment.
2435ffd1746dSEd Schouten } else {
24363b0f4066SDimitry Andric llvm::Value *amt = Builder.getInt32(amount);
24373861d79fSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
24383b0f4066SDimitry Andric value = Builder.CreateGEP(value, amt, "incdec.ptr");
24393b0f4066SDimitry Andric else
2440b40b48b8SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false,
2441b40b48b8SDimitry Andric isSubtraction, E->getExprLoc(),
2442b40b48b8SDimitry Andric "incdec.ptr");
24432754fe60SDimitry Andric }
24442754fe60SDimitry Andric
24452754fe60SDimitry Andric // Vector increment/decrement.
24462754fe60SDimitry Andric } else if (type->isVectorType()) {
24472754fe60SDimitry Andric if (type->hasIntegerRepresentation()) {
24482754fe60SDimitry Andric llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
24492754fe60SDimitry Andric
24502754fe60SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
24512754fe60SDimitry Andric } else {
24522754fe60SDimitry Andric value = Builder.CreateFAdd(
24532754fe60SDimitry Andric value,
24542754fe60SDimitry Andric llvm::ConstantFP::get(value->getType(), amount),
24552754fe60SDimitry Andric isInc ? "inc" : "dec");
24562754fe60SDimitry Andric }
24572754fe60SDimitry Andric
24582754fe60SDimitry Andric // Floating point.
24592754fe60SDimitry Andric } else if (type->isRealFloatingType()) {
2460ffd1746dSEd Schouten // Add the inc/dec to the real part.
24612754fe60SDimitry Andric llvm::Value *amt;
24626122f3e6SDimitry Andric
246333956c43SDimitry Andric if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
24646122f3e6SDimitry Andric // Another special case: half FP increment should be done via float
24659a199699SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
246659d1ed5bSDimitry Andric value = Builder.CreateCall(
246759d1ed5bSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
246859d1ed5bSDimitry Andric CGF.CGM.FloatTy),
246933956c43SDimitry Andric input, "incdec.conv");
247033956c43SDimitry Andric } else {
247133956c43SDimitry Andric value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv");
247233956c43SDimitry Andric }
24736122f3e6SDimitry Andric }
24746122f3e6SDimitry Andric
24752754fe60SDimitry Andric if (value->getType()->isFloatTy())
24762754fe60SDimitry Andric amt = llvm::ConstantFP::get(VMContext,
24772754fe60SDimitry Andric llvm::APFloat(static_cast<float>(amount)));
24782754fe60SDimitry Andric else if (value->getType()->isDoubleTy())
24792754fe60SDimitry Andric amt = llvm::ConstantFP::get(VMContext,
24802754fe60SDimitry Andric llvm::APFloat(static_cast<double>(amount)));
2481ffd1746dSEd Schouten else {
2482e7145dcbSDimitry Andric // Remaining types are Half, LongDouble or __float128. Convert from float.
24832754fe60SDimitry Andric llvm::APFloat F(static_cast<float>(amount));
2484ffd1746dSEd Schouten bool ignored;
2485e7145dcbSDimitry Andric const llvm::fltSemantics *FS;
248633956c43SDimitry Andric // Don't use getFloatTypeSemantics because Half isn't
248733956c43SDimitry Andric // necessarily represented using the "half" LLVM type.
2488e7145dcbSDimitry Andric if (value->getType()->isFP128Ty())
2489e7145dcbSDimitry Andric FS = &CGF.getTarget().getFloat128Format();
2490e7145dcbSDimitry Andric else if (value->getType()->isHalfTy())
2491e7145dcbSDimitry Andric FS = &CGF.getTarget().getHalfFormat();
2492e7145dcbSDimitry Andric else
2493e7145dcbSDimitry Andric FS = &CGF.getTarget().getLongDoubleFormat();
2494e7145dcbSDimitry Andric F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
24952754fe60SDimitry Andric amt = llvm::ConstantFP::get(VMContext, F);
2496ffd1746dSEd Schouten }
24972754fe60SDimitry Andric value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
24982754fe60SDimitry Andric
249933956c43SDimitry Andric if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
25009a199699SDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
250159d1ed5bSDimitry Andric value = Builder.CreateCall(
250259d1ed5bSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,
250359d1ed5bSDimitry Andric CGF.CGM.FloatTy),
250433956c43SDimitry Andric value, "incdec.conv");
250533956c43SDimitry Andric } else {
250633956c43SDimitry Andric value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv");
250733956c43SDimitry Andric }
250833956c43SDimitry Andric }
25096122f3e6SDimitry Andric
25102754fe60SDimitry Andric // Objective-C pointer types.
25112754fe60SDimitry Andric } else {
25122754fe60SDimitry Andric const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>();
25132754fe60SDimitry Andric value = CGF.EmitCastToVoidPtr(value);
25142754fe60SDimitry Andric
25152754fe60SDimitry Andric CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType());
25162754fe60SDimitry Andric if (!isInc) size = -size;
25172754fe60SDimitry Andric llvm::Value *sizeValue =
25182754fe60SDimitry Andric llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
25192754fe60SDimitry Andric
25203861d79fSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
25213b0f4066SDimitry Andric value = Builder.CreateGEP(value, sizeValue, "incdec.objptr");
25223b0f4066SDimitry Andric else
2523b40b48b8SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(value, sizeValue,
2524b40b48b8SDimitry Andric /*SignedIndices=*/false, isSubtraction,
252524d58133SDimitry Andric E->getExprLoc(), "incdec.objptr");
25262754fe60SDimitry Andric value = Builder.CreateBitCast(value, input->getType());
2527ffd1746dSEd Schouten }
2528ffd1746dSEd Schouten
2529dff0c46cSDimitry Andric if (atomicPHI) {
2530dff0c46cSDimitry Andric llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2531dff0c46cSDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
253239d628a0SDimitry Andric auto Pair = CGF.EmitAtomicCompareExchange(
253333956c43SDimitry Andric LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
253433956c43SDimitry Andric llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
253533956c43SDimitry Andric llvm::Value *success = Pair.second;
2536dff0c46cSDimitry Andric atomicPHI->addIncoming(old, opBB);
2537dff0c46cSDimitry Andric Builder.CreateCondBr(success, contBB, opBB);
2538dff0c46cSDimitry Andric Builder.SetInsertPoint(contBB);
2539dff0c46cSDimitry Andric return isPre ? value : input;
2540dff0c46cSDimitry Andric }
2541dff0c46cSDimitry Andric
2542ffd1746dSEd Schouten // Store the updated result through the lvalue.
2543ffd1746dSEd Schouten if (LV.isBitField())
254417a519f9SDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
2545ffd1746dSEd Schouten else
254617a519f9SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(value), LV);
2547ffd1746dSEd Schouten
2548ffd1746dSEd Schouten // If this is a postinc, return the value read from memory, otherwise use the
2549ffd1746dSEd Schouten // updated value.
25502754fe60SDimitry Andric return isPre ? value : input;
2551ffd1746dSEd Schouten }
2552ffd1746dSEd Schouten
2553ffd1746dSEd Schouten
2554ffd1746dSEd Schouten
VisitUnaryMinus(const UnaryOperator * E)2555f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
2556f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
2557ffd1746dSEd Schouten // Emit unary minus with EmitSub so we handle overflow cases etc.
2558ffd1746dSEd Schouten BinOpInfo BinOp;
2559ffd1746dSEd Schouten BinOp.RHS = Visit(E->getSubExpr());
2560ffd1746dSEd Schouten
2561ffd1746dSEd Schouten if (BinOp.RHS->getType()->isFPOrFPVectorTy())
2562ffd1746dSEd Schouten BinOp.LHS = llvm::ConstantFP::getZeroValueForNegation(BinOp.RHS->getType());
2563ffd1746dSEd Schouten else
2564ffd1746dSEd Schouten BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
2565ffd1746dSEd Schouten BinOp.Ty = E->getType();
2566e580952dSDimitry Andric BinOp.Opcode = BO_Sub;
256720e90f04SDimitry Andric // FIXME: once UnaryOperator carries FPFeatures, copy it here.
2568ffd1746dSEd Schouten BinOp.E = E;
2569ffd1746dSEd Schouten return EmitSub(BinOp);
2570f22ef01cSRoman Divacky }
2571f22ef01cSRoman Divacky
VisitUnaryNot(const UnaryOperator * E)2572f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
2573f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
2574f22ef01cSRoman Divacky Value *Op = Visit(E->getSubExpr());
2575f22ef01cSRoman Divacky return Builder.CreateNot(Op, "neg");
2576f22ef01cSRoman Divacky }
2577f22ef01cSRoman Divacky
VisitUnaryLNot(const UnaryOperator * E)2578f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
2579dff0c46cSDimitry Andric // Perform vector logical not on comparison with zero vector.
2580dff0c46cSDimitry Andric if (E->getType()->isExtVectorType()) {
2581dff0c46cSDimitry Andric Value *Oper = Visit(E->getSubExpr());
2582dff0c46cSDimitry Andric Value *Zero = llvm::Constant::getNullValue(Oper->getType());
2583139f7f9bSDimitry Andric Value *Result;
2584139f7f9bSDimitry Andric if (Oper->getType()->isFPOrFPVectorTy())
2585139f7f9bSDimitry Andric Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
2586139f7f9bSDimitry Andric else
2587139f7f9bSDimitry Andric Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
2588dff0c46cSDimitry Andric return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
2589dff0c46cSDimitry Andric }
2590dff0c46cSDimitry Andric
2591f22ef01cSRoman Divacky // Compare operand to zero.
2592f22ef01cSRoman Divacky Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
2593f22ef01cSRoman Divacky
2594f22ef01cSRoman Divacky // Invert value.
2595f22ef01cSRoman Divacky // TODO: Could dynamically modify easy computations here. For example, if
2596f22ef01cSRoman Divacky // the operand is an icmp ne, turn into icmp eq.
2597f22ef01cSRoman Divacky BoolVal = Builder.CreateNot(BoolVal, "lnot");
2598f22ef01cSRoman Divacky
2599f22ef01cSRoman Divacky // ZExt result to the expr type.
2600f22ef01cSRoman Divacky return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
2601f22ef01cSRoman Divacky }
2602f22ef01cSRoman Divacky
VisitOffsetOfExpr(OffsetOfExpr * E)2603e580952dSDimitry Andric Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
2604e580952dSDimitry Andric // Try folding the offsetof to a constant.
2605*b5893f02SDimitry Andric Expr::EvalResult EVResult;
2606*b5893f02SDimitry Andric if (E->EvaluateAsInt(EVResult, CGF.getContext())) {
2607*b5893f02SDimitry Andric llvm::APSInt Value = EVResult.Val.getInt();
2608dff0c46cSDimitry Andric return Builder.getInt(Value);
2609*b5893f02SDimitry Andric }
2610f22ef01cSRoman Divacky
2611e580952dSDimitry Andric // Loop over the components of the offsetof to compute the value.
2612e580952dSDimitry Andric unsigned n = E->getNumComponents();
26136122f3e6SDimitry Andric llvm::Type* ResultType = ConvertType(E->getType());
2614e580952dSDimitry Andric llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
2615e580952dSDimitry Andric QualType CurrentType = E->getTypeSourceInfo()->getType();
2616e580952dSDimitry Andric for (unsigned i = 0; i != n; ++i) {
26170623d748SDimitry Andric OffsetOfNode ON = E->getComponent(i);
261859d1ed5bSDimitry Andric llvm::Value *Offset = nullptr;
2619e580952dSDimitry Andric switch (ON.getKind()) {
26200623d748SDimitry Andric case OffsetOfNode::Array: {
2621e580952dSDimitry Andric // Compute the index
2622e580952dSDimitry Andric Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
2623e580952dSDimitry Andric llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
2624bd5abe19SDimitry Andric bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType();
2625e580952dSDimitry Andric Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv");
2626f22ef01cSRoman Divacky
2627e580952dSDimitry Andric // Save the element type
2628e580952dSDimitry Andric CurrentType =
2629e580952dSDimitry Andric CGF.getContext().getAsArrayType(CurrentType)->getElementType();
2630e580952dSDimitry Andric
2631e580952dSDimitry Andric // Compute the element size
2632e580952dSDimitry Andric llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
2633e580952dSDimitry Andric CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity());
2634e580952dSDimitry Andric
2635e580952dSDimitry Andric // Multiply out to compute the result
2636e580952dSDimitry Andric Offset = Builder.CreateMul(Idx, ElemSize);
2637e580952dSDimitry Andric break;
2638e580952dSDimitry Andric }
2639e580952dSDimitry Andric
26400623d748SDimitry Andric case OffsetOfNode::Field: {
2641e580952dSDimitry Andric FieldDecl *MemberDecl = ON.getField();
2642e580952dSDimitry Andric RecordDecl *RD = CurrentType->getAs<RecordType>()->getDecl();
2643e580952dSDimitry Andric const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
2644e580952dSDimitry Andric
2645e580952dSDimitry Andric // Compute the index of the field in its parent.
2646e580952dSDimitry Andric unsigned i = 0;
2647e580952dSDimitry Andric // FIXME: It would be nice if we didn't have to loop here!
2648e580952dSDimitry Andric for (RecordDecl::field_iterator Field = RD->field_begin(),
2649e580952dSDimitry Andric FieldEnd = RD->field_end();
26507ae0e2c9SDimitry Andric Field != FieldEnd; ++Field, ++i) {
2651e580952dSDimitry Andric if (*Field == MemberDecl)
2652e580952dSDimitry Andric break;
2653e580952dSDimitry Andric }
2654e580952dSDimitry Andric assert(i < RL.getFieldCount() && "offsetof field in wrong type");
2655e580952dSDimitry Andric
2656e580952dSDimitry Andric // Compute the offset to the field
2657e580952dSDimitry Andric int64_t OffsetInt = RL.getFieldOffset(i) /
2658e580952dSDimitry Andric CGF.getContext().getCharWidth();
2659e580952dSDimitry Andric Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
2660e580952dSDimitry Andric
2661e580952dSDimitry Andric // Save the element type.
2662e580952dSDimitry Andric CurrentType = MemberDecl->getType();
2663e580952dSDimitry Andric break;
2664e580952dSDimitry Andric }
2665e580952dSDimitry Andric
26660623d748SDimitry Andric case OffsetOfNode::Identifier:
2667e580952dSDimitry Andric llvm_unreachable("dependent __builtin_offsetof");
2668e580952dSDimitry Andric
26690623d748SDimitry Andric case OffsetOfNode::Base: {
2670e580952dSDimitry Andric if (ON.getBase()->isVirtual()) {
2671e580952dSDimitry Andric CGF.ErrorUnsupported(E, "virtual base in offsetof");
2672e580952dSDimitry Andric continue;
2673e580952dSDimitry Andric }
2674e580952dSDimitry Andric
2675e580952dSDimitry Andric RecordDecl *RD = CurrentType->getAs<RecordType>()->getDecl();
2676e580952dSDimitry Andric const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
2677e580952dSDimitry Andric
2678e580952dSDimitry Andric // Save the element type.
2679e580952dSDimitry Andric CurrentType = ON.getBase()->getType();
2680e580952dSDimitry Andric
2681e580952dSDimitry Andric // Compute the offset to the base.
2682e580952dSDimitry Andric const RecordType *BaseRT = CurrentType->getAs<RecordType>();
2683e580952dSDimitry Andric CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
26847ae0e2c9SDimitry Andric CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD);
26857ae0e2c9SDimitry Andric Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
2686e580952dSDimitry Andric break;
2687e580952dSDimitry Andric }
2688e580952dSDimitry Andric }
2689e580952dSDimitry Andric Result = Builder.CreateAdd(Result, Offset);
2690e580952dSDimitry Andric }
2691e580952dSDimitry Andric return Result;
2692f22ef01cSRoman Divacky }
2693f22ef01cSRoman Divacky
26943b0f4066SDimitry Andric /// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of
2695f22ef01cSRoman Divacky /// argument of the sizeof expression as an integer.
2696f22ef01cSRoman Divacky Value *
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)26973b0f4066SDimitry Andric ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
26983b0f4066SDimitry Andric const UnaryExprOrTypeTraitExpr *E) {
2699f22ef01cSRoman Divacky QualType TypeToSize = E->getTypeOfArgument();
27003b0f4066SDimitry Andric if (E->getKind() == UETT_SizeOf) {
2701f22ef01cSRoman Divacky if (const VariableArrayType *VAT =
2702f22ef01cSRoman Divacky CGF.getContext().getAsVariableArrayType(TypeToSize)) {
2703f22ef01cSRoman Divacky if (E->isArgumentType()) {
2704f22ef01cSRoman Divacky // sizeof(type) - make sure to emit the VLA size.
270517a519f9SDimitry Andric CGF.EmitVariablyModifiedType(TypeToSize);
2706f22ef01cSRoman Divacky } else {
2707f22ef01cSRoman Divacky // C99 6.5.3.4p2: If the argument is an expression of type
2708f22ef01cSRoman Divacky // VLA, it is evaluated.
27092754fe60SDimitry Andric CGF.EmitIgnoredExpr(E->getArgumentExpr());
2710f22ef01cSRoman Divacky }
2711f22ef01cSRoman Divacky
27124ba319b5SDimitry Andric auto VlaSize = CGF.getVLASize(VAT);
27134ba319b5SDimitry Andric llvm::Value *size = VlaSize.NumElts;
271417a519f9SDimitry Andric
271517a519f9SDimitry Andric // Scale the number of non-VLA elements by the non-VLA element size.
27164ba319b5SDimitry Andric CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type);
271717a519f9SDimitry Andric if (!eltSize.isOne())
27184ba319b5SDimitry Andric size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size);
271917a519f9SDimitry Andric
272017a519f9SDimitry Andric return size;
2721f22ef01cSRoman Divacky }
27223dac3a9bSDimitry Andric } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) {
27233dac3a9bSDimitry Andric auto Alignment =
27243dac3a9bSDimitry Andric CGF.getContext()
27253dac3a9bSDimitry Andric .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
27263dac3a9bSDimitry Andric E->getTypeOfArgument()->getPointeeType()))
27273dac3a9bSDimitry Andric .getQuantity();
27283dac3a9bSDimitry Andric return llvm::ConstantInt::get(CGF.SizeTy, Alignment);
2729f22ef01cSRoman Divacky }
2730f22ef01cSRoman Divacky
2731f22ef01cSRoman Divacky // If this isn't sizeof(vla), the result must be constant; use the constant
2732f22ef01cSRoman Divacky // folding logic so we don't have to duplicate it here.
2733dff0c46cSDimitry Andric return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext()));
2734f22ef01cSRoman Divacky }
2735f22ef01cSRoman Divacky
VisitUnaryReal(const UnaryOperator * E)2736f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
2737f22ef01cSRoman Divacky Expr *Op = E->getSubExpr();
27382754fe60SDimitry Andric if (Op->getType()->isAnyComplexType()) {
27392754fe60SDimitry Andric // If it's an l-value, load through the appropriate subobject l-value.
27402754fe60SDimitry Andric // Note that we have to ask E because Op might be an l-value that
27412754fe60SDimitry Andric // this won't work for, e.g. an Obj-C property.
27422754fe60SDimitry Andric if (E->isGLValue())
2743f785676fSDimitry Andric return CGF.EmitLoadOfLValue(CGF.EmitLValue(E),
2744f785676fSDimitry Andric E->getExprLoc()).getScalarVal();
27452754fe60SDimitry Andric
27462754fe60SDimitry Andric // Otherwise, calculate and project.
27472754fe60SDimitry Andric return CGF.EmitComplexExpr(Op, false, true).first;
27482754fe60SDimitry Andric }
27492754fe60SDimitry Andric
2750f22ef01cSRoman Divacky return Visit(Op);
2751f22ef01cSRoman Divacky }
27522754fe60SDimitry Andric
VisitUnaryImag(const UnaryOperator * E)2753f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
2754f22ef01cSRoman Divacky Expr *Op = E->getSubExpr();
27552754fe60SDimitry Andric if (Op->getType()->isAnyComplexType()) {
27562754fe60SDimitry Andric // If it's an l-value, load through the appropriate subobject l-value.
27572754fe60SDimitry Andric // Note that we have to ask E because Op might be an l-value that
27582754fe60SDimitry Andric // this won't work for, e.g. an Obj-C property.
27592754fe60SDimitry Andric if (Op->isGLValue())
2760f785676fSDimitry Andric return CGF.EmitLoadOfLValue(CGF.EmitLValue(E),
2761f785676fSDimitry Andric E->getExprLoc()).getScalarVal();
27622754fe60SDimitry Andric
27632754fe60SDimitry Andric // Otherwise, calculate and project.
27642754fe60SDimitry Andric return CGF.EmitComplexExpr(Op, true, false).second;
27652754fe60SDimitry Andric }
2766f22ef01cSRoman Divacky
2767f22ef01cSRoman Divacky // __imag on a scalar returns zero. Emit the subexpr to ensure side
2768f22ef01cSRoman Divacky // effects are evaluated, but not the actual value.
2769dff0c46cSDimitry Andric if (Op->isGLValue())
2770dff0c46cSDimitry Andric CGF.EmitLValue(Op);
2771dff0c46cSDimitry Andric else
2772f22ef01cSRoman Divacky CGF.EmitScalarExpr(Op, true);
2773f22ef01cSRoman Divacky return llvm::Constant::getNullValue(ConvertType(E->getType()));
2774f22ef01cSRoman Divacky }
2775f22ef01cSRoman Divacky
2776f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
2777f22ef01cSRoman Divacky // Binary Operators
2778f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
2779f22ef01cSRoman Divacky
EmitBinOps(const BinaryOperator * E)2780f22ef01cSRoman Divacky BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
2781f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
2782f22ef01cSRoman Divacky BinOpInfo Result;
2783f22ef01cSRoman Divacky Result.LHS = Visit(E->getLHS());
2784f22ef01cSRoman Divacky Result.RHS = Visit(E->getRHS());
2785f22ef01cSRoman Divacky Result.Ty = E->getType();
2786ffd1746dSEd Schouten Result.Opcode = E->getOpcode();
278720e90f04SDimitry Andric Result.FPFeatures = E->getFPFeatures();
2788f22ef01cSRoman Divacky Result.E = E;
2789f22ef01cSRoman Divacky return Result;
2790f22ef01cSRoman Divacky }
2791f22ef01cSRoman Divacky
EmitCompoundAssignLValue(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &),Value * & Result)2792f22ef01cSRoman Divacky LValue ScalarExprEmitter::EmitCompoundAssignLValue(
2793f22ef01cSRoman Divacky const CompoundAssignOperator *E,
2794f22ef01cSRoman Divacky Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
2795ffd1746dSEd Schouten Value *&Result) {
2796f22ef01cSRoman Divacky QualType LHSTy = E->getLHS()->getType();
2797f22ef01cSRoman Divacky BinOpInfo OpInfo;
2798f22ef01cSRoman Divacky
2799f785676fSDimitry Andric if (E->getComputationResultType()->isAnyComplexType())
280033956c43SDimitry Andric return CGF.EmitScalarCompoundAssignWithComplex(E, Result);
2801f22ef01cSRoman Divacky
2802f22ef01cSRoman Divacky // Emit the RHS first. __block variables need to have the rhs evaluated
2803f22ef01cSRoman Divacky // first, plus this should improve codegen a little.
2804f22ef01cSRoman Divacky OpInfo.RHS = Visit(E->getRHS());
2805f22ef01cSRoman Divacky OpInfo.Ty = E->getComputationResultType();
2806ffd1746dSEd Schouten OpInfo.Opcode = E->getOpcode();
280720e90f04SDimitry Andric OpInfo.FPFeatures = E->getFPFeatures();
2808f22ef01cSRoman Divacky OpInfo.E = E;
2809f22ef01cSRoman Divacky // Load/convert the LHS.
28103861d79fSDimitry Andric LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
2811f22ef01cSRoman Divacky
281259d1ed5bSDimitry Andric llvm::PHINode *atomicPHI = nullptr;
2813139f7f9bSDimitry Andric if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
2814139f7f9bSDimitry Andric QualType type = atomicTy->getValueType();
2815139f7f9bSDimitry Andric if (!type->isBooleanType() && type->isIntegerType() &&
2816139f7f9bSDimitry Andric !(type->isUnsignedIntegerType() &&
281739d628a0SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
2818139f7f9bSDimitry Andric CGF.getLangOpts().getSignedOverflowBehavior() !=
2819139f7f9bSDimitry Andric LangOptions::SOB_Trapping) {
2820139f7f9bSDimitry Andric llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP;
2821139f7f9bSDimitry Andric switch (OpInfo.Opcode) {
2822139f7f9bSDimitry Andric // We don't have atomicrmw operands for *, %, /, <<, >>
2823139f7f9bSDimitry Andric case BO_MulAssign: case BO_DivAssign:
2824139f7f9bSDimitry Andric case BO_RemAssign:
2825139f7f9bSDimitry Andric case BO_ShlAssign:
2826139f7f9bSDimitry Andric case BO_ShrAssign:
2827139f7f9bSDimitry Andric break;
2828139f7f9bSDimitry Andric case BO_AddAssign:
2829139f7f9bSDimitry Andric aop = llvm::AtomicRMWInst::Add;
2830139f7f9bSDimitry Andric break;
2831139f7f9bSDimitry Andric case BO_SubAssign:
2832139f7f9bSDimitry Andric aop = llvm::AtomicRMWInst::Sub;
2833139f7f9bSDimitry Andric break;
2834139f7f9bSDimitry Andric case BO_AndAssign:
2835139f7f9bSDimitry Andric aop = llvm::AtomicRMWInst::And;
2836139f7f9bSDimitry Andric break;
2837139f7f9bSDimitry Andric case BO_XorAssign:
2838139f7f9bSDimitry Andric aop = llvm::AtomicRMWInst::Xor;
2839139f7f9bSDimitry Andric break;
2840139f7f9bSDimitry Andric case BO_OrAssign:
2841139f7f9bSDimitry Andric aop = llvm::AtomicRMWInst::Or;
2842139f7f9bSDimitry Andric break;
2843139f7f9bSDimitry Andric default:
2844139f7f9bSDimitry Andric llvm_unreachable("Invalid compound assignment type");
2845139f7f9bSDimitry Andric }
2846139f7f9bSDimitry Andric if (aop != llvm::AtomicRMWInst::BAD_BINOP) {
28470623d748SDimitry Andric llvm::Value *amt = CGF.EmitToMemory(
28480623d748SDimitry Andric EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
28490623d748SDimitry Andric E->getExprLoc()),
28500623d748SDimitry Andric LHSTy);
28510623d748SDimitry Andric Builder.CreateAtomicRMW(aop, LHSLV.getPointer(), amt,
2852e7145dcbSDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
2853139f7f9bSDimitry Andric return LHSLV;
2854139f7f9bSDimitry Andric }
2855139f7f9bSDimitry Andric }
2856dff0c46cSDimitry Andric // FIXME: For floating point types, we should be saving and restoring the
2857dff0c46cSDimitry Andric // floating point environment in the loop.
2858dff0c46cSDimitry Andric llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2859dff0c46cSDimitry Andric llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
2860f785676fSDimitry Andric OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
2861139f7f9bSDimitry Andric OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type);
2862dff0c46cSDimitry Andric Builder.CreateBr(opBB);
2863dff0c46cSDimitry Andric Builder.SetInsertPoint(opBB);
2864dff0c46cSDimitry Andric atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
2865dff0c46cSDimitry Andric atomicPHI->addIncoming(OpInfo.LHS, startBB);
2866dff0c46cSDimitry Andric OpInfo.LHS = atomicPHI;
2867dff0c46cSDimitry Andric }
2868139f7f9bSDimitry Andric else
2869f785676fSDimitry Andric OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
2870dff0c46cSDimitry Andric
28710623d748SDimitry Andric SourceLocation Loc = E->getExprLoc();
28720623d748SDimitry Andric OpInfo.LHS =
28730623d748SDimitry Andric EmitScalarConversion(OpInfo.LHS, LHSTy, E->getComputationLHSType(), Loc);
28747ae0e2c9SDimitry Andric
2875f22ef01cSRoman Divacky // Expand the binary operator.
2876ffd1746dSEd Schouten Result = (this->*Func)(OpInfo);
2877f22ef01cSRoman Divacky
2878*b5893f02SDimitry Andric // Convert the result back to the LHS type,
2879*b5893f02SDimitry Andric // potentially with Implicit Conversion sanitizer check.
2880*b5893f02SDimitry Andric Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy,
2881*b5893f02SDimitry Andric Loc, ScalarConversionOpts(CGF.SanOpts));
2882f22ef01cSRoman Divacky
2883dff0c46cSDimitry Andric if (atomicPHI) {
2884dff0c46cSDimitry Andric llvm::BasicBlock *opBB = Builder.GetInsertBlock();
2885dff0c46cSDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
288639d628a0SDimitry Andric auto Pair = CGF.EmitAtomicCompareExchange(
288733956c43SDimitry Andric LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc());
288833956c43SDimitry Andric llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy);
288933956c43SDimitry Andric llvm::Value *success = Pair.second;
2890dff0c46cSDimitry Andric atomicPHI->addIncoming(old, opBB);
2891dff0c46cSDimitry Andric Builder.CreateCondBr(success, contBB, opBB);
2892dff0c46cSDimitry Andric Builder.SetInsertPoint(contBB);
2893dff0c46cSDimitry Andric return LHSLV;
2894dff0c46cSDimitry Andric }
2895dff0c46cSDimitry Andric
2896f22ef01cSRoman Divacky // Store the result value into the LHS lvalue. Bit-fields are handled
2897f22ef01cSRoman Divacky // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
2898f22ef01cSRoman Divacky // 'An assignment expression has the value of the left operand after the
2899f22ef01cSRoman Divacky // assignment...'.
2900ffd1746dSEd Schouten if (LHSLV.isBitField())
290117a519f9SDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
2902ffd1746dSEd Schouten else
290317a519f9SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
2904ffd1746dSEd Schouten
2905f22ef01cSRoman Divacky return LHSLV;
2906f22ef01cSRoman Divacky }
2907f22ef01cSRoman Divacky
EmitCompoundAssign(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &))2908f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
2909f22ef01cSRoman Divacky Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
2910f22ef01cSRoman Divacky bool Ignore = TestAndClearIgnoreResultAssign();
2911ffd1746dSEd Schouten Value *RHS;
2912ffd1746dSEd Schouten LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
2913f22ef01cSRoman Divacky
2914ffd1746dSEd Schouten // If the result is clearly ignored, return now.
2915f22ef01cSRoman Divacky if (Ignore)
291659d1ed5bSDimitry Andric return nullptr;
2917ffd1746dSEd Schouten
29182754fe60SDimitry Andric // The result of an assignment in C is the assigned r-value.
29193861d79fSDimitry Andric if (!CGF.getLangOpts().CPlusPlus)
2920ffd1746dSEd Schouten return RHS;
2921ffd1746dSEd Schouten
2922ffd1746dSEd Schouten // If the lvalue is non-volatile, return the computed value of the assignment.
2923ffd1746dSEd Schouten if (!LHS.isVolatileQualified())
2924ffd1746dSEd Schouten return RHS;
2925ffd1746dSEd Schouten
2926ffd1746dSEd Schouten // Otherwise, reload the value.
2927f785676fSDimitry Andric return EmitLoadOfLValue(LHS, E->getExprLoc());
2928f22ef01cSRoman Divacky }
2929f22ef01cSRoman Divacky
EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo & Ops,llvm::Value * Zero,bool isDiv)29302754fe60SDimitry Andric void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
29313861d79fSDimitry Andric const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
293233956c43SDimitry Andric SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
29332754fe60SDimitry Andric
293439d628a0SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
293539d628a0SDimitry Andric Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
293639d628a0SDimitry Andric SanitizerKind::IntegerDivideByZero));
293739d628a0SDimitry Andric }
29383861d79fSDimitry Andric
293920e90f04SDimitry Andric const auto *BO = cast<BinaryOperator>(Ops.E);
294039d628a0SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
294120e90f04SDimitry Andric Ops.Ty->hasSignedIntegerRepresentation() &&
2942f37b6182SDimitry Andric !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) &&
2943f37b6182SDimitry Andric Ops.mayHaveIntegerOverflow()) {
29446122f3e6SDimitry Andric llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
29452754fe60SDimitry Andric
29462754fe60SDimitry Andric llvm::Value *IntMin =
29473b0f4066SDimitry Andric Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
29482754fe60SDimitry Andric llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
29492754fe60SDimitry Andric
29503861d79fSDimitry Andric llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
29513861d79fSDimitry Andric llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
295239d628a0SDimitry Andric llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
295339d628a0SDimitry Andric Checks.push_back(
295439d628a0SDimitry Andric std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
29552754fe60SDimitry Andric }
29563861d79fSDimitry Andric
295739d628a0SDimitry Andric if (Checks.size() > 0)
295839d628a0SDimitry Andric EmitBinOpCheck(Checks, Ops);
29592754fe60SDimitry Andric }
2960f22ef01cSRoman Divacky
EmitDiv(const BinOpInfo & Ops)2961f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
296259d1ed5bSDimitry Andric {
296359d1ed5bSDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
296439d628a0SDimitry Andric if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
296539d628a0SDimitry Andric CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
2966f37b6182SDimitry Andric Ops.Ty->isIntegerType() &&
2967f37b6182SDimitry Andric (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
29682754fe60SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
29692754fe60SDimitry Andric EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
297039d628a0SDimitry Andric } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
2971f37b6182SDimitry Andric Ops.Ty->isRealFloatingType() &&
2972f37b6182SDimitry Andric Ops.mayHaveFloatDivisionByZero()) {
2973139f7f9bSDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
297439d628a0SDimitry Andric llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
297539d628a0SDimitry Andric EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
297639d628a0SDimitry Andric Ops);
29772754fe60SDimitry Andric }
297859d1ed5bSDimitry Andric }
2979139f7f9bSDimitry Andric
2980dff0c46cSDimitry Andric if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
2981dff0c46cSDimitry Andric llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
298244290647SDimitry Andric if (CGF.getLangOpts().OpenCL &&
298344290647SDimitry Andric !CGF.CGM.getCodeGenOpts().CorrectlyRoundedDivSqrt) {
298444290647SDimitry Andric // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 2.5ulp
298544290647SDimitry Andric // OpenCL v1.2 s5.6.4.2: The -cl-fp32-correctly-rounded-divide-sqrt
298644290647SDimitry Andric // build option allows an application to specify that single precision
298744290647SDimitry Andric // floating-point divide (x/y and 1/x) and sqrt used in the program
298844290647SDimitry Andric // source are correctly rounded.
2989dff0c46cSDimitry Andric llvm::Type *ValTy = Val->getType();
2990dff0c46cSDimitry Andric if (ValTy->isFloatTy() ||
2991dff0c46cSDimitry Andric (isa<llvm::VectorType>(ValTy) &&
2992dff0c46cSDimitry Andric cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy()))
2993dff0c46cSDimitry Andric CGF.SetFPAccuracy(Val, 2.5);
2994dff0c46cSDimitry Andric }
2995dff0c46cSDimitry Andric return Val;
2996dff0c46cSDimitry Andric }
2997e580952dSDimitry Andric else if (Ops.Ty->hasUnsignedIntegerRepresentation())
2998f22ef01cSRoman Divacky return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
2999f22ef01cSRoman Divacky else
3000f22ef01cSRoman Divacky return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
3001f22ef01cSRoman Divacky }
3002f22ef01cSRoman Divacky
EmitRem(const BinOpInfo & Ops)3003f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
3004f22ef01cSRoman Divacky // Rem in C can't be a floating point type: C99 6.5.5p2.
300520e90f04SDimitry Andric if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
300620e90f04SDimitry Andric CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
3007f37b6182SDimitry Andric Ops.Ty->isIntegerType() &&
3008f37b6182SDimitry Andric (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
300959d1ed5bSDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
30102754fe60SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
30112754fe60SDimitry Andric EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
30122754fe60SDimitry Andric }
30132754fe60SDimitry Andric
30143b0f4066SDimitry Andric if (Ops.Ty->hasUnsignedIntegerRepresentation())
3015f22ef01cSRoman Divacky return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
3016f22ef01cSRoman Divacky else
3017f22ef01cSRoman Divacky return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
3018f22ef01cSRoman Divacky }
3019f22ef01cSRoman Divacky
EmitOverflowCheckedBinOp(const BinOpInfo & Ops)3020f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
3021f22ef01cSRoman Divacky unsigned IID;
3022f22ef01cSRoman Divacky unsigned OpID = 0;
3023f22ef01cSRoman Divacky
3024139f7f9bSDimitry Andric bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
3025ffd1746dSEd Schouten switch (Ops.Opcode) {
3026e580952dSDimitry Andric case BO_Add:
3027e580952dSDimitry Andric case BO_AddAssign:
3028f22ef01cSRoman Divacky OpID = 1;
3029139f7f9bSDimitry Andric IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3030139f7f9bSDimitry Andric llvm::Intrinsic::uadd_with_overflow;
3031f22ef01cSRoman Divacky break;
3032e580952dSDimitry Andric case BO_Sub:
3033e580952dSDimitry Andric case BO_SubAssign:
3034f22ef01cSRoman Divacky OpID = 2;
3035139f7f9bSDimitry Andric IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3036139f7f9bSDimitry Andric llvm::Intrinsic::usub_with_overflow;
3037f22ef01cSRoman Divacky break;
3038e580952dSDimitry Andric case BO_Mul:
3039e580952dSDimitry Andric case BO_MulAssign:
3040f22ef01cSRoman Divacky OpID = 3;
3041139f7f9bSDimitry Andric IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3042139f7f9bSDimitry Andric llvm::Intrinsic::umul_with_overflow;
3043f22ef01cSRoman Divacky break;
3044f22ef01cSRoman Divacky default:
30456122f3e6SDimitry Andric llvm_unreachable("Unsupported operation for overflow detection");
3046f22ef01cSRoman Divacky }
3047f22ef01cSRoman Divacky OpID <<= 1;
3048139f7f9bSDimitry Andric if (isSigned)
3049f22ef01cSRoman Divacky OpID |= 1;
3050f22ef01cSRoman Divacky
30515517e702SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
305217a519f9SDimitry Andric llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
3053f22ef01cSRoman Divacky
305417a519f9SDimitry Andric llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
3055f22ef01cSRoman Divacky
305633956c43SDimitry Andric Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3057f22ef01cSRoman Divacky Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3058f22ef01cSRoman Divacky Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3059f22ef01cSRoman Divacky
30603861d79fSDimitry Andric // Handle overflow with llvm.trap if no custom handler has been specified.
30613861d79fSDimitry Andric const std::string *handlerName =
30623861d79fSDimitry Andric &CGF.getLangOpts().OverflowHandler;
30633861d79fSDimitry Andric if (handlerName->empty()) {
30643861d79fSDimitry Andric // If the signed-integer-overflow sanitizer is enabled, emit a call to its
30653861d79fSDimitry Andric // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
306639d628a0SDimitry Andric if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
306739d628a0SDimitry Andric llvm::Value *NotOverflow = Builder.CreateNot(overflow);
306833956c43SDimitry Andric SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
306939d628a0SDimitry Andric : SanitizerKind::UnsignedIntegerOverflow;
307039d628a0SDimitry Andric EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
307159d1ed5bSDimitry Andric } else
3072139f7f9bSDimitry Andric CGF.EmitTrapCheck(Builder.CreateNot(overflow));
30733861d79fSDimitry Andric return result;
30743861d79fSDimitry Andric }
30753861d79fSDimitry Andric
3076f22ef01cSRoman Divacky // Branch in case of overflow.
30772754fe60SDimitry Andric llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
307844290647SDimitry Andric llvm::BasicBlock *continueBB =
307944290647SDimitry Andric CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode());
3080e580952dSDimitry Andric llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
3081f22ef01cSRoman Divacky
3082f22ef01cSRoman Divacky Builder.CreateCondBr(overflow, overflowBB, continueBB);
3083f22ef01cSRoman Divacky
30842754fe60SDimitry Andric // If an overflow handler is set, then we want to call it and then use its
30852754fe60SDimitry Andric // result, if it returns.
30862754fe60SDimitry Andric Builder.SetInsertPoint(overflowBB);
30872754fe60SDimitry Andric
30882754fe60SDimitry Andric // Get the overflow handler.
3089dff0c46cSDimitry Andric llvm::Type *Int8Ty = CGF.Int8Ty;
309017a519f9SDimitry Andric llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty };
30912754fe60SDimitry Andric llvm::FunctionType *handlerTy =
30922754fe60SDimitry Andric llvm::FunctionType::get(CGF.Int64Ty, argTypes, true);
30932754fe60SDimitry Andric llvm::Value *handler = CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
30942754fe60SDimitry Andric
30952754fe60SDimitry Andric // Sign extend the args to 64-bit, so that we can use the same handler for
30962754fe60SDimitry Andric // all types of overflow.
30972754fe60SDimitry Andric llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty);
30982754fe60SDimitry Andric llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty);
30992754fe60SDimitry Andric
31002754fe60SDimitry Andric // Call the handler with the two arguments, the operation, and the size of
31012754fe60SDimitry Andric // the result.
3102139f7f9bSDimitry Andric llvm::Value *handlerArgs[] = {
3103139f7f9bSDimitry Andric lhs,
3104139f7f9bSDimitry Andric rhs,
31052754fe60SDimitry Andric Builder.getInt8(OpID),
3106139f7f9bSDimitry Andric Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3107139f7f9bSDimitry Andric };
3108139f7f9bSDimitry Andric llvm::Value *handlerResult =
3109139f7f9bSDimitry Andric CGF.EmitNounwindRuntimeCall(handler, handlerArgs);
31102754fe60SDimitry Andric
31112754fe60SDimitry Andric // Truncate the result back to the desired size.
31122754fe60SDimitry Andric handlerResult = Builder.CreateTrunc(handlerResult, opTy);
31132754fe60SDimitry Andric Builder.CreateBr(continueBB);
31142754fe60SDimitry Andric
31152754fe60SDimitry Andric Builder.SetInsertPoint(continueBB);
31163b0f4066SDimitry Andric llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
31172754fe60SDimitry Andric phi->addIncoming(result, initialBB);
31182754fe60SDimitry Andric phi->addIncoming(handlerResult, overflowBB);
31192754fe60SDimitry Andric
31202754fe60SDimitry Andric return phi;
31212754fe60SDimitry Andric }
31222754fe60SDimitry Andric
312317a519f9SDimitry Andric /// Emit pointer + index arithmetic.
emitPointerArithmetic(CodeGenFunction & CGF,const BinOpInfo & op,bool isSubtraction)312417a519f9SDimitry Andric static Value *emitPointerArithmetic(CodeGenFunction &CGF,
312517a519f9SDimitry Andric const BinOpInfo &op,
312617a519f9SDimitry Andric bool isSubtraction) {
312717a519f9SDimitry Andric // Must have binary (not unary) expr here. Unary pointer
312817a519f9SDimitry Andric // increment/decrement doesn't use this path.
312917a519f9SDimitry Andric const BinaryOperator *expr = cast<BinaryOperator>(op.E);
313017a519f9SDimitry Andric
313117a519f9SDimitry Andric Value *pointer = op.LHS;
313217a519f9SDimitry Andric Expr *pointerOperand = expr->getLHS();
313317a519f9SDimitry Andric Value *index = op.RHS;
313417a519f9SDimitry Andric Expr *indexOperand = expr->getRHS();
313517a519f9SDimitry Andric
313617a519f9SDimitry Andric // In a subtraction, the LHS is always the pointer.
313717a519f9SDimitry Andric if (!isSubtraction && !pointer->getType()->isPointerTy()) {
313817a519f9SDimitry Andric std::swap(pointer, index);
313917a519f9SDimitry Andric std::swap(pointerOperand, indexOperand);
3140ffd1746dSEd Schouten }
3141f22ef01cSRoman Divacky
314224d58133SDimitry Andric bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
314324d58133SDimitry Andric
314417a519f9SDimitry Andric unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
314544290647SDimitry Andric auto &DL = CGF.CGM.getDataLayout();
314644290647SDimitry Andric auto PtrTy = cast<llvm::PointerType>(pointer->getType());
31479a199699SDimitry Andric
31489a199699SDimitry Andric // Some versions of glibc and gcc use idioms (particularly in their malloc
31499a199699SDimitry Andric // routines) that add a pointer-sized integer (known to be a pointer value)
31509a199699SDimitry Andric // to a null pointer in order to cast the value back to an integer or as
31519a199699SDimitry Andric // part of a pointer alignment algorithm. This is undefined behavior, but
31529a199699SDimitry Andric // we'd like to be able to compile programs that use it.
31539a199699SDimitry Andric //
31549a199699SDimitry Andric // Normally, we'd generate a GEP with a null-pointer base here in response
31559a199699SDimitry Andric // to that code, but it's also UB to dereference a pointer created that
31569a199699SDimitry Andric // way. Instead (as an acknowledged hack to tolerate the idiom) we will
31579a199699SDimitry Andric // generate a direct cast of the integer value to a pointer.
31589a199699SDimitry Andric //
31599a199699SDimitry Andric // The idiom (p = nullptr + N) is not met if any of the following are true:
31609a199699SDimitry Andric //
31619a199699SDimitry Andric // The operation is subtraction.
31629a199699SDimitry Andric // The index is not pointer-sized.
31639a199699SDimitry Andric // The pointer type is not byte-sized.
31649a199699SDimitry Andric //
31659a199699SDimitry Andric if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(),
31669a199699SDimitry Andric op.Opcode,
31679a199699SDimitry Andric expr->getLHS(),
31689a199699SDimitry Andric expr->getRHS()))
31699a199699SDimitry Andric return CGF.Builder.CreateIntToPtr(index, pointer->getType());
31709a199699SDimitry Andric
317144290647SDimitry Andric if (width != DL.getTypeSizeInBits(PtrTy)) {
317217a519f9SDimitry Andric // Zero-extend or sign-extend the pointer value according to
317317a519f9SDimitry Andric // whether the index is signed or not.
317444290647SDimitry Andric index = CGF.Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned,
317517a519f9SDimitry Andric "idx.ext");
3176f22ef01cSRoman Divacky }
3177f22ef01cSRoman Divacky
317817a519f9SDimitry Andric // If this is subtraction, negate the index.
317917a519f9SDimitry Andric if (isSubtraction)
318017a519f9SDimitry Andric index = CGF.Builder.CreateNeg(index, "idx.neg");
3181ffd1746dSEd Schouten
318239d628a0SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
3183139f7f9bSDimitry Andric CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
3184139f7f9bSDimitry Andric /*Accessed*/ false);
3185139f7f9bSDimitry Andric
318617a519f9SDimitry Andric const PointerType *pointerType
318717a519f9SDimitry Andric = pointerOperand->getType()->getAs<PointerType>();
318817a519f9SDimitry Andric if (!pointerType) {
318917a519f9SDimitry Andric QualType objectType = pointerOperand->getType()
319017a519f9SDimitry Andric ->castAs<ObjCObjectPointerType>()
319117a519f9SDimitry Andric ->getPointeeType();
319217a519f9SDimitry Andric llvm::Value *objectSize
319317a519f9SDimitry Andric = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType));
319417a519f9SDimitry Andric
319517a519f9SDimitry Andric index = CGF.Builder.CreateMul(index, objectSize);
319617a519f9SDimitry Andric
319717a519f9SDimitry Andric Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy);
319817a519f9SDimitry Andric result = CGF.Builder.CreateGEP(result, index, "add.ptr");
319917a519f9SDimitry Andric return CGF.Builder.CreateBitCast(result, pointer->getType());
3200f22ef01cSRoman Divacky }
3201ffd1746dSEd Schouten
320217a519f9SDimitry Andric QualType elementType = pointerType->getPointeeType();
320317a519f9SDimitry Andric if (const VariableArrayType *vla
320417a519f9SDimitry Andric = CGF.getContext().getAsVariableArrayType(elementType)) {
320517a519f9SDimitry Andric // The element count here is the total number of non-VLA elements.
32064ba319b5SDimitry Andric llvm::Value *numElements = CGF.getVLASize(vla).NumElts;
3207f22ef01cSRoman Divacky
320817a519f9SDimitry Andric // Effectively, the multiply by the VLA size is part of the GEP.
320917a519f9SDimitry Andric // GEP indexes are signed, and scaling an index isn't permitted to
321017a519f9SDimitry Andric // signed-overflow, so we use the same semantics for our explicit
321117a519f9SDimitry Andric // multiply. We suppress this if overflow is not undefined behavior.
3212dff0c46cSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined()) {
321317a519f9SDimitry Andric index = CGF.Builder.CreateMul(index, numElements, "vla.index");
321417a519f9SDimitry Andric pointer = CGF.Builder.CreateGEP(pointer, index, "add.ptr");
321517a519f9SDimitry Andric } else {
321617a519f9SDimitry Andric index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
321724d58133SDimitry Andric pointer =
3218b40b48b8SDimitry Andric CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction,
321924d58133SDimitry Andric op.E->getExprLoc(), "add.ptr");
3220f22ef01cSRoman Divacky }
322117a519f9SDimitry Andric return pointer;
3222f22ef01cSRoman Divacky }
3223f22ef01cSRoman Divacky
3224f22ef01cSRoman Divacky // Explicitly handle GNU void* and function pointer arithmetic extensions. The
3225f22ef01cSRoman Divacky // GNU void* casts amount to no-ops since our void* type is i8*, but this is
3226f22ef01cSRoman Divacky // future proof.
322717a519f9SDimitry Andric if (elementType->isVoidType() || elementType->isFunctionType()) {
322817a519f9SDimitry Andric Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy);
322917a519f9SDimitry Andric result = CGF.Builder.CreateGEP(result, index, "add.ptr");
323017a519f9SDimitry Andric return CGF.Builder.CreateBitCast(result, pointer->getType());
3231f22ef01cSRoman Divacky }
3232f22ef01cSRoman Divacky
3233dff0c46cSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
323417a519f9SDimitry Andric return CGF.Builder.CreateGEP(pointer, index, "add.ptr");
323517a519f9SDimitry Andric
3236b40b48b8SDimitry Andric return CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction,
323724d58133SDimitry Andric op.E->getExprLoc(), "add.ptr");
3238f22ef01cSRoman Divacky }
3239f22ef01cSRoman Divacky
32403861d79fSDimitry Andric // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
32413861d79fSDimitry Andric // Addend. Use negMul and negAdd to negate the first operand of the Mul or
32423861d79fSDimitry Andric // the add operand respectively. This allows fmuladd to represent a*b-c, or
32433861d79fSDimitry Andric // c-a*b. Patterns in LLVM should catch the negated forms and translate them to
32443861d79fSDimitry Andric // efficient operations.
buildFMulAdd(llvm::BinaryOperator * MulOp,Value * Addend,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool negMul,bool negAdd)32453861d79fSDimitry Andric static Value* buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend,
32463861d79fSDimitry Andric const CodeGenFunction &CGF, CGBuilderTy &Builder,
32473861d79fSDimitry Andric bool negMul, bool negAdd) {
32483861d79fSDimitry Andric assert(!(negMul && negAdd) && "Only one of negMul and negAdd should be set.");
32493861d79fSDimitry Andric
32503861d79fSDimitry Andric Value *MulOp0 = MulOp->getOperand(0);
32513861d79fSDimitry Andric Value *MulOp1 = MulOp->getOperand(1);
32523861d79fSDimitry Andric if (negMul) {
32533861d79fSDimitry Andric MulOp0 =
32543861d79fSDimitry Andric Builder.CreateFSub(
32553861d79fSDimitry Andric llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0,
32563861d79fSDimitry Andric "neg");
32573861d79fSDimitry Andric } else if (negAdd) {
32583861d79fSDimitry Andric Addend =
32593861d79fSDimitry Andric Builder.CreateFSub(
32603861d79fSDimitry Andric llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend,
32613861d79fSDimitry Andric "neg");
32623861d79fSDimitry Andric }
32633861d79fSDimitry Andric
326433956c43SDimitry Andric Value *FMulAdd = Builder.CreateCall(
32653861d79fSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
326633956c43SDimitry Andric {MulOp0, MulOp1, Addend});
32673861d79fSDimitry Andric MulOp->eraseFromParent();
32683861d79fSDimitry Andric
32693861d79fSDimitry Andric return FMulAdd;
32703861d79fSDimitry Andric }
32713861d79fSDimitry Andric
32723861d79fSDimitry Andric // Check whether it would be legal to emit an fmuladd intrinsic call to
32733861d79fSDimitry Andric // represent op and if so, build the fmuladd.
32743861d79fSDimitry Andric //
32753861d79fSDimitry Andric // Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
32763861d79fSDimitry Andric // Does NOT check the type of the operation - it's assumed that this function
32773861d79fSDimitry Andric // will be called from contexts where it's known that the type is contractable.
tryEmitFMulAdd(const BinOpInfo & op,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool isSub=false)32783861d79fSDimitry Andric static Value* tryEmitFMulAdd(const BinOpInfo &op,
32793861d79fSDimitry Andric const CodeGenFunction &CGF, CGBuilderTy &Builder,
32803861d79fSDimitry Andric bool isSub=false) {
32813861d79fSDimitry Andric
32823861d79fSDimitry Andric assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
32833861d79fSDimitry Andric op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
32843861d79fSDimitry Andric "Only fadd/fsub can be the root of an fmuladd.");
32853861d79fSDimitry Andric
32863861d79fSDimitry Andric // Check whether this op is marked as fusable.
328720e90f04SDimitry Andric if (!op.FPFeatures.allowFPContractWithinStatement())
328859d1ed5bSDimitry Andric return nullptr;
32893861d79fSDimitry Andric
32903861d79fSDimitry Andric // We have a potentially fusable op. Look for a mul on one of the operands.
32910623d748SDimitry Andric // Also, make sure that the mul result isn't used directly. In that case,
32920623d748SDimitry Andric // there's no point creating a muladd operation.
32930623d748SDimitry Andric if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
32940623d748SDimitry Andric if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
32950623d748SDimitry Andric LHSBinOp->use_empty())
32963861d79fSDimitry Andric return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub);
32973861d79fSDimitry Andric }
32980623d748SDimitry Andric if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) {
32990623d748SDimitry Andric if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
33000623d748SDimitry Andric RHSBinOp->use_empty())
33013861d79fSDimitry Andric return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false);
33023861d79fSDimitry Andric }
33033861d79fSDimitry Andric
330459d1ed5bSDimitry Andric return nullptr;
33053861d79fSDimitry Andric }
33063861d79fSDimitry Andric
EmitAdd(const BinOpInfo & op)330717a519f9SDimitry Andric Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
330817a519f9SDimitry Andric if (op.LHS->getType()->isPointerTy() ||
330917a519f9SDimitry Andric op.RHS->getType()->isPointerTy())
3310b40b48b8SDimitry Andric return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction);
331117a519f9SDimitry Andric
331217a519f9SDimitry Andric if (op.Ty->isSignedIntegerOrEnumerationType()) {
33133861d79fSDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
3314ffd1746dSEd Schouten case LangOptions::SOB_Defined:
331517a519f9SDimitry Andric return Builder.CreateAdd(op.LHS, op.RHS, "add");
33163861d79fSDimitry Andric case LangOptions::SOB_Undefined:
331739d628a0SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
33183861d79fSDimitry Andric return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
3319*b5893f02SDimitry Andric LLVM_FALLTHROUGH;
3320ffd1746dSEd Schouten case LangOptions::SOB_Trapping:
332120e90f04SDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), op))
332220e90f04SDimitry Andric return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
332317a519f9SDimitry Andric return EmitOverflowCheckedBinOp(op);
3324ffd1746dSEd Schouten }
3325ffd1746dSEd Schouten }
3326f22ef01cSRoman Divacky
332739d628a0SDimitry Andric if (op.Ty->isUnsignedIntegerType() &&
332820e90f04SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
332920e90f04SDimitry Andric !CanElideOverflowCheck(CGF.getContext(), op))
3330139f7f9bSDimitry Andric return EmitOverflowCheckedBinOp(op);
3331139f7f9bSDimitry Andric
33323861d79fSDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
33333861d79fSDimitry Andric // Try to form an fmuladd.
33343861d79fSDimitry Andric if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
33353861d79fSDimitry Andric return FMulAdd;
33363861d79fSDimitry Andric
333720e90f04SDimitry Andric Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add");
333820e90f04SDimitry Andric return propagateFMFlags(V, op);
33393861d79fSDimitry Andric }
3340f22ef01cSRoman Divacky
334117a519f9SDimitry Andric return Builder.CreateAdd(op.LHS, op.RHS, "add");
3342f22ef01cSRoman Divacky }
3343f22ef01cSRoman Divacky
EmitSub(const BinOpInfo & op)334417a519f9SDimitry Andric Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
334517a519f9SDimitry Andric // The LHS is always a pointer if either side is.
334617a519f9SDimitry Andric if (!op.LHS->getType()->isPointerTy()) {
334717a519f9SDimitry Andric if (op.Ty->isSignedIntegerOrEnumerationType()) {
33483861d79fSDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
334917a519f9SDimitry Andric case LangOptions::SOB_Defined:
335017a519f9SDimitry Andric return Builder.CreateSub(op.LHS, op.RHS, "sub");
33513861d79fSDimitry Andric case LangOptions::SOB_Undefined:
335239d628a0SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
33533861d79fSDimitry Andric return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
3354*b5893f02SDimitry Andric LLVM_FALLTHROUGH;
335517a519f9SDimitry Andric case LangOptions::SOB_Trapping:
335620e90f04SDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), op))
335720e90f04SDimitry Andric return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
335817a519f9SDimitry Andric return EmitOverflowCheckedBinOp(op);
335917a519f9SDimitry Andric }
3360f22ef01cSRoman Divacky }
3361f22ef01cSRoman Divacky
336239d628a0SDimitry Andric if (op.Ty->isUnsignedIntegerType() &&
336320e90f04SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
336420e90f04SDimitry Andric !CanElideOverflowCheck(CGF.getContext(), op))
3365139f7f9bSDimitry Andric return EmitOverflowCheckedBinOp(op);
3366139f7f9bSDimitry Andric
33673861d79fSDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
33683861d79fSDimitry Andric // Try to form an fmuladd.
33693861d79fSDimitry Andric if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
33703861d79fSDimitry Andric return FMulAdd;
337120e90f04SDimitry Andric Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub");
337220e90f04SDimitry Andric return propagateFMFlags(V, op);
33733861d79fSDimitry Andric }
337417a519f9SDimitry Andric
337517a519f9SDimitry Andric return Builder.CreateSub(op.LHS, op.RHS, "sub");
337617a519f9SDimitry Andric }
337717a519f9SDimitry Andric
337817a519f9SDimitry Andric // If the RHS is not a pointer, then we have normal pointer
337917a519f9SDimitry Andric // arithmetic.
338017a519f9SDimitry Andric if (!op.RHS->getType()->isPointerTy())
3381b40b48b8SDimitry Andric return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction);
338217a519f9SDimitry Andric
338317a519f9SDimitry Andric // Otherwise, this is a pointer subtraction.
338417a519f9SDimitry Andric
338517a519f9SDimitry Andric // Do the raw subtraction part.
338617a519f9SDimitry Andric llvm::Value *LHS
338717a519f9SDimitry Andric = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast");
338817a519f9SDimitry Andric llvm::Value *RHS
338917a519f9SDimitry Andric = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast");
339017a519f9SDimitry Andric Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
339117a519f9SDimitry Andric
339217a519f9SDimitry Andric // Okay, figure out the element size.
339317a519f9SDimitry Andric const BinaryOperator *expr = cast<BinaryOperator>(op.E);
339417a519f9SDimitry Andric QualType elementType = expr->getLHS()->getType()->getPointeeType();
339517a519f9SDimitry Andric
339659d1ed5bSDimitry Andric llvm::Value *divisor = nullptr;
339717a519f9SDimitry Andric
339817a519f9SDimitry Andric // For a variable-length array, this is going to be non-constant.
339917a519f9SDimitry Andric if (const VariableArrayType *vla
340017a519f9SDimitry Andric = CGF.getContext().getAsVariableArrayType(elementType)) {
34014ba319b5SDimitry Andric auto VlaSize = CGF.getVLASize(vla);
34024ba319b5SDimitry Andric elementType = VlaSize.Type;
34034ba319b5SDimitry Andric divisor = VlaSize.NumElts;
340417a519f9SDimitry Andric
340517a519f9SDimitry Andric // Scale the number of non-VLA elements by the non-VLA element size.
340617a519f9SDimitry Andric CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType);
340717a519f9SDimitry Andric if (!eltSize.isOne())
340817a519f9SDimitry Andric divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor);
340917a519f9SDimitry Andric
341017a519f9SDimitry Andric // For everything elese, we can just compute it, safe in the
341117a519f9SDimitry Andric // assumption that Sema won't let anything through that we can't
341217a519f9SDimitry Andric // safely compute the size of.
341317a519f9SDimitry Andric } else {
341417a519f9SDimitry Andric CharUnits elementSize;
341517a519f9SDimitry Andric // Handle GCC extension for pointer arithmetic on void* and
341617a519f9SDimitry Andric // function pointer types.
341717a519f9SDimitry Andric if (elementType->isVoidType() || elementType->isFunctionType())
341817a519f9SDimitry Andric elementSize = CharUnits::One();
3419f22ef01cSRoman Divacky else
342017a519f9SDimitry Andric elementSize = CGF.getContext().getTypeSizeInChars(elementType);
342117a519f9SDimitry Andric
342217a519f9SDimitry Andric // Don't even emit the divide for element size of 1.
342317a519f9SDimitry Andric if (elementSize.isOne())
342417a519f9SDimitry Andric return diffInChars;
342517a519f9SDimitry Andric
342617a519f9SDimitry Andric divisor = CGF.CGM.getSize(elementSize);
3427f22ef01cSRoman Divacky }
3428f22ef01cSRoman Divacky
3429f22ef01cSRoman Divacky // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
3430f22ef01cSRoman Divacky // pointer difference in C is only defined in the case where both operands
3431f22ef01cSRoman Divacky // are pointing to elements of an array.
343217a519f9SDimitry Andric return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div");
3433f22ef01cSRoman Divacky }
3434f22ef01cSRoman Divacky
GetWidthMinusOneValue(Value * LHS,Value * RHS)3435139f7f9bSDimitry Andric Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) {
3436139f7f9bSDimitry Andric llvm::IntegerType *Ty;
3437139f7f9bSDimitry Andric if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
3438139f7f9bSDimitry Andric Ty = cast<llvm::IntegerType>(VT->getElementType());
3439139f7f9bSDimitry Andric else
3440139f7f9bSDimitry Andric Ty = cast<llvm::IntegerType>(LHS->getType());
3441139f7f9bSDimitry Andric return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
3442139f7f9bSDimitry Andric }
3443139f7f9bSDimitry Andric
EmitShl(const BinOpInfo & Ops)3444f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
3445f22ef01cSRoman Divacky // LLVM requires the LHS and RHS to be the same type: promote or truncate the
3446f22ef01cSRoman Divacky // RHS to the same size as the LHS.
3447f22ef01cSRoman Divacky Value *RHS = Ops.RHS;
3448f22ef01cSRoman Divacky if (Ops.LHS->getType() != RHS->getType())
3449f22ef01cSRoman Divacky RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
3450f22ef01cSRoman Divacky
345133956c43SDimitry Andric bool SanitizeBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
3452be69257aSDimitry Andric Ops.Ty->hasSignedIntegerRepresentation() &&
3453be69257aSDimitry Andric !CGF.getLangOpts().isSignedOverflowDefined();
345433956c43SDimitry Andric bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
345533956c43SDimitry Andric // OpenCL 6.3j: shift values are effectively % word size of LHS.
345633956c43SDimitry Andric if (CGF.getLangOpts().OpenCL)
345733956c43SDimitry Andric RHS =
345833956c43SDimitry Andric Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shl.mask");
345933956c43SDimitry Andric else if ((SanitizeBase || SanitizeExponent) &&
34603861d79fSDimitry Andric isa<llvm::IntegerType>(Ops.LHS->getType())) {
346159d1ed5bSDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
346233956c43SDimitry Andric SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
346320e90f04SDimitry Andric llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
346420e90f04SDimitry Andric llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
34653861d79fSDimitry Andric
346633956c43SDimitry Andric if (SanitizeExponent) {
346733956c43SDimitry Andric Checks.push_back(
346833956c43SDimitry Andric std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
346933956c43SDimitry Andric }
347033956c43SDimitry Andric
347133956c43SDimitry Andric if (SanitizeBase) {
347233956c43SDimitry Andric // Check whether we are shifting any non-zero bits off the top of the
347333956c43SDimitry Andric // integer. We only emit this check if exponent is valid - otherwise
347433956c43SDimitry Andric // instructions below will have undefined behavior themselves.
3475139f7f9bSDimitry Andric llvm::BasicBlock *Orig = Builder.GetInsertBlock();
3476139f7f9bSDimitry Andric llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
347733956c43SDimitry Andric llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
347833956c43SDimitry Andric Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
347920e90f04SDimitry Andric llvm::Value *PromotedWidthMinusOne =
348020e90f04SDimitry Andric (RHS == Ops.RHS) ? WidthMinusOne
348120e90f04SDimitry Andric : GetWidthMinusOneValue(Ops.LHS, RHS);
348233956c43SDimitry Andric CGF.EmitBlock(CheckShiftBase);
348320e90f04SDimitry Andric llvm::Value *BitsShiftedOff = Builder.CreateLShr(
348420e90f04SDimitry Andric Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
34853861d79fSDimitry Andric /*NUW*/ true, /*NSW*/ true),
34863861d79fSDimitry Andric "shl.check");
34873861d79fSDimitry Andric if (CGF.getLangOpts().CPlusPlus) {
34883861d79fSDimitry Andric // In C99, we are not permitted to shift a 1 bit into the sign bit.
34893861d79fSDimitry Andric // Under C++11's rules, shifting a 1 bit into the sign bit is
34903861d79fSDimitry Andric // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't
34913861d79fSDimitry Andric // define signed left shifts, so we use the C99 and C++11 rules there).
34923861d79fSDimitry Andric llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
34933861d79fSDimitry Andric BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
34943861d79fSDimitry Andric }
34953861d79fSDimitry Andric llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
349633956c43SDimitry Andric llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
3497139f7f9bSDimitry Andric CGF.EmitBlock(Cont);
349833956c43SDimitry Andric llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
349933956c43SDimitry Andric BaseCheck->addIncoming(Builder.getTrue(), Orig);
350033956c43SDimitry Andric BaseCheck->addIncoming(ValidBase, CheckShiftBase);
350133956c43SDimitry Andric Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase));
35023861d79fSDimitry Andric }
3503139f7f9bSDimitry Andric
350433956c43SDimitry Andric assert(!Checks.empty());
350533956c43SDimitry Andric EmitBinOpCheck(Checks, Ops);
3506f22ef01cSRoman Divacky }
3507f22ef01cSRoman Divacky
3508f22ef01cSRoman Divacky return Builder.CreateShl(Ops.LHS, RHS, "shl");
3509f22ef01cSRoman Divacky }
3510f22ef01cSRoman Divacky
EmitShr(const BinOpInfo & Ops)3511f22ef01cSRoman Divacky Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
3512f22ef01cSRoman Divacky // LLVM requires the LHS and RHS to be the same type: promote or truncate the
3513f22ef01cSRoman Divacky // RHS to the same size as the LHS.
3514f22ef01cSRoman Divacky Value *RHS = Ops.RHS;
3515f22ef01cSRoman Divacky if (Ops.LHS->getType() != RHS->getType())
3516f22ef01cSRoman Divacky RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
3517f22ef01cSRoman Divacky
351833956c43SDimitry Andric // OpenCL 6.3j: shift values are effectively % word size of LHS.
351933956c43SDimitry Andric if (CGF.getLangOpts().OpenCL)
352033956c43SDimitry Andric RHS =
352133956c43SDimitry Andric Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shr.mask");
352233956c43SDimitry Andric else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
352359d1ed5bSDimitry Andric isa<llvm::IntegerType>(Ops.LHS->getType())) {
352459d1ed5bSDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
352539d628a0SDimitry Andric llvm::Value *Valid =
352639d628a0SDimitry Andric Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
352733956c43SDimitry Andric EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
352859d1ed5bSDimitry Andric }
3529139f7f9bSDimitry Andric
3530e580952dSDimitry Andric if (Ops.Ty->hasUnsignedIntegerRepresentation())
3531f22ef01cSRoman Divacky return Builder.CreateLShr(Ops.LHS, RHS, "shr");
3532f22ef01cSRoman Divacky return Builder.CreateAShr(Ops.LHS, RHS, "shr");
3533f22ef01cSRoman Divacky }
3534f22ef01cSRoman Divacky
35352754fe60SDimitry Andric enum IntrinsicType { VCMPEQ, VCMPGT };
35362754fe60SDimitry Andric // return corresponding comparison intrinsic for given vector type
GetIntrinsic(IntrinsicType IT,BuiltinType::Kind ElemKind)35372754fe60SDimitry Andric static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
35382754fe60SDimitry Andric BuiltinType::Kind ElemKind) {
35392754fe60SDimitry Andric switch (ElemKind) {
35406122f3e6SDimitry Andric default: llvm_unreachable("unexpected element type");
35412754fe60SDimitry Andric case BuiltinType::Char_U:
35422754fe60SDimitry Andric case BuiltinType::UChar:
35432754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
35442754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
35452754fe60SDimitry Andric case BuiltinType::Char_S:
35462754fe60SDimitry Andric case BuiltinType::SChar:
35472754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
35482754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
35492754fe60SDimitry Andric case BuiltinType::UShort:
35502754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
35512754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
35522754fe60SDimitry Andric case BuiltinType::Short:
35532754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
35542754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
35552754fe60SDimitry Andric case BuiltinType::UInt:
35562754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
35572754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
35582754fe60SDimitry Andric case BuiltinType::Int:
35592754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
35602754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
35619a199699SDimitry Andric case BuiltinType::ULong:
35629a199699SDimitry Andric case BuiltinType::ULongLong:
35639a199699SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
35649a199699SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
35659a199699SDimitry Andric case BuiltinType::Long:
35669a199699SDimitry Andric case BuiltinType::LongLong:
35679a199699SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
35689a199699SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
35692754fe60SDimitry Andric case BuiltinType::Float:
35702754fe60SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
35712754fe60SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
35729a199699SDimitry Andric case BuiltinType::Double:
35739a199699SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
35749a199699SDimitry Andric llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
35752754fe60SDimitry Andric }
35762754fe60SDimitry Andric }
35772754fe60SDimitry Andric
EmitCompare(const BinaryOperator * E,llvm::CmpInst::Predicate UICmpOpc,llvm::CmpInst::Predicate SICmpOpc,llvm::CmpInst::Predicate FCmpOpc)35780623d748SDimitry Andric Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
35790623d748SDimitry Andric llvm::CmpInst::Predicate UICmpOpc,
35800623d748SDimitry Andric llvm::CmpInst::Predicate SICmpOpc,
35810623d748SDimitry Andric llvm::CmpInst::Predicate FCmpOpc) {
3582f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
3583f22ef01cSRoman Divacky Value *Result;
3584f22ef01cSRoman Divacky QualType LHSTy = E->getLHS()->getType();
358539d628a0SDimitry Andric QualType RHSTy = E->getRHS()->getType();
3586e580952dSDimitry Andric if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) {
3587e580952dSDimitry Andric assert(E->getOpcode() == BO_EQ ||
3588e580952dSDimitry Andric E->getOpcode() == BO_NE);
3589e580952dSDimitry Andric Value *LHS = CGF.EmitScalarExpr(E->getLHS());
3590e580952dSDimitry Andric Value *RHS = CGF.EmitScalarExpr(E->getRHS());
3591e580952dSDimitry Andric Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
3592e580952dSDimitry Andric CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
359339d628a0SDimitry Andric } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) {
3594f22ef01cSRoman Divacky Value *LHS = Visit(E->getLHS());
3595f22ef01cSRoman Divacky Value *RHS = Visit(E->getRHS());
3596f22ef01cSRoman Divacky
35972754fe60SDimitry Andric // If AltiVec, the comparison results in a numeric type, so we use
35982754fe60SDimitry Andric // intrinsics comparing vectors and giving 0 or 1 as a result
35993b0f4066SDimitry Andric if (LHSTy->isVectorType() && !E->getType()->isVectorType()) {
36002754fe60SDimitry Andric // constants for mapping CR6 register bits to predicate result
36012754fe60SDimitry Andric enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
36022754fe60SDimitry Andric
36032754fe60SDimitry Andric llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic;
36042754fe60SDimitry Andric
36052754fe60SDimitry Andric // in several cases vector arguments order will be reversed
36062754fe60SDimitry Andric Value *FirstVecArg = LHS,
36072754fe60SDimitry Andric *SecondVecArg = RHS;
36082754fe60SDimitry Andric
36092754fe60SDimitry Andric QualType ElTy = LHSTy->getAs<VectorType>()->getElementType();
36102754fe60SDimitry Andric const BuiltinType *BTy = ElTy->getAs<BuiltinType>();
36112754fe60SDimitry Andric BuiltinType::Kind ElementKind = BTy->getKind();
36122754fe60SDimitry Andric
36132754fe60SDimitry Andric switch(E->getOpcode()) {
36146122f3e6SDimitry Andric default: llvm_unreachable("is not a comparison operation");
36152754fe60SDimitry Andric case BO_EQ:
36162754fe60SDimitry Andric CR6 = CR6_LT;
36172754fe60SDimitry Andric ID = GetIntrinsic(VCMPEQ, ElementKind);
36182754fe60SDimitry Andric break;
36192754fe60SDimitry Andric case BO_NE:
36202754fe60SDimitry Andric CR6 = CR6_EQ;
36212754fe60SDimitry Andric ID = GetIntrinsic(VCMPEQ, ElementKind);
36222754fe60SDimitry Andric break;
36232754fe60SDimitry Andric case BO_LT:
36242754fe60SDimitry Andric CR6 = CR6_LT;
36252754fe60SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
36262754fe60SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
36272754fe60SDimitry Andric break;
36282754fe60SDimitry Andric case BO_GT:
36292754fe60SDimitry Andric CR6 = CR6_LT;
36302754fe60SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
36312754fe60SDimitry Andric break;
36322754fe60SDimitry Andric case BO_LE:
36332754fe60SDimitry Andric if (ElementKind == BuiltinType::Float) {
36342754fe60SDimitry Andric CR6 = CR6_LT;
36352754fe60SDimitry Andric ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
36362754fe60SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
36372754fe60SDimitry Andric }
36382754fe60SDimitry Andric else {
36392754fe60SDimitry Andric CR6 = CR6_EQ;
36402754fe60SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
36412754fe60SDimitry Andric }
36422754fe60SDimitry Andric break;
36432754fe60SDimitry Andric case BO_GE:
36442754fe60SDimitry Andric if (ElementKind == BuiltinType::Float) {
36452754fe60SDimitry Andric CR6 = CR6_LT;
36462754fe60SDimitry Andric ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
36472754fe60SDimitry Andric }
36482754fe60SDimitry Andric else {
36492754fe60SDimitry Andric CR6 = CR6_EQ;
36502754fe60SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
36512754fe60SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
36522754fe60SDimitry Andric }
36532754fe60SDimitry Andric break;
36542754fe60SDimitry Andric }
36552754fe60SDimitry Andric
36563b0f4066SDimitry Andric Value *CR6Param = Builder.getInt32(CR6);
36572754fe60SDimitry Andric llvm::Function *F = CGF.CGM.getIntrinsic(ID);
365833956c43SDimitry Andric Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
36599a199699SDimitry Andric
36609a199699SDimitry Andric // The result type of intrinsic may not be same as E->getType().
36619a199699SDimitry Andric // If E->getType() is not BoolTy, EmitScalarConversion will do the
36629a199699SDimitry Andric // conversion work. If E->getType() is BoolTy, EmitScalarConversion will
36639a199699SDimitry Andric // do nothing, if ResultTy is not i1 at the same time, it will cause
36649a199699SDimitry Andric // crash later.
36659a199699SDimitry Andric llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
36669a199699SDimitry Andric if (ResultTy->getBitWidth() > 1 &&
36679a199699SDimitry Andric E->getType() == CGF.getContext().BoolTy)
36689a199699SDimitry Andric Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
36690623d748SDimitry Andric return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
36700623d748SDimitry Andric E->getExprLoc());
36712754fe60SDimitry Andric }
36722754fe60SDimitry Andric
3673f22ef01cSRoman Divacky if (LHS->getType()->isFPOrFPVectorTy()) {
36740623d748SDimitry Andric Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
3675e580952dSDimitry Andric } else if (LHSTy->hasSignedIntegerRepresentation()) {
36760623d748SDimitry Andric Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
3677f22ef01cSRoman Divacky } else {
3678f22ef01cSRoman Divacky // Unsigned integers and pointers.
36794ba319b5SDimitry Andric
36804ba319b5SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers &&
36814ba319b5SDimitry Andric !isa<llvm::ConstantPointerNull>(LHS) &&
36824ba319b5SDimitry Andric !isa<llvm::ConstantPointerNull>(RHS)) {
36834ba319b5SDimitry Andric
36844ba319b5SDimitry Andric // Dynamic information is required to be stripped for comparisons,
36854ba319b5SDimitry Andric // because it could leak the dynamic information. Based on comparisons
36864ba319b5SDimitry Andric // of pointers to dynamic objects, the optimizer can replace one pointer
36874ba319b5SDimitry Andric // with another, which might be incorrect in presence of invariant
36884ba319b5SDimitry Andric // groups. Comparison with null is safe because null does not carry any
36894ba319b5SDimitry Andric // dynamic information.
36904ba319b5SDimitry Andric if (LHSTy.mayBeDynamicClass())
36914ba319b5SDimitry Andric LHS = Builder.CreateStripInvariantGroup(LHS);
36924ba319b5SDimitry Andric if (RHSTy.mayBeDynamicClass())
36934ba319b5SDimitry Andric RHS = Builder.CreateStripInvariantGroup(RHS);
36944ba319b5SDimitry Andric }
36954ba319b5SDimitry Andric
36960623d748SDimitry Andric Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
3697f22ef01cSRoman Divacky }
3698f22ef01cSRoman Divacky
3699f22ef01cSRoman Divacky // If this is a vector comparison, sign extend the result to the appropriate
3700f22ef01cSRoman Divacky // vector integer type and return it (don't convert to bool).
3701f22ef01cSRoman Divacky if (LHSTy->isVectorType())
3702f22ef01cSRoman Divacky return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
3703f22ef01cSRoman Divacky
3704f22ef01cSRoman Divacky } else {
3705f22ef01cSRoman Divacky // Complex Comparison: can only be an equality comparison.
370639d628a0SDimitry Andric CodeGenFunction::ComplexPairTy LHS, RHS;
370739d628a0SDimitry Andric QualType CETy;
370839d628a0SDimitry Andric if (auto *CTy = LHSTy->getAs<ComplexType>()) {
370939d628a0SDimitry Andric LHS = CGF.EmitComplexExpr(E->getLHS());
371039d628a0SDimitry Andric CETy = CTy->getElementType();
371139d628a0SDimitry Andric } else {
371239d628a0SDimitry Andric LHS.first = Visit(E->getLHS());
371339d628a0SDimitry Andric LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
371439d628a0SDimitry Andric CETy = LHSTy;
371539d628a0SDimitry Andric }
371639d628a0SDimitry Andric if (auto *CTy = RHSTy->getAs<ComplexType>()) {
371739d628a0SDimitry Andric RHS = CGF.EmitComplexExpr(E->getRHS());
371839d628a0SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(CETy,
371939d628a0SDimitry Andric CTy->getElementType()) &&
372039d628a0SDimitry Andric "The element types must always match.");
372139d628a0SDimitry Andric (void)CTy;
372239d628a0SDimitry Andric } else {
372339d628a0SDimitry Andric RHS.first = Visit(E->getRHS());
372439d628a0SDimitry Andric RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
372539d628a0SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) &&
372639d628a0SDimitry Andric "The element types must always match.");
372739d628a0SDimitry Andric }
3728f22ef01cSRoman Divacky
3729f22ef01cSRoman Divacky Value *ResultR, *ResultI;
3730f22ef01cSRoman Divacky if (CETy->isRealFloatingType()) {
37310623d748SDimitry Andric ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r");
37320623d748SDimitry Andric ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i");
3733f22ef01cSRoman Divacky } else {
3734f22ef01cSRoman Divacky // Complex comparisons can only be equality comparisons. As such, signed
3735f22ef01cSRoman Divacky // and unsigned opcodes are the same.
37360623d748SDimitry Andric ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r");
37370623d748SDimitry Andric ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i");
3738f22ef01cSRoman Divacky }
3739f22ef01cSRoman Divacky
3740e580952dSDimitry Andric if (E->getOpcode() == BO_EQ) {
3741f22ef01cSRoman Divacky Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
3742f22ef01cSRoman Divacky } else {
3743e580952dSDimitry Andric assert(E->getOpcode() == BO_NE &&
3744f22ef01cSRoman Divacky "Complex comparison other than == or != ?");
3745f22ef01cSRoman Divacky Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
3746f22ef01cSRoman Divacky }
3747f22ef01cSRoman Divacky }
3748f22ef01cSRoman Divacky
37490623d748SDimitry Andric return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
37500623d748SDimitry Andric E->getExprLoc());
3751f22ef01cSRoman Divacky }
3752f22ef01cSRoman Divacky
VisitBinAssign(const BinaryOperator * E)3753f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
3754f22ef01cSRoman Divacky bool Ignore = TestAndClearIgnoreResultAssign();
3755f22ef01cSRoman Divacky
375617a519f9SDimitry Andric Value *RHS;
375717a519f9SDimitry Andric LValue LHS;
375817a519f9SDimitry Andric
375917a519f9SDimitry Andric switch (E->getLHS()->getType().getObjCLifetime()) {
376017a519f9SDimitry Andric case Qualifiers::OCL_Strong:
376159d1ed5bSDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
376217a519f9SDimitry Andric break;
376317a519f9SDimitry Andric
376417a519f9SDimitry Andric case Qualifiers::OCL_Autoreleasing:
376559d1ed5bSDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E);
376617a519f9SDimitry Andric break;
376717a519f9SDimitry Andric
3768e7145dcbSDimitry Andric case Qualifiers::OCL_ExplicitNone:
3769e7145dcbSDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore);
3770e7145dcbSDimitry Andric break;
3771e7145dcbSDimitry Andric
377217a519f9SDimitry Andric case Qualifiers::OCL_Weak:
377317a519f9SDimitry Andric RHS = Visit(E->getRHS());
37743861d79fSDimitry Andric LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
377517a519f9SDimitry Andric RHS = CGF.EmitARCStoreWeak(LHS.getAddress(), RHS, Ignore);
377617a519f9SDimitry Andric break;
377717a519f9SDimitry Andric
377817a519f9SDimitry Andric case Qualifiers::OCL_None:
377917a519f9SDimitry Andric // __block variables need to have the rhs evaluated first, plus
378017a519f9SDimitry Andric // this should improve codegen just a little.
378117a519f9SDimitry Andric RHS = Visit(E->getRHS());
37823861d79fSDimitry Andric LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
3783f22ef01cSRoman Divacky
3784f22ef01cSRoman Divacky // Store the value into the LHS. Bit-fields are handled specially
3785f22ef01cSRoman Divacky // because the result is altered by the store, i.e., [C99 6.5.16p1]
3786f22ef01cSRoman Divacky // 'An assignment expression has the value of the left operand after
3787f22ef01cSRoman Divacky // the assignment...'.
378820e90f04SDimitry Andric if (LHS.isBitField()) {
378917a519f9SDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
379020e90f04SDimitry Andric } else {
379120e90f04SDimitry Andric CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
379217a519f9SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
379317a519f9SDimitry Andric }
379420e90f04SDimitry Andric }
3795ffd1746dSEd Schouten
3796ffd1746dSEd Schouten // If the result is clearly ignored, return now.
3797f22ef01cSRoman Divacky if (Ignore)
379859d1ed5bSDimitry Andric return nullptr;
3799ffd1746dSEd Schouten
38002754fe60SDimitry Andric // The result of an assignment in C is the assigned r-value.
38013861d79fSDimitry Andric if (!CGF.getLangOpts().CPlusPlus)
3802ffd1746dSEd Schouten return RHS;
3803ffd1746dSEd Schouten
3804ffd1746dSEd Schouten // If the lvalue is non-volatile, return the computed value of the assignment.
3805ffd1746dSEd Schouten if (!LHS.isVolatileQualified())
3806ffd1746dSEd Schouten return RHS;
3807ffd1746dSEd Schouten
3808ffd1746dSEd Schouten // Otherwise, reload the value.
3809f785676fSDimitry Andric return EmitLoadOfLValue(LHS, E->getExprLoc());
3810f22ef01cSRoman Divacky }
3811f22ef01cSRoman Divacky
VisitBinLAnd(const BinaryOperator * E)3812f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
3813dff0c46cSDimitry Andric // Perform vector logical and on comparisons with zero vectors.
3814dff0c46cSDimitry Andric if (E->getType()->isVectorType()) {
381533956c43SDimitry Andric CGF.incrementProfileCounter(E);
381659d1ed5bSDimitry Andric
3817dff0c46cSDimitry Andric Value *LHS = Visit(E->getLHS());
3818dff0c46cSDimitry Andric Value *RHS = Visit(E->getRHS());
3819dff0c46cSDimitry Andric Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3820139f7f9bSDimitry Andric if (LHS->getType()->isFPOrFPVectorTy()) {
3821139f7f9bSDimitry Andric LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
3822139f7f9bSDimitry Andric RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
3823139f7f9bSDimitry Andric } else {
3824dff0c46cSDimitry Andric LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
3825dff0c46cSDimitry Andric RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
3826139f7f9bSDimitry Andric }
3827dff0c46cSDimitry Andric Value *And = Builder.CreateAnd(LHS, RHS);
3828139f7f9bSDimitry Andric return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");
3829dff0c46cSDimitry Andric }
3830dff0c46cSDimitry Andric
38316122f3e6SDimitry Andric llvm::Type *ResTy = ConvertType(E->getType());
3832f22ef01cSRoman Divacky
3833f22ef01cSRoman Divacky // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
3834f22ef01cSRoman Divacky // If we have 1 && X, just emit X without inserting the control flow.
38353b0f4066SDimitry Andric bool LHSCondVal;
38363b0f4066SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
38373b0f4066SDimitry Andric if (LHSCondVal) { // If we have 1 && X, just emit X.
383833956c43SDimitry Andric CGF.incrementProfileCounter(E);
383959d1ed5bSDimitry Andric
3840f22ef01cSRoman Divacky Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
3841f22ef01cSRoman Divacky // ZExt result to int or bool.
3842f22ef01cSRoman Divacky return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
3843f22ef01cSRoman Divacky }
3844f22ef01cSRoman Divacky
3845f22ef01cSRoman Divacky // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
3846f22ef01cSRoman Divacky if (!CGF.ContainsLabel(E->getRHS()))
3847f22ef01cSRoman Divacky return llvm::Constant::getNullValue(ResTy);
3848f22ef01cSRoman Divacky }
3849f22ef01cSRoman Divacky
3850f22ef01cSRoman Divacky llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
3851f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs");
3852f22ef01cSRoman Divacky
38532754fe60SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
38542754fe60SDimitry Andric
3855f22ef01cSRoman Divacky // Branch on the LHS first. If it is false, go to the failure (cont) block.
385633956c43SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
385733956c43SDimitry Andric CGF.getProfileCount(E->getRHS()));
3858f22ef01cSRoman Divacky
3859f22ef01cSRoman Divacky // Any edges into the ContBlock are now from an (indeterminate number of)
3860f22ef01cSRoman Divacky // edges from this first condition. All of these values will be false. Start
3861f22ef01cSRoman Divacky // setting up the PHI node in the Cont Block for this.
38623b0f4066SDimitry Andric llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
3863f22ef01cSRoman Divacky "", ContBlock);
3864f22ef01cSRoman Divacky for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3865f22ef01cSRoman Divacky PI != PE; ++PI)
3866f22ef01cSRoman Divacky PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
3867f22ef01cSRoman Divacky
38682754fe60SDimitry Andric eval.begin(CGF);
3869f22ef01cSRoman Divacky CGF.EmitBlock(RHSBlock);
387033956c43SDimitry Andric CGF.incrementProfileCounter(E);
3871f22ef01cSRoman Divacky Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
38722754fe60SDimitry Andric eval.end(CGF);
3873f22ef01cSRoman Divacky
3874f22ef01cSRoman Divacky // Reaquire the RHS block, as there may be subblocks inserted.
3875f22ef01cSRoman Divacky RHSBlock = Builder.GetInsertBlock();
3876f22ef01cSRoman Divacky
387759d1ed5bSDimitry Andric // Emit an unconditional branch from this block to ContBlock.
387859d1ed5bSDimitry Andric {
38793b0f4066SDimitry Andric // There is no need to emit line number for unconditional branch.
388033956c43SDimitry Andric auto NL = ApplyDebugLocation::CreateEmpty(CGF);
3881f22ef01cSRoman Divacky CGF.EmitBlock(ContBlock);
388259d1ed5bSDimitry Andric }
388359d1ed5bSDimitry Andric // Insert an entry into the phi node for the edge with the value of RHSCond.
3884f22ef01cSRoman Divacky PN->addIncoming(RHSCond, RHSBlock);
3885f22ef01cSRoman Divacky
38864ba319b5SDimitry Andric // Artificial location to preserve the scope information
38874ba319b5SDimitry Andric {
38884ba319b5SDimitry Andric auto NL = ApplyDebugLocation::CreateArtificial(CGF);
38894ba319b5SDimitry Andric PN->setDebugLoc(Builder.getCurrentDebugLocation());
38904ba319b5SDimitry Andric }
38914ba319b5SDimitry Andric
3892f22ef01cSRoman Divacky // ZExt result to int.
3893f22ef01cSRoman Divacky return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");
3894f22ef01cSRoman Divacky }
3895f22ef01cSRoman Divacky
VisitBinLOr(const BinaryOperator * E)3896f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
3897dff0c46cSDimitry Andric // Perform vector logical or on comparisons with zero vectors.
3898dff0c46cSDimitry Andric if (E->getType()->isVectorType()) {
389933956c43SDimitry Andric CGF.incrementProfileCounter(E);
390059d1ed5bSDimitry Andric
3901dff0c46cSDimitry Andric Value *LHS = Visit(E->getLHS());
3902dff0c46cSDimitry Andric Value *RHS = Visit(E->getRHS());
3903dff0c46cSDimitry Andric Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
3904139f7f9bSDimitry Andric if (LHS->getType()->isFPOrFPVectorTy()) {
3905139f7f9bSDimitry Andric LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
3906139f7f9bSDimitry Andric RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
3907139f7f9bSDimitry Andric } else {
3908dff0c46cSDimitry Andric LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
3909dff0c46cSDimitry Andric RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
3910139f7f9bSDimitry Andric }
3911dff0c46cSDimitry Andric Value *Or = Builder.CreateOr(LHS, RHS);
3912139f7f9bSDimitry Andric return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");
3913dff0c46cSDimitry Andric }
3914dff0c46cSDimitry Andric
39156122f3e6SDimitry Andric llvm::Type *ResTy = ConvertType(E->getType());
3916f22ef01cSRoman Divacky
3917f22ef01cSRoman Divacky // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
3918f22ef01cSRoman Divacky // If we have 0 || X, just emit X without inserting the control flow.
39193b0f4066SDimitry Andric bool LHSCondVal;
39203b0f4066SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
39213b0f4066SDimitry Andric if (!LHSCondVal) { // If we have 0 || X, just emit X.
392233956c43SDimitry Andric CGF.incrementProfileCounter(E);
392359d1ed5bSDimitry Andric
3924f22ef01cSRoman Divacky Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
3925f22ef01cSRoman Divacky // ZExt result to int or bool.
3926f22ef01cSRoman Divacky return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
3927f22ef01cSRoman Divacky }
3928f22ef01cSRoman Divacky
3929f22ef01cSRoman Divacky // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.
3930f22ef01cSRoman Divacky if (!CGF.ContainsLabel(E->getRHS()))
3931f22ef01cSRoman Divacky return llvm::ConstantInt::get(ResTy, 1);
3932f22ef01cSRoman Divacky }
3933f22ef01cSRoman Divacky
3934f22ef01cSRoman Divacky llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
3935f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
3936f22ef01cSRoman Divacky
39372754fe60SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
39382754fe60SDimitry Andric
3939f22ef01cSRoman Divacky // Branch on the LHS first. If it is true, go to the success (cont) block.
394059d1ed5bSDimitry Andric CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock,
394133956c43SDimitry Andric CGF.getCurrentProfileCount() -
394233956c43SDimitry Andric CGF.getProfileCount(E->getRHS()));
3943f22ef01cSRoman Divacky
3944f22ef01cSRoman Divacky // Any edges into the ContBlock are now from an (indeterminate number of)
3945f22ef01cSRoman Divacky // edges from this first condition. All of these values will be true. Start
3946f22ef01cSRoman Divacky // setting up the PHI node in the Cont Block for this.
39473b0f4066SDimitry Andric llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
3948f22ef01cSRoman Divacky "", ContBlock);
3949f22ef01cSRoman Divacky for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
3950f22ef01cSRoman Divacky PI != PE; ++PI)
3951f22ef01cSRoman Divacky PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
3952f22ef01cSRoman Divacky
39532754fe60SDimitry Andric eval.begin(CGF);
3954f22ef01cSRoman Divacky
3955f22ef01cSRoman Divacky // Emit the RHS condition as a bool value.
3956f22ef01cSRoman Divacky CGF.EmitBlock(RHSBlock);
395733956c43SDimitry Andric CGF.incrementProfileCounter(E);
3958f22ef01cSRoman Divacky Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
3959f22ef01cSRoman Divacky
39602754fe60SDimitry Andric eval.end(CGF);
3961f22ef01cSRoman Divacky
3962f22ef01cSRoman Divacky // Reaquire the RHS block, as there may be subblocks inserted.
3963f22ef01cSRoman Divacky RHSBlock = Builder.GetInsertBlock();
3964f22ef01cSRoman Divacky
3965f22ef01cSRoman Divacky // Emit an unconditional branch from this block to ContBlock. Insert an entry
3966f22ef01cSRoman Divacky // into the phi node for the edge with the value of RHSCond.
3967f22ef01cSRoman Divacky CGF.EmitBlock(ContBlock);
3968f22ef01cSRoman Divacky PN->addIncoming(RHSCond, RHSBlock);
3969f22ef01cSRoman Divacky
3970f22ef01cSRoman Divacky // ZExt result to int.
3971f22ef01cSRoman Divacky return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");
3972f22ef01cSRoman Divacky }
3973f22ef01cSRoman Divacky
VisitBinComma(const BinaryOperator * E)3974f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
39752754fe60SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS());
3976f22ef01cSRoman Divacky CGF.EnsureInsertPoint();
3977f22ef01cSRoman Divacky return Visit(E->getRHS());
3978f22ef01cSRoman Divacky }
3979f22ef01cSRoman Divacky
3980f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
3981f22ef01cSRoman Divacky // Other Operators
3982f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
3983f22ef01cSRoman Divacky
3984f22ef01cSRoman Divacky /// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
3985f22ef01cSRoman Divacky /// expression is cheap enough and side-effect-free enough to evaluate
3986f22ef01cSRoman Divacky /// unconditionally instead of conditionally. This is used to convert control
3987f22ef01cSRoman Divacky /// flow into selects in some cases.
isCheapEnoughToEvaluateUnconditionally(const Expr * E,CodeGenFunction & CGF)3988f22ef01cSRoman Divacky static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
3989f22ef01cSRoman Divacky CodeGenFunction &CGF) {
39903b0f4066SDimitry Andric // Anything that is an integer or floating point constant is fine.
3991f785676fSDimitry Andric return E->IgnoreParens()->isEvaluatable(CGF.getContext());
3992f22ef01cSRoman Divacky
3993f785676fSDimitry Andric // Even non-volatile automatic variables can't be evaluated unconditionally.
3994f785676fSDimitry Andric // Referencing a thread_local may cause non-trivial initialization work to
3995f785676fSDimitry Andric // occur. If we're inside a lambda and one of the variables is from the scope
3996f785676fSDimitry Andric // outside the lambda, that function may have returned already. Reading its
3997f785676fSDimitry Andric // locals is a bad idea. Also, these reads may introduce races there didn't
3998f785676fSDimitry Andric // exist in the source-level program.
3999f22ef01cSRoman Divacky }
4000f22ef01cSRoman Divacky
4001f22ef01cSRoman Divacky
4002f22ef01cSRoman Divacky Value *ScalarExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)40032754fe60SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
4004f22ef01cSRoman Divacky TestAndClearIgnoreResultAssign();
40052754fe60SDimitry Andric
40062754fe60SDimitry Andric // Bind the common expression if necessary.
40072754fe60SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E);
40082754fe60SDimitry Andric
40092754fe60SDimitry Andric Expr *condExpr = E->getCond();
40102754fe60SDimitry Andric Expr *lhsExpr = E->getTrueExpr();
40112754fe60SDimitry Andric Expr *rhsExpr = E->getFalseExpr();
40122754fe60SDimitry Andric
4013f22ef01cSRoman Divacky // If the condition constant folds and can be elided, try to avoid emitting
4014f22ef01cSRoman Divacky // the condition and the dead arm.
40153b0f4066SDimitry Andric bool CondExprBool;
40163b0f4066SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
40172754fe60SDimitry Andric Expr *live = lhsExpr, *dead = rhsExpr;
40183b0f4066SDimitry Andric if (!CondExprBool) std::swap(live, dead);
4019f22ef01cSRoman Divacky
4020dff0c46cSDimitry Andric // If the dead side doesn't have labels we need, just emit the Live part.
4021dff0c46cSDimitry Andric if (!CGF.ContainsLabel(dead)) {
402259d1ed5bSDimitry Andric if (CondExprBool)
402333956c43SDimitry Andric CGF.incrementProfileCounter(E);
4024dff0c46cSDimitry Andric Value *Result = Visit(live);
4025dff0c46cSDimitry Andric
4026dff0c46cSDimitry Andric // If the live part is a throw expression, it acts like it has a void
4027dff0c46cSDimitry Andric // type, so evaluating it returns a null Value*. However, a conditional
4028dff0c46cSDimitry Andric // with non-void type must return a non-null Value*.
4029dff0c46cSDimitry Andric if (!Result && !E->getType()->isVoidType())
4030dff0c46cSDimitry Andric Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
4031dff0c46cSDimitry Andric
4032dff0c46cSDimitry Andric return Result;
4033dff0c46cSDimitry Andric }
4034f22ef01cSRoman Divacky }
4035f22ef01cSRoman Divacky
40362754fe60SDimitry Andric // OpenCL: If the condition is a vector, we can treat this condition like
40372754fe60SDimitry Andric // the select function.
40383861d79fSDimitry Andric if (CGF.getLangOpts().OpenCL
40392754fe60SDimitry Andric && condExpr->getType()->isVectorType()) {
404033956c43SDimitry Andric CGF.incrementProfileCounter(E);
404159d1ed5bSDimitry Andric
40422754fe60SDimitry Andric llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
40432754fe60SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
40442754fe60SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
40452754fe60SDimitry Andric
40466122f3e6SDimitry Andric llvm::Type *condType = ConvertType(condExpr->getType());
40476122f3e6SDimitry Andric llvm::VectorType *vecTy = cast<llvm::VectorType>(condType);
40482754fe60SDimitry Andric
40492754fe60SDimitry Andric unsigned numElem = vecTy->getNumElements();
40506122f3e6SDimitry Andric llvm::Type *elemType = vecTy->getElementType();
40512754fe60SDimitry Andric
4052dff0c46cSDimitry Andric llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
40532754fe60SDimitry Andric llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
40542754fe60SDimitry Andric llvm::Value *tmp = Builder.CreateSExt(TestMSB,
40552754fe60SDimitry Andric llvm::VectorType::get(elemType,
40562754fe60SDimitry Andric numElem),
40572754fe60SDimitry Andric "sext");
40582754fe60SDimitry Andric llvm::Value *tmp2 = Builder.CreateNot(tmp);
40592754fe60SDimitry Andric
40602754fe60SDimitry Andric // Cast float to int to perform ANDs if necessary.
40612754fe60SDimitry Andric llvm::Value *RHSTmp = RHS;
40622754fe60SDimitry Andric llvm::Value *LHSTmp = LHS;
40632754fe60SDimitry Andric bool wasCast = false;
40646122f3e6SDimitry Andric llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
40657ae0e2c9SDimitry Andric if (rhsVTy->getElementType()->isFloatingPointTy()) {
40662754fe60SDimitry Andric RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
40672754fe60SDimitry Andric LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
40682754fe60SDimitry Andric wasCast = true;
40692754fe60SDimitry Andric }
40702754fe60SDimitry Andric
40712754fe60SDimitry Andric llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
40722754fe60SDimitry Andric llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
40732754fe60SDimitry Andric llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond");
40742754fe60SDimitry Andric if (wasCast)
40752754fe60SDimitry Andric tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
40762754fe60SDimitry Andric
40772754fe60SDimitry Andric return tmp5;
40782754fe60SDimitry Andric }
4079f22ef01cSRoman Divacky
4080f22ef01cSRoman Divacky // If this is a really simple expression (like x ? 4 : 5), emit this as a
4081f22ef01cSRoman Divacky // select instead of as control flow. We can only do this if it is cheap and
4082f22ef01cSRoman Divacky // safe to evaluate the LHS and RHS unconditionally.
40832754fe60SDimitry Andric if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
40842754fe60SDimitry Andric isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
40852754fe60SDimitry Andric llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
408620e90f04SDimitry Andric llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
408720e90f04SDimitry Andric
408820e90f04SDimitry Andric CGF.incrementProfileCounter(E, StepV);
408920e90f04SDimitry Andric
40902754fe60SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
40912754fe60SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
4092dff0c46cSDimitry Andric if (!LHS) {
4093dff0c46cSDimitry Andric // If the conditional has void type, make sure we return a null Value*.
4094dff0c46cSDimitry Andric assert(!RHS && "LHS and RHS types must match");
409559d1ed5bSDimitry Andric return nullptr;
4096dff0c46cSDimitry Andric }
4097f22ef01cSRoman Divacky return Builder.CreateSelect(CondV, LHS, RHS, "cond");
4098f22ef01cSRoman Divacky }
4099f22ef01cSRoman Divacky
4100f22ef01cSRoman Divacky llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
4101f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
4102f22ef01cSRoman Divacky llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
4103f22ef01cSRoman Divacky
41042754fe60SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
410533956c43SDimitry Andric CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock,
410633956c43SDimitry Andric CGF.getProfileCount(lhsExpr));
4107f22ef01cSRoman Divacky
4108f22ef01cSRoman Divacky CGF.EmitBlock(LHSBlock);
410933956c43SDimitry Andric CGF.incrementProfileCounter(E);
41102754fe60SDimitry Andric eval.begin(CGF);
41112754fe60SDimitry Andric Value *LHS = Visit(lhsExpr);
41122754fe60SDimitry Andric eval.end(CGF);
4113f22ef01cSRoman Divacky
4114f22ef01cSRoman Divacky LHSBlock = Builder.GetInsertBlock();
41152754fe60SDimitry Andric Builder.CreateBr(ContBlock);
4116f22ef01cSRoman Divacky
4117f22ef01cSRoman Divacky CGF.EmitBlock(RHSBlock);
41182754fe60SDimitry Andric eval.begin(CGF);
41192754fe60SDimitry Andric Value *RHS = Visit(rhsExpr);
41202754fe60SDimitry Andric eval.end(CGF);
4121f22ef01cSRoman Divacky
4122f22ef01cSRoman Divacky RHSBlock = Builder.GetInsertBlock();
4123f22ef01cSRoman Divacky CGF.EmitBlock(ContBlock);
4124f22ef01cSRoman Divacky
4125f22ef01cSRoman Divacky // If the LHS or RHS is a throw expression, it will be legitimately null.
4126f22ef01cSRoman Divacky if (!LHS)
4127f22ef01cSRoman Divacky return RHS;
4128f22ef01cSRoman Divacky if (!RHS)
4129f22ef01cSRoman Divacky return LHS;
4130f22ef01cSRoman Divacky
4131f22ef01cSRoman Divacky // Create a PHI node for the real part.
41323b0f4066SDimitry Andric llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond");
4133f22ef01cSRoman Divacky PN->addIncoming(LHS, LHSBlock);
4134f22ef01cSRoman Divacky PN->addIncoming(RHS, RHSBlock);
4135f22ef01cSRoman Divacky return PN;
4136f22ef01cSRoman Divacky }
4137f22ef01cSRoman Divacky
VisitChooseExpr(ChooseExpr * E)4138f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
4139f785676fSDimitry Andric return Visit(E->getChosenSubExpr());
4140f22ef01cSRoman Divacky }
4141f22ef01cSRoman Divacky
VisitVAArgExpr(VAArgExpr * VE)4142f22ef01cSRoman Divacky Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
414359d1ed5bSDimitry Andric QualType Ty = VE->getType();
41449cac79b3SDimitry Andric
414559d1ed5bSDimitry Andric if (Ty->isVariablyModifiedType())
414659d1ed5bSDimitry Andric CGF.EmitVariablyModifiedType(Ty);
414759d1ed5bSDimitry Andric
41480623d748SDimitry Andric Address ArgValue = Address::invalid();
41490623d748SDimitry Andric Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
41500623d748SDimitry Andric
41519cac79b3SDimitry Andric llvm::Type *ArgTy = ConvertType(VE->getType());
4152f22ef01cSRoman Divacky
4153e7145dcbSDimitry Andric // If EmitVAArg fails, emit an error.
4154e7145dcbSDimitry Andric if (!ArgPtr.isValid()) {
4155e7145dcbSDimitry Andric CGF.ErrorUnsupported(VE, "va_arg expression");
4156e7145dcbSDimitry Andric return llvm::UndefValue::get(ArgTy);
4157e7145dcbSDimitry Andric }
4158f22ef01cSRoman Divacky
4159f22ef01cSRoman Divacky // FIXME Volatility.
41609cac79b3SDimitry Andric llvm::Value *Val = Builder.CreateLoad(ArgPtr);
41619cac79b3SDimitry Andric
41629cac79b3SDimitry Andric // If EmitVAArg promoted the type, we must truncate it.
416339d628a0SDimitry Andric if (ArgTy != Val->getType()) {
416439d628a0SDimitry Andric if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
416539d628a0SDimitry Andric Val = Builder.CreateIntToPtr(Val, ArgTy);
416639d628a0SDimitry Andric else
41679cac79b3SDimitry Andric Val = Builder.CreateTrunc(Val, ArgTy);
416839d628a0SDimitry Andric }
41699cac79b3SDimitry Andric
41709cac79b3SDimitry Andric return Val;
4171f22ef01cSRoman Divacky }
4172f22ef01cSRoman Divacky
VisitBlockExpr(const BlockExpr * block)41732754fe60SDimitry Andric Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
41742754fe60SDimitry Andric return CGF.EmitBlockLiteral(block);
4175f22ef01cSRoman Divacky }
4176f22ef01cSRoman Divacky
4177e7145dcbSDimitry Andric // Convert a vec3 to vec4, or vice versa.
ConvertVec3AndVec4(CGBuilderTy & Builder,CodeGenFunction & CGF,Value * Src,unsigned NumElementsDst)4178e7145dcbSDimitry Andric static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF,
4179e7145dcbSDimitry Andric Value *Src, unsigned NumElementsDst) {
4180e7145dcbSDimitry Andric llvm::Value *UnV = llvm::UndefValue::get(Src->getType());
4181e7145dcbSDimitry Andric SmallVector<llvm::Constant*, 4> Args;
4182e7145dcbSDimitry Andric Args.push_back(Builder.getInt32(0));
4183e7145dcbSDimitry Andric Args.push_back(Builder.getInt32(1));
4184e7145dcbSDimitry Andric Args.push_back(Builder.getInt32(2));
4185e7145dcbSDimitry Andric if (NumElementsDst == 4)
4186e7145dcbSDimitry Andric Args.push_back(llvm::UndefValue::get(CGF.Int32Ty));
4187e7145dcbSDimitry Andric llvm::Constant *Mask = llvm::ConstantVector::get(Args);
4188e7145dcbSDimitry Andric return Builder.CreateShuffleVector(Src, UnV, Mask);
4189e7145dcbSDimitry Andric }
4190e7145dcbSDimitry Andric
419144290647SDimitry Andric // Create cast instructions for converting LLVM value \p Src to LLVM type \p
419244290647SDimitry Andric // DstTy. \p Src has the same size as \p DstTy. Both are single value types
419344290647SDimitry Andric // but could be scalar or vectors of different lengths, and either can be
419444290647SDimitry Andric // pointer.
419544290647SDimitry Andric // There are 4 cases:
419644290647SDimitry Andric // 1. non-pointer -> non-pointer : needs 1 bitcast
419744290647SDimitry Andric // 2. pointer -> pointer : needs 1 bitcast or addrspacecast
419844290647SDimitry Andric // 3. pointer -> non-pointer
419944290647SDimitry Andric // a) pointer -> intptr_t : needs 1 ptrtoint
420044290647SDimitry Andric // b) pointer -> non-intptr_t : needs 1 ptrtoint then 1 bitcast
420144290647SDimitry Andric // 4. non-pointer -> pointer
420244290647SDimitry Andric // a) intptr_t -> pointer : needs 1 inttoptr
420344290647SDimitry Andric // b) non-intptr_t -> pointer : needs 1 bitcast then 1 inttoptr
420444290647SDimitry Andric // Note: for cases 3b and 4b two casts are required since LLVM casts do not
420544290647SDimitry Andric // allow casting directly between pointer types and non-integer non-pointer
420644290647SDimitry Andric // types.
createCastsForTypeOfSameSize(CGBuilderTy & Builder,const llvm::DataLayout & DL,Value * Src,llvm::Type * DstTy,StringRef Name="")420744290647SDimitry Andric static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
420844290647SDimitry Andric const llvm::DataLayout &DL,
420944290647SDimitry Andric Value *Src, llvm::Type *DstTy,
421044290647SDimitry Andric StringRef Name = "") {
421144290647SDimitry Andric auto SrcTy = Src->getType();
421244290647SDimitry Andric
421344290647SDimitry Andric // Case 1.
421444290647SDimitry Andric if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
421544290647SDimitry Andric return Builder.CreateBitCast(Src, DstTy, Name);
421644290647SDimitry Andric
421744290647SDimitry Andric // Case 2.
421844290647SDimitry Andric if (SrcTy->isPointerTy() && DstTy->isPointerTy())
421944290647SDimitry Andric return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
422044290647SDimitry Andric
422144290647SDimitry Andric // Case 3.
422244290647SDimitry Andric if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
422344290647SDimitry Andric // Case 3b.
422444290647SDimitry Andric if (!DstTy->isIntegerTy())
422544290647SDimitry Andric Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
422644290647SDimitry Andric // Cases 3a and 3b.
422744290647SDimitry Andric return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
422844290647SDimitry Andric }
422944290647SDimitry Andric
423044290647SDimitry Andric // Case 4b.
423144290647SDimitry Andric if (!SrcTy->isIntegerTy())
423244290647SDimitry Andric Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
423344290647SDimitry Andric // Cases 4a and 4b.
423444290647SDimitry Andric return Builder.CreateIntToPtr(Src, DstTy, Name);
423544290647SDimitry Andric }
423644290647SDimitry Andric
VisitAsTypeExpr(AsTypeExpr * E)4237bd5abe19SDimitry Andric Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
4238bd5abe19SDimitry Andric Value *Src = CGF.EmitScalarExpr(E->getSrcExpr());
42396122f3e6SDimitry Andric llvm::Type *DstTy = ConvertType(E->getType());
4240bd5abe19SDimitry Andric
42416122f3e6SDimitry Andric llvm::Type *SrcTy = Src->getType();
4242e7145dcbSDimitry Andric unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ?
4243e7145dcbSDimitry Andric cast<llvm::VectorType>(SrcTy)->getNumElements() : 0;
4244e7145dcbSDimitry Andric unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ?
4245e7145dcbSDimitry Andric cast<llvm::VectorType>(DstTy)->getNumElements() : 0;
4246bd5abe19SDimitry Andric
4247e7145dcbSDimitry Andric // Going from vec3 to non-vec3 is a special case and requires a shuffle
4248e7145dcbSDimitry Andric // vector to get a vec4, then a bitcast if the target type is different.
4249e7145dcbSDimitry Andric if (NumElementsSrc == 3 && NumElementsDst != 3) {
4250e7145dcbSDimitry Andric Src = ConvertVec3AndVec4(Builder, CGF, Src, 4);
425120e90f04SDimitry Andric
425220e90f04SDimitry Andric if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) {
425344290647SDimitry Andric Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
425444290647SDimitry Andric DstTy);
425520e90f04SDimitry Andric }
425620e90f04SDimitry Andric
4257e7145dcbSDimitry Andric Src->setName("astype");
4258e7145dcbSDimitry Andric return Src;
4259bd5abe19SDimitry Andric }
4260bd5abe19SDimitry Andric
4261e7145dcbSDimitry Andric // Going from non-vec3 to vec3 is a special case and requires a bitcast
4262e7145dcbSDimitry Andric // to vec4 if the original type is not vec4, then a shuffle vector to
4263e7145dcbSDimitry Andric // get a vec3.
4264e7145dcbSDimitry Andric if (NumElementsSrc != 3 && NumElementsDst == 3) {
426520e90f04SDimitry Andric if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) {
4266e7145dcbSDimitry Andric auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4);
426744290647SDimitry Andric Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
426844290647SDimitry Andric Vec4Ty);
426920e90f04SDimitry Andric }
427020e90f04SDimitry Andric
4271e7145dcbSDimitry Andric Src = ConvertVec3AndVec4(Builder, CGF, Src, 3);
4272e7145dcbSDimitry Andric Src->setName("astype");
4273e7145dcbSDimitry Andric return Src;
4274bd5abe19SDimitry Andric }
4275bd5abe19SDimitry Andric
427644290647SDimitry Andric return Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(),
427744290647SDimitry Andric Src, DstTy, "astype");
4278bd5abe19SDimitry Andric }
4279bd5abe19SDimitry Andric
VisitAtomicExpr(AtomicExpr * E)42806122f3e6SDimitry Andric Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
42816122f3e6SDimitry Andric return CGF.EmitAtomicExpr(E).getScalarVal();
42826122f3e6SDimitry Andric }
42836122f3e6SDimitry Andric
4284f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
4285f22ef01cSRoman Divacky // Entry Point into this File
4286f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
4287f22ef01cSRoman Divacky
42880623d748SDimitry Andric /// Emit the computation of the specified expression of scalar type, ignoring
42890623d748SDimitry Andric /// the result.
EmitScalarExpr(const Expr * E,bool IgnoreResultAssign)4290f22ef01cSRoman Divacky Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
4291139f7f9bSDimitry Andric assert(E && hasScalarEvaluationKind(E->getType()) &&
4292f22ef01cSRoman Divacky "Invalid scalar expression to emit");
4293f22ef01cSRoman Divacky
429433956c43SDimitry Andric return ScalarExprEmitter(*this, IgnoreResultAssign)
4295f22ef01cSRoman Divacky .Visit(const_cast<Expr *>(E));
4296f22ef01cSRoman Divacky }
4297f22ef01cSRoman Divacky
42980623d748SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
42990623d748SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)4300f22ef01cSRoman Divacky Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
43010623d748SDimitry Andric QualType DstTy,
43020623d748SDimitry Andric SourceLocation Loc) {
4303139f7f9bSDimitry Andric assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
4304f22ef01cSRoman Divacky "Invalid scalar expression to emit");
43050623d748SDimitry Andric return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
4306f22ef01cSRoman Divacky }
4307f22ef01cSRoman Divacky
43080623d748SDimitry Andric /// Emit a conversion from the specified complex type to the specified
43090623d748SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)4310f22ef01cSRoman Divacky Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
4311f22ef01cSRoman Divacky QualType SrcTy,
43120623d748SDimitry Andric QualType DstTy,
43130623d748SDimitry Andric SourceLocation Loc) {
4314139f7f9bSDimitry Andric assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) &&
4315f22ef01cSRoman Divacky "Invalid complex -> scalar conversion");
43160623d748SDimitry Andric return ScalarExprEmitter(*this)
43170623d748SDimitry Andric .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
4318f22ef01cSRoman Divacky }
4319f22ef01cSRoman Divacky
4320ffd1746dSEd Schouten
4321ffd1746dSEd Schouten llvm::Value *CodeGenFunction::
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)4322ffd1746dSEd Schouten EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
4323ffd1746dSEd Schouten bool isInc, bool isPre) {
4324ffd1746dSEd Schouten return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
4325ffd1746dSEd Schouten }
4326ffd1746dSEd Schouten
EmitObjCIsaExpr(const ObjCIsaExpr * E)4327f22ef01cSRoman Divacky LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
4328f22ef01cSRoman Divacky // object->isa or (*object).isa
4329f22ef01cSRoman Divacky // Generate code as for: *(Class*)object
4330f22ef01cSRoman Divacky
4331f22ef01cSRoman Divacky Expr *BaseExpr = E->getBase();
43320623d748SDimitry Andric Address Addr = Address::invalid();
43332754fe60SDimitry Andric if (BaseExpr->isRValue()) {
43340623d748SDimitry Andric Addr = Address(EmitScalarExpr(BaseExpr), getPointerAlign());
4335e580952dSDimitry Andric } else {
43360623d748SDimitry Andric Addr = EmitLValue(BaseExpr).getAddress();
4337f22ef01cSRoman Divacky }
4338f22ef01cSRoman Divacky
43390623d748SDimitry Andric // Cast the address to Class*.
43400623d748SDimitry Andric Addr = Builder.CreateElementBitCast(Addr, ConvertType(E->getType()));
43410623d748SDimitry Andric return MakeAddrLValue(Addr, E->getType());
4342f22ef01cSRoman Divacky }
4343f22ef01cSRoman Divacky
4344f22ef01cSRoman Divacky
EmitCompoundAssignmentLValue(const CompoundAssignOperator * E)43452754fe60SDimitry Andric LValue CodeGenFunction::EmitCompoundAssignmentLValue(
4346f22ef01cSRoman Divacky const CompoundAssignOperator *E) {
4347f22ef01cSRoman Divacky ScalarExprEmitter Scalar(*this);
434859d1ed5bSDimitry Andric Value *Result = nullptr;
4349f22ef01cSRoman Divacky switch (E->getOpcode()) {
4350f22ef01cSRoman Divacky #define COMPOUND_OP(Op) \
4351e580952dSDimitry Andric case BO_##Op##Assign: \
4352f22ef01cSRoman Divacky return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
4353ffd1746dSEd Schouten Result)
4354f22ef01cSRoman Divacky COMPOUND_OP(Mul);
4355f22ef01cSRoman Divacky COMPOUND_OP(Div);
4356f22ef01cSRoman Divacky COMPOUND_OP(Rem);
4357f22ef01cSRoman Divacky COMPOUND_OP(Add);
4358f22ef01cSRoman Divacky COMPOUND_OP(Sub);
4359f22ef01cSRoman Divacky COMPOUND_OP(Shl);
4360f22ef01cSRoman Divacky COMPOUND_OP(Shr);
4361f22ef01cSRoman Divacky COMPOUND_OP(And);
4362f22ef01cSRoman Divacky COMPOUND_OP(Xor);
4363f22ef01cSRoman Divacky COMPOUND_OP(Or);
4364f22ef01cSRoman Divacky #undef COMPOUND_OP
4365f22ef01cSRoman Divacky
4366e580952dSDimitry Andric case BO_PtrMemD:
4367e580952dSDimitry Andric case BO_PtrMemI:
4368e580952dSDimitry Andric case BO_Mul:
4369e580952dSDimitry Andric case BO_Div:
4370e580952dSDimitry Andric case BO_Rem:
4371e580952dSDimitry Andric case BO_Add:
4372e580952dSDimitry Andric case BO_Sub:
4373e580952dSDimitry Andric case BO_Shl:
4374e580952dSDimitry Andric case BO_Shr:
4375e580952dSDimitry Andric case BO_LT:
4376e580952dSDimitry Andric case BO_GT:
4377e580952dSDimitry Andric case BO_LE:
4378e580952dSDimitry Andric case BO_GE:
4379e580952dSDimitry Andric case BO_EQ:
4380e580952dSDimitry Andric case BO_NE:
43819a199699SDimitry Andric case BO_Cmp:
4382e580952dSDimitry Andric case BO_And:
4383e580952dSDimitry Andric case BO_Xor:
4384e580952dSDimitry Andric case BO_Or:
4385e580952dSDimitry Andric case BO_LAnd:
4386e580952dSDimitry Andric case BO_LOr:
4387e580952dSDimitry Andric case BO_Assign:
4388e580952dSDimitry Andric case BO_Comma:
43896122f3e6SDimitry Andric llvm_unreachable("Not valid compound assignment operators");
4390f22ef01cSRoman Divacky }
4391f22ef01cSRoman Divacky
4392f22ef01cSRoman Divacky llvm_unreachable("Unhandled compound assignment operator");
4393f22ef01cSRoman Divacky }
4394f9448bf3SDimitry Andric
EmitCheckedInBoundsGEP(Value * Ptr,ArrayRef<Value * > IdxList,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,const Twine & Name)4395f9448bf3SDimitry Andric Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr,
4396f9448bf3SDimitry Andric ArrayRef<Value *> IdxList,
439724d58133SDimitry Andric bool SignedIndices,
4398b40b48b8SDimitry Andric bool IsSubtraction,
4399f9448bf3SDimitry Andric SourceLocation Loc,
4400f9448bf3SDimitry Andric const Twine &Name) {
4401f9448bf3SDimitry Andric Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
4402f9448bf3SDimitry Andric
4403f9448bf3SDimitry Andric // If the pointer overflow sanitizer isn't enabled, do nothing.
4404f9448bf3SDimitry Andric if (!SanOpts.has(SanitizerKind::PointerOverflow))
4405f9448bf3SDimitry Andric return GEPVal;
4406f9448bf3SDimitry Andric
4407f9448bf3SDimitry Andric // If the GEP has already been reduced to a constant, leave it be.
4408f9448bf3SDimitry Andric if (isa<llvm::Constant>(GEPVal))
4409f9448bf3SDimitry Andric return GEPVal;
4410f9448bf3SDimitry Andric
4411f9448bf3SDimitry Andric // Only check for overflows in the default address space.
4412f9448bf3SDimitry Andric if (GEPVal->getType()->getPointerAddressSpace())
4413f9448bf3SDimitry Andric return GEPVal;
4414f9448bf3SDimitry Andric
4415f9448bf3SDimitry Andric auto *GEP = cast<llvm::GEPOperator>(GEPVal);
4416f9448bf3SDimitry Andric assert(GEP->isInBounds() && "Expected inbounds GEP");
4417f9448bf3SDimitry Andric
4418f9448bf3SDimitry Andric SanitizerScope SanScope(this);
4419f9448bf3SDimitry Andric auto &VMContext = getLLVMContext();
4420f9448bf3SDimitry Andric const auto &DL = CGM.getDataLayout();
4421f9448bf3SDimitry Andric auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
4422f9448bf3SDimitry Andric
4423f9448bf3SDimitry Andric // Grab references to the signed add/mul overflow intrinsics for intptr_t.
4424f9448bf3SDimitry Andric auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
4425f9448bf3SDimitry Andric auto *SAddIntrinsic =
4426f9448bf3SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
4427f9448bf3SDimitry Andric auto *SMulIntrinsic =
4428f9448bf3SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
4429f9448bf3SDimitry Andric
4430f9448bf3SDimitry Andric // The total (signed) byte offset for the GEP.
4431f9448bf3SDimitry Andric llvm::Value *TotalOffset = nullptr;
4432f9448bf3SDimitry Andric // The offset overflow flag - true if the total offset overflows.
4433f9448bf3SDimitry Andric llvm::Value *OffsetOverflows = Builder.getFalse();
4434f9448bf3SDimitry Andric
4435f9448bf3SDimitry Andric /// Return the result of the given binary operation.
4436f9448bf3SDimitry Andric auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
4437f9448bf3SDimitry Andric llvm::Value *RHS) -> llvm::Value * {
44386d97bb29SDimitry Andric assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop");
4439f9448bf3SDimitry Andric
4440f9448bf3SDimitry Andric // If the operands are constants, return a constant result.
4441f9448bf3SDimitry Andric if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
4442f9448bf3SDimitry Andric if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
4443f9448bf3SDimitry Andric llvm::APInt N;
4444f9448bf3SDimitry Andric bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
4445f9448bf3SDimitry Andric /*Signed=*/true, N);
4446f9448bf3SDimitry Andric if (HasOverflow)
4447f9448bf3SDimitry Andric OffsetOverflows = Builder.getTrue();
4448f9448bf3SDimitry Andric return llvm::ConstantInt::get(VMContext, N);
4449f9448bf3SDimitry Andric }
4450f9448bf3SDimitry Andric }
4451f9448bf3SDimitry Andric
4452f9448bf3SDimitry Andric // Otherwise, compute the result with checked arithmetic.
4453f9448bf3SDimitry Andric auto *ResultAndOverflow = Builder.CreateCall(
4454f9448bf3SDimitry Andric (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
4455f9448bf3SDimitry Andric OffsetOverflows = Builder.CreateOr(
445624d58133SDimitry Andric Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
4457f9448bf3SDimitry Andric return Builder.CreateExtractValue(ResultAndOverflow, 0);
4458f9448bf3SDimitry Andric };
4459f9448bf3SDimitry Andric
4460f9448bf3SDimitry Andric // Determine the total byte offset by looking at each GEP operand.
4461f9448bf3SDimitry Andric for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
4462f9448bf3SDimitry Andric GTI != GTE; ++GTI) {
4463f9448bf3SDimitry Andric llvm::Value *LocalOffset;
4464f9448bf3SDimitry Andric auto *Index = GTI.getOperand();
4465f9448bf3SDimitry Andric // Compute the local offset contributed by this indexing step:
4466f9448bf3SDimitry Andric if (auto *STy = GTI.getStructTypeOrNull()) {
4467f9448bf3SDimitry Andric // For struct indexing, the local offset is the byte position of the
4468f9448bf3SDimitry Andric // specified field.
4469f9448bf3SDimitry Andric unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
4470f9448bf3SDimitry Andric LocalOffset = llvm::ConstantInt::get(
4471f9448bf3SDimitry Andric IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
4472f9448bf3SDimitry Andric } else {
4473f9448bf3SDimitry Andric // Otherwise this is array-like indexing. The local offset is the index
4474f9448bf3SDimitry Andric // multiplied by the element size.
4475f9448bf3SDimitry Andric auto *ElementSize = llvm::ConstantInt::get(
4476f9448bf3SDimitry Andric IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType()));
4477f9448bf3SDimitry Andric auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
4478f9448bf3SDimitry Andric LocalOffset = eval(BO_Mul, ElementSize, IndexS);
4479f9448bf3SDimitry Andric }
4480f9448bf3SDimitry Andric
4481f9448bf3SDimitry Andric // If this is the first offset, set it as the total offset. Otherwise, add
4482f9448bf3SDimitry Andric // the local offset into the running total.
4483f9448bf3SDimitry Andric if (!TotalOffset || TotalOffset == Zero)
4484f9448bf3SDimitry Andric TotalOffset = LocalOffset;
4485f9448bf3SDimitry Andric else
4486f9448bf3SDimitry Andric TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
4487f9448bf3SDimitry Andric }
4488f9448bf3SDimitry Andric
4489f9448bf3SDimitry Andric // Common case: if the total offset is zero, don't emit a check.
4490f9448bf3SDimitry Andric if (TotalOffset == Zero)
4491f9448bf3SDimitry Andric return GEPVal;
4492f9448bf3SDimitry Andric
4493f9448bf3SDimitry Andric // Now that we've computed the total offset, add it to the base pointer (with
4494f9448bf3SDimitry Andric // wrapping semantics).
4495f9448bf3SDimitry Andric auto *IntPtr = Builder.CreatePtrToInt(GEP->getPointerOperand(), IntPtrTy);
4496f9448bf3SDimitry Andric auto *ComputedGEP = Builder.CreateAdd(IntPtr, TotalOffset);
4497f9448bf3SDimitry Andric
4498f9448bf3SDimitry Andric // The GEP is valid if:
4499f9448bf3SDimitry Andric // 1) The total offset doesn't overflow, and
4500f9448bf3SDimitry Andric // 2) The sign of the difference between the computed address and the base
4501f9448bf3SDimitry Andric // pointer matches the sign of the total offset.
450224d58133SDimitry Andric llvm::Value *ValidGEP;
450324d58133SDimitry Andric auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
450424d58133SDimitry Andric if (SignedIndices) {
4505b40b48b8SDimitry Andric auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
4506f9448bf3SDimitry Andric auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
450724d58133SDimitry Andric llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
450824d58133SDimitry Andric ValidGEP = Builder.CreateAnd(
450924d58133SDimitry Andric Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
451024d58133SDimitry Andric NoOffsetOverflow);
4511b40b48b8SDimitry Andric } else if (!SignedIndices && !IsSubtraction) {
4512b40b48b8SDimitry Andric auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
451324d58133SDimitry Andric ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
4514b40b48b8SDimitry Andric } else {
4515b40b48b8SDimitry Andric auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
4516b40b48b8SDimitry Andric ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
451724d58133SDimitry Andric }
4518f9448bf3SDimitry Andric
4519f9448bf3SDimitry Andric llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
4520f9448bf3SDimitry Andric // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
4521f9448bf3SDimitry Andric llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4522f9448bf3SDimitry Andric EmitCheck(std::make_pair(ValidGEP, SanitizerKind::PointerOverflow),
4523f9448bf3SDimitry Andric SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
4524f9448bf3SDimitry Andric
4525f9448bf3SDimitry Andric return GEPVal;
4526f9448bf3SDimitry Andric }
4527