1ec2b103cSEd Schouten //===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
2ec2b103cSEd Schouten //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec2b103cSEd Schouten //
7ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
8ec2b103cSEd Schouten //
9ec2b103cSEd Schouten // This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
10ec2b103cSEd Schouten //
11ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
12ec2b103cSEd Schouten
133d1dcd9bSDimitry Andric #include "CGCXXABI.h"
14676fbe81SDimitry Andric #include "CGCleanup.h"
15809500fcSDimitry Andric #include "CGDebugInfo.h"
164c8b2481SRoman Divacky #include "CGObjCRuntime.h"
17706b4fc4SDimitry Andric #include "CGOpenMPRuntime.h"
18ac9a064cSDimitry Andric #include "CGRecordLayout.h"
19676fbe81SDimitry Andric #include "CodeGenFunction.h"
20ec2b103cSEd Schouten #include "CodeGenModule.h"
2122989816SDimitry Andric #include "ConstantEmitter.h"
22c192b3dcSDimitry Andric #include "TargetInfo.h"
23ec2b103cSEd Schouten #include "clang/AST/ASTContext.h"
24706b4fc4SDimitry Andric #include "clang/AST/Attr.h"
25ec2b103cSEd Schouten #include "clang/AST/DeclObjC.h"
26bab175ecSDimitry Andric #include "clang/AST/Expr.h"
27ec2b103cSEd Schouten #include "clang/AST/RecordLayout.h"
28ec2b103cSEd Schouten #include "clang/AST/StmtVisitor.h"
29676fbe81SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
30ec2b103cSEd Schouten #include "clang/Basic/TargetInfo.h"
31b60736ecSDimitry Andric #include "llvm/ADT/APFixedPoint.h"
329f4dbff6SDimitry Andric #include "llvm/IR/CFG.h"
33809500fcSDimitry Andric #include "llvm/IR/Constants.h"
34809500fcSDimitry Andric #include "llvm/IR/DataLayout.h"
35145449b1SDimitry Andric #include "llvm/IR/DerivedTypes.h"
36b60736ecSDimitry Andric #include "llvm/IR/FixedPointBuilder.h"
37809500fcSDimitry Andric #include "llvm/IR/Function.h"
38416ada0fSDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
39809500fcSDimitry Andric #include "llvm/IR/GlobalVariable.h"
40809500fcSDimitry Andric #include "llvm/IR/Intrinsics.h"
41706b4fc4SDimitry Andric #include "llvm/IR/IntrinsicsPowerPC.h"
42cfca06d7SDimitry Andric #include "llvm/IR/MatrixBuilder.h"
43809500fcSDimitry Andric #include "llvm/IR/Module.h"
44145449b1SDimitry Andric #include "llvm/Support/TypeSize.h"
45ec2b103cSEd Schouten #include <cstdarg>
46e3b55780SDimitry Andric #include <optional>
47ec2b103cSEd Schouten
48ec2b103cSEd Schouten using namespace clang;
49ec2b103cSEd Schouten using namespace CodeGen;
50ec2b103cSEd Schouten using llvm::Value;
51ec2b103cSEd Schouten
52ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
53ec2b103cSEd Schouten // Scalar Expression Emitter
54ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
55ec2b103cSEd Schouten
56ac9a064cSDimitry Andric namespace llvm {
57ac9a064cSDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage;
58ac9a064cSDimitry Andric } // namespace llvm
59ac9a064cSDimitry Andric
60bca07a45SDimitry Andric namespace {
61416ada0fSDimitry Andric
62416ada0fSDimitry Andric /// Determine whether the given binary operation may overflow.
63416ada0fSDimitry Andric /// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
64416ada0fSDimitry Andric /// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
65416ada0fSDimitry Andric /// the returned overflow check is precise. The returned value is 'true' for
66416ada0fSDimitry Andric /// all other opcodes, to be conservative.
mayHaveIntegerOverflow(llvm::ConstantInt * LHS,llvm::ConstantInt * RHS,BinaryOperator::Opcode Opcode,bool Signed,llvm::APInt & Result)67416ada0fSDimitry Andric bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
68416ada0fSDimitry Andric BinaryOperator::Opcode Opcode, bool Signed,
69416ada0fSDimitry Andric llvm::APInt &Result) {
70416ada0fSDimitry Andric // Assume overflow is possible, unless we can prove otherwise.
71416ada0fSDimitry Andric bool Overflow = true;
72416ada0fSDimitry Andric const auto &LHSAP = LHS->getValue();
73416ada0fSDimitry Andric const auto &RHSAP = RHS->getValue();
74416ada0fSDimitry Andric if (Opcode == BO_Add) {
75145449b1SDimitry Andric Result = Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
76145449b1SDimitry Andric : LHSAP.uadd_ov(RHSAP, Overflow);
77416ada0fSDimitry Andric } else if (Opcode == BO_Sub) {
78145449b1SDimitry Andric Result = Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
79145449b1SDimitry Andric : LHSAP.usub_ov(RHSAP, Overflow);
80416ada0fSDimitry Andric } else if (Opcode == BO_Mul) {
81145449b1SDimitry Andric Result = Signed ? LHSAP.smul_ov(RHSAP, Overflow)
82145449b1SDimitry Andric : LHSAP.umul_ov(RHSAP, Overflow);
83416ada0fSDimitry Andric } else if (Opcode == BO_Div || Opcode == BO_Rem) {
84416ada0fSDimitry Andric if (Signed && !RHS->isZero())
85416ada0fSDimitry Andric Result = LHSAP.sdiv_ov(RHSAP, Overflow);
86416ada0fSDimitry Andric else
87416ada0fSDimitry Andric return false;
88416ada0fSDimitry Andric }
89416ada0fSDimitry Andric return Overflow;
90416ada0fSDimitry Andric }
91416ada0fSDimitry Andric
92ec2b103cSEd Schouten struct BinOpInfo {
93ec2b103cSEd Schouten Value *LHS;
94ec2b103cSEd Schouten Value *RHS;
95ec2b103cSEd Schouten QualType Ty; // Computation Type.
964ba67500SRoman Divacky BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
977442d6faSDimitry Andric FPOptions FPFeatures;
984ba67500SRoman Divacky const Expr *E; // Entire expr, for error unsupported. May not be binop.
99f0c0337bSDimitry Andric
100f0c0337bSDimitry Andric /// Check if the binop can result in integer overflow.
mayHaveIntegerOverflow__anon258b33720111::BinOpInfo101f0c0337bSDimitry Andric bool mayHaveIntegerOverflow() const {
102f0c0337bSDimitry Andric // Without constant input, we can't rule out overflow.
103416ada0fSDimitry Andric auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
104416ada0fSDimitry Andric auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
105f0c0337bSDimitry Andric if (!LHSCI || !RHSCI)
106f0c0337bSDimitry Andric return true;
107f0c0337bSDimitry Andric
108416ada0fSDimitry Andric llvm::APInt Result;
109416ada0fSDimitry Andric return ::mayHaveIntegerOverflow(
110416ada0fSDimitry Andric LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result);
111f0c0337bSDimitry Andric }
112f0c0337bSDimitry Andric
113f0c0337bSDimitry Andric /// Check if the binop computes a division or a remainder.
isDivremOp__anon258b33720111::BinOpInfo1142410013dSDimitry Andric bool isDivremOp() const {
115f0c0337bSDimitry Andric return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
116f0c0337bSDimitry Andric Opcode == BO_RemAssign;
117f0c0337bSDimitry Andric }
118f0c0337bSDimitry Andric
119f0c0337bSDimitry Andric /// Check if the binop can result in an integer division by zero.
mayHaveIntegerDivisionByZero__anon258b33720111::BinOpInfo120f0c0337bSDimitry Andric bool mayHaveIntegerDivisionByZero() const {
1212410013dSDimitry Andric if (isDivremOp())
122f0c0337bSDimitry Andric if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
123f0c0337bSDimitry Andric return CI->isZero();
124f0c0337bSDimitry Andric return true;
125f0c0337bSDimitry Andric }
126f0c0337bSDimitry Andric
127f0c0337bSDimitry Andric /// Check if the binop can result in a float division by zero.
mayHaveFloatDivisionByZero__anon258b33720111::BinOpInfo128f0c0337bSDimitry Andric bool mayHaveFloatDivisionByZero() const {
1292410013dSDimitry Andric if (isDivremOp())
130f0c0337bSDimitry Andric if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
131f0c0337bSDimitry Andric return CFP->isZero();
132f0c0337bSDimitry Andric return true;
133f0c0337bSDimitry Andric }
13422989816SDimitry Andric
135cfca06d7SDimitry Andric /// Check if at least one operand is a fixed point type. In such cases, this
136cfca06d7SDimitry Andric /// operation did not follow usual arithmetic conversion and both operands
137cfca06d7SDimitry Andric /// might not be of the same type.
isFixedPointOp__anon258b33720111::BinOpInfo138cfca06d7SDimitry Andric bool isFixedPointOp() const {
13922989816SDimitry Andric // We cannot simply check the result type since comparison operations return
14022989816SDimitry Andric // an int.
14122989816SDimitry Andric if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
14222989816SDimitry Andric QualType LHSType = BinOp->getLHS()->getType();
14322989816SDimitry Andric QualType RHSType = BinOp->getRHS()->getType();
14422989816SDimitry Andric return LHSType->isFixedPointType() || RHSType->isFixedPointType();
14522989816SDimitry Andric }
146cfca06d7SDimitry Andric if (const auto *UnOp = dyn_cast<UnaryOperator>(E))
147cfca06d7SDimitry Andric return UnOp->getSubExpr()->getType()->isFixedPointType();
14822989816SDimitry Andric return false;
14922989816SDimitry Andric }
150ac9a064cSDimitry Andric
151ac9a064cSDimitry Andric /// Check if the RHS has a signed integer representation.
rhsHasSignedIntegerRepresentation__anon258b33720111::BinOpInfo152ac9a064cSDimitry Andric bool rhsHasSignedIntegerRepresentation() const {
153ac9a064cSDimitry Andric if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
154ac9a064cSDimitry Andric QualType RHSType = BinOp->getRHS()->getType();
155ac9a064cSDimitry Andric return RHSType->hasSignedIntegerRepresentation();
156ac9a064cSDimitry Andric }
157ac9a064cSDimitry Andric return false;
158ac9a064cSDimitry Andric }
159ec2b103cSEd Schouten };
160ec2b103cSEd Schouten
MustVisitNullValue(const Expr * E)161bca07a45SDimitry Andric static bool MustVisitNullValue(const Expr *E) {
162bca07a45SDimitry Andric // If a null pointer expression's type is the C++0x nullptr_t, then
163bca07a45SDimitry Andric // it's not necessarily a simple constant and it must be evaluated
164bca07a45SDimitry Andric // for its potential side effects.
165bca07a45SDimitry Andric return E->getType()->isNullPtrType();
166bca07a45SDimitry Andric }
167bca07a45SDimitry Andric
1687442d6faSDimitry Andric /// If \p E is a widened promoted integer, get its base (unpromoted) type.
getUnwidenedIntegerType(const ASTContext & Ctx,const Expr * E)169e3b55780SDimitry Andric static std::optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
1707442d6faSDimitry Andric const Expr *E) {
1717442d6faSDimitry Andric const Expr *Base = E->IgnoreImpCasts();
1727442d6faSDimitry Andric if (E == Base)
173e3b55780SDimitry Andric return std::nullopt;
1747442d6faSDimitry Andric
1757442d6faSDimitry Andric QualType BaseTy = Base->getType();
176e3b55780SDimitry Andric if (!Ctx.isPromotableIntegerType(BaseTy) ||
1777442d6faSDimitry Andric Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
178e3b55780SDimitry Andric return std::nullopt;
1797442d6faSDimitry Andric
1807442d6faSDimitry Andric return BaseTy;
1817442d6faSDimitry Andric }
1827442d6faSDimitry Andric
1837442d6faSDimitry Andric /// Check if \p E is a widened promoted integer.
IsWidenedIntegerOp(const ASTContext & Ctx,const Expr * E)1847442d6faSDimitry Andric static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
185145449b1SDimitry Andric return getUnwidenedIntegerType(Ctx, E).has_value();
1867442d6faSDimitry Andric }
1877442d6faSDimitry Andric
1887442d6faSDimitry Andric /// Check if we can skip the overflow check for \p Op.
CanElideOverflowCheck(const ASTContext & Ctx,const BinOpInfo & Op)1897442d6faSDimitry Andric static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
1907442d6faSDimitry Andric assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
1917442d6faSDimitry Andric "Expected a unary or binary operator");
1927442d6faSDimitry Andric
193f0c0337bSDimitry Andric // If the binop has constant inputs and we can prove there is no overflow,
194f0c0337bSDimitry Andric // we can elide the overflow check.
195f0c0337bSDimitry Andric if (!Op.mayHaveIntegerOverflow())
196f0c0337bSDimitry Andric return true;
197f0c0337bSDimitry Andric
198f0c0337bSDimitry Andric // If a unary op has a widened operand, the op cannot overflow.
1997442d6faSDimitry Andric if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
20048675466SDimitry Andric return !UO->canOverflow();
2017442d6faSDimitry Andric
202f0c0337bSDimitry Andric // We usually don't need overflow checks for binops with widened operands.
203f0c0337bSDimitry Andric // Multiplication with promoted unsigned operands is a special case.
2047442d6faSDimitry Andric const auto *BO = cast<BinaryOperator>(Op.E);
2057442d6faSDimitry Andric auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
2067442d6faSDimitry Andric if (!OptionalLHSTy)
2077442d6faSDimitry Andric return false;
2087442d6faSDimitry Andric
2097442d6faSDimitry Andric auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
2107442d6faSDimitry Andric if (!OptionalRHSTy)
2117442d6faSDimitry Andric return false;
2127442d6faSDimitry Andric
2137442d6faSDimitry Andric QualType LHSTy = *OptionalLHSTy;
2147442d6faSDimitry Andric QualType RHSTy = *OptionalRHSTy;
2157442d6faSDimitry Andric
216f0c0337bSDimitry Andric // This is the simple case: binops without unsigned multiplication, and with
217f0c0337bSDimitry Andric // widened operands. No overflow check is needed here.
2187442d6faSDimitry Andric if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
2197442d6faSDimitry Andric !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
2207442d6faSDimitry Andric return true;
2217442d6faSDimitry Andric
222f0c0337bSDimitry Andric // For unsigned multiplication the overflow check can be elided if either one
223f0c0337bSDimitry Andric // of the unpromoted types are less than half the size of the promoted type.
2247442d6faSDimitry Andric unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
2257442d6faSDimitry Andric return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
2267442d6faSDimitry Andric (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
2277442d6faSDimitry Andric }
2287442d6faSDimitry Andric
2291569ce68SRoman Divacky class ScalarExprEmitter
230ec2b103cSEd Schouten : public StmtVisitor<ScalarExprEmitter, Value*> {
231ec2b103cSEd Schouten CodeGenFunction &CGF;
232ec2b103cSEd Schouten CGBuilderTy &Builder;
233ec2b103cSEd Schouten bool IgnoreResultAssign;
2344c8b2481SRoman Divacky llvm::LLVMContext &VMContext;
235ec2b103cSEd Schouten public:
236ec2b103cSEd Schouten
ScalarExprEmitter(CodeGenFunction & cgf,bool ira=false)237ec2b103cSEd Schouten ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false)
2384c8b2481SRoman Divacky : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
2394c8b2481SRoman Divacky VMContext(cgf.getLLVMContext()) {
240ec2b103cSEd Schouten }
241ec2b103cSEd Schouten
242ec2b103cSEd Schouten //===--------------------------------------------------------------------===//
243ec2b103cSEd Schouten // Utilities
244ec2b103cSEd Schouten //===--------------------------------------------------------------------===//
245ec2b103cSEd Schouten
TestAndClearIgnoreResultAssign()246ec2b103cSEd Schouten bool TestAndClearIgnoreResultAssign() {
2474c8b2481SRoman Divacky bool I = IgnoreResultAssign;
2484c8b2481SRoman Divacky IgnoreResultAssign = false;
2494c8b2481SRoman Divacky return I;
2504c8b2481SRoman Divacky }
251ec2b103cSEd Schouten
ConvertType(QualType T)25236981b17SDimitry Andric llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
EmitLValue(const Expr * E)253ec2b103cSEd Schouten LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
EmitCheckedLValue(const Expr * E,CodeGenFunction::TypeCheckKind TCK)25413cc256eSDimitry Andric LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
25513cc256eSDimitry Andric return CGF.EmitCheckedLValue(E, TCK);
25613cc256eSDimitry Andric }
25713cc256eSDimitry Andric
2585e20cdd8SDimitry Andric void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
25906d4ba38SDimitry Andric const BinOpInfo &Info);
260ec2b103cSEd Schouten
EmitLoadOfLValue(LValue LV,SourceLocation Loc)261bfef3995SDimitry Andric Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
262bfef3995SDimitry Andric return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
263ec2b103cSEd Schouten }
264ec2b103cSEd Schouten
EmitLValueAlignmentAssumption(const Expr * E,Value * V)26506d4ba38SDimitry Andric void EmitLValueAlignmentAssumption(const Expr *E, Value *V) {
26606d4ba38SDimitry Andric const AlignValueAttr *AVAttr = nullptr;
26706d4ba38SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
26806d4ba38SDimitry Andric const ValueDecl *VD = DRE->getDecl();
26906d4ba38SDimitry Andric
27006d4ba38SDimitry Andric if (VD->getType()->isReferenceType()) {
27106d4ba38SDimitry Andric if (const auto *TTy =
272e3b55780SDimitry Andric VD->getType().getNonReferenceType()->getAs<TypedefType>())
27306d4ba38SDimitry Andric AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
27406d4ba38SDimitry Andric } else {
27506d4ba38SDimitry Andric // Assumptions for function parameters are emitted at the start of the
276676fbe81SDimitry Andric // function, so there is no need to repeat that here,
277676fbe81SDimitry Andric // unless the alignment-assumption sanitizer is enabled,
278676fbe81SDimitry Andric // then we prefer the assumption over alignment attribute
279676fbe81SDimitry Andric // on IR function param.
280676fbe81SDimitry Andric if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment))
28106d4ba38SDimitry Andric return;
28206d4ba38SDimitry Andric
28306d4ba38SDimitry Andric AVAttr = VD->getAttr<AlignValueAttr>();
28406d4ba38SDimitry Andric }
28506d4ba38SDimitry Andric }
28606d4ba38SDimitry Andric
28706d4ba38SDimitry Andric if (!AVAttr)
288e3b55780SDimitry Andric if (const auto *TTy = E->getType()->getAs<TypedefType>())
28906d4ba38SDimitry Andric AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
29006d4ba38SDimitry Andric
29106d4ba38SDimitry Andric if (!AVAttr)
29206d4ba38SDimitry Andric return;
29306d4ba38SDimitry Andric
29406d4ba38SDimitry Andric Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
29506d4ba38SDimitry Andric llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
296cfca06d7SDimitry Andric CGF.emitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI);
29706d4ba38SDimitry Andric }
29806d4ba38SDimitry Andric
299ec2b103cSEd Schouten /// EmitLoadOfLValue - Given an expression with complex type that represents a
300ec2b103cSEd Schouten /// value l-value, this method emits the address of the l-value, then loads
301ec2b103cSEd Schouten /// and returns the result.
EmitLoadOfLValue(const Expr * E)302ec2b103cSEd Schouten Value *EmitLoadOfLValue(const Expr *E) {
30306d4ba38SDimitry Andric Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
304bfef3995SDimitry Andric E->getExprLoc());
30506d4ba38SDimitry Andric
30606d4ba38SDimitry Andric EmitLValueAlignmentAssumption(E, V);
30706d4ba38SDimitry Andric return V;
308ec2b103cSEd Schouten }
309ec2b103cSEd Schouten
310ec2b103cSEd Schouten /// EmitConversionToBool - Convert the specified expression value to a
311ec2b103cSEd Schouten /// boolean (i1) truth value. This is equivalent to "Val != 0".
312ec2b103cSEd Schouten Value *EmitConversionToBool(Value *Src, QualType DstTy);
313ec2b103cSEd Schouten
31422989816SDimitry Andric /// Emit a check that a conversion from a floating-point type does not
31545b53394SDimitry Andric /// overflow.
31613cc256eSDimitry Andric void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
31745b53394SDimitry Andric Value *Src, QualType SrcType, QualType DstType,
31845b53394SDimitry Andric llvm::Type *DstTy, SourceLocation Loc);
31913cc256eSDimitry Andric
320c7e70c43SDimitry Andric /// Known implicit conversion check kinds.
321ac9a064cSDimitry Andric /// This is used for bitfield conversion checks as well.
322c7e70c43SDimitry Andric /// Keep in sync with the enum of the same name in ubsan_handlers.h
323c7e70c43SDimitry Andric enum ImplicitConversionCheckKind : unsigned char {
324676fbe81SDimitry Andric ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
325676fbe81SDimitry Andric ICCK_UnsignedIntegerTruncation = 1,
326676fbe81SDimitry Andric ICCK_SignedIntegerTruncation = 2,
327676fbe81SDimitry Andric ICCK_IntegerSignChange = 3,
328676fbe81SDimitry Andric ICCK_SignedIntegerTruncationOrSignChange = 4,
329c7e70c43SDimitry Andric };
330c7e70c43SDimitry Andric
331c7e70c43SDimitry Andric /// Emit a check that an [implicit] truncation of an integer does not
332c7e70c43SDimitry Andric /// discard any bits. It is not UB, so we use the value after truncation.
333c7e70c43SDimitry Andric void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst,
334c7e70c43SDimitry Andric QualType DstType, SourceLocation Loc);
335c7e70c43SDimitry Andric
336676fbe81SDimitry Andric /// Emit a check that an [implicit] conversion of an integer does not change
337676fbe81SDimitry Andric /// the sign of the value. It is not UB, so we use the value after conversion.
338676fbe81SDimitry Andric /// NOTE: Src and Dst may be the exact same value! (point to the same thing)
339676fbe81SDimitry Andric void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
340676fbe81SDimitry Andric QualType DstType, SourceLocation Loc);
341676fbe81SDimitry Andric
34245b53394SDimitry Andric /// Emit a conversion from the specified type to the specified destination
34345b53394SDimitry Andric /// type, both of which are LLVM scalar types.
344c7e70c43SDimitry Andric struct ScalarConversionOpts {
345c7e70c43SDimitry Andric bool TreatBooleanAsSigned;
346c7e70c43SDimitry Andric bool EmitImplicitIntegerTruncationChecks;
347676fbe81SDimitry Andric bool EmitImplicitIntegerSignChangeChecks;
348ec2b103cSEd Schouten
ScalarConversionOpts__anon258b33720111::ScalarExprEmitter::ScalarConversionOpts349c7e70c43SDimitry Andric ScalarConversionOpts()
350c7e70c43SDimitry Andric : TreatBooleanAsSigned(false),
351676fbe81SDimitry Andric EmitImplicitIntegerTruncationChecks(false),
352676fbe81SDimitry Andric EmitImplicitIntegerSignChangeChecks(false) {}
353676fbe81SDimitry Andric
ScalarConversionOpts__anon258b33720111::ScalarExprEmitter::ScalarConversionOpts354676fbe81SDimitry Andric ScalarConversionOpts(clang::SanitizerSet SanOpts)
355676fbe81SDimitry Andric : TreatBooleanAsSigned(false),
356676fbe81SDimitry Andric EmitImplicitIntegerTruncationChecks(
357676fbe81SDimitry Andric SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
358676fbe81SDimitry Andric EmitImplicitIntegerSignChangeChecks(
359676fbe81SDimitry Andric SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {}
360c7e70c43SDimitry Andric };
361344a3780SDimitry Andric Value *EmitScalarCast(Value *Src, QualType SrcType, QualType DstType,
362344a3780SDimitry Andric llvm::Type *SrcTy, llvm::Type *DstTy,
363344a3780SDimitry Andric ScalarConversionOpts Opts);
364c7e70c43SDimitry Andric Value *
365c7e70c43SDimitry Andric EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
366c7e70c43SDimitry Andric SourceLocation Loc,
367c7e70c43SDimitry Andric ScalarConversionOpts Opts = ScalarConversionOpts());
36845b53394SDimitry Andric
36922989816SDimitry Andric /// Convert between either a fixed point and other fixed point or fixed point
37022989816SDimitry Andric /// and an integer.
371676fbe81SDimitry Andric Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy,
372676fbe81SDimitry Andric SourceLocation Loc);
373676fbe81SDimitry Andric
37445b53394SDimitry Andric /// Emit a conversion from the specified complex type to the specified
37545b53394SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
376ec2b103cSEd Schouten Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
37745b53394SDimitry Andric QualType SrcTy, QualType DstTy,
37845b53394SDimitry Andric SourceLocation Loc);
379ec2b103cSEd Schouten
380d7279c4cSRoman Divacky /// EmitNullValue - Emit a value that corresponds to null for the given type.
381d7279c4cSRoman Divacky Value *EmitNullValue(QualType Ty);
382d7279c4cSRoman Divacky
383bca07a45SDimitry Andric /// EmitFloatToBoolConversion - Perform an FP to boolean conversion.
EmitFloatToBoolConversion(Value * V)384bca07a45SDimitry Andric Value *EmitFloatToBoolConversion(Value *V) {
385bca07a45SDimitry Andric // Compare against 0.0 for fp scalars.
386bca07a45SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
387bca07a45SDimitry Andric return Builder.CreateFCmpUNE(V, Zero, "tobool");
388bca07a45SDimitry Andric }
389bca07a45SDimitry Andric
390bca07a45SDimitry Andric /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion.
EmitPointerToBoolConversion(Value * V,QualType QT)391bab175ecSDimitry Andric Value *EmitPointerToBoolConversion(Value *V, QualType QT) {
392bab175ecSDimitry Andric Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT);
393bab175ecSDimitry Andric
394bca07a45SDimitry Andric return Builder.CreateICmpNE(V, Zero, "tobool");
395bca07a45SDimitry Andric }
396bca07a45SDimitry Andric
EmitIntToBoolConversion(Value * V)397bca07a45SDimitry Andric Value *EmitIntToBoolConversion(Value *V) {
398bca07a45SDimitry Andric // Because of the type rules of C, we often end up computing a
399bca07a45SDimitry Andric // logical value, then zero extending it to int, then wanting it
400bca07a45SDimitry Andric // as a logical value again. Optimize this common case.
401bca07a45SDimitry Andric if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
402bca07a45SDimitry Andric if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
403bca07a45SDimitry Andric Value *Result = ZI->getOperand(0);
404bca07a45SDimitry Andric // If there aren't any more uses, zap the instruction to save space.
405bca07a45SDimitry Andric // Note that there can be more uses, for example if this
406bca07a45SDimitry Andric // is the result of an assignment.
407bca07a45SDimitry Andric if (ZI->use_empty())
408bca07a45SDimitry Andric ZI->eraseFromParent();
409bca07a45SDimitry Andric return Result;
410bca07a45SDimitry Andric }
411bca07a45SDimitry Andric }
412bca07a45SDimitry Andric
41301af97d3SDimitry Andric return Builder.CreateIsNotNull(V, "tobool");
414bca07a45SDimitry Andric }
415bca07a45SDimitry Andric
416ec2b103cSEd Schouten //===--------------------------------------------------------------------===//
417ec2b103cSEd Schouten // Visitor Methods
418ec2b103cSEd Schouten //===--------------------------------------------------------------------===//
419ec2b103cSEd Schouten
Visit(Expr * E)420bca07a45SDimitry Andric Value *Visit(Expr *E) {
4215e20cdd8SDimitry Andric ApplyDebugLocation DL(CGF, E);
422bca07a45SDimitry Andric return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
423bca07a45SDimitry Andric }
424bca07a45SDimitry Andric
VisitStmt(Stmt * S)425ec2b103cSEd Schouten Value *VisitStmt(Stmt *S) {
426cfca06d7SDimitry Andric S->dump(llvm::errs(), CGF.getContext());
42736981b17SDimitry Andric llvm_unreachable("Stmt can't have complex result type!");
428ec2b103cSEd Schouten }
429ec2b103cSEd Schouten Value *VisitExpr(Expr *S);
43073490b89SRoman Divacky
VisitConstantExpr(ConstantExpr * E)431676fbe81SDimitry Andric Value *VisitConstantExpr(ConstantExpr *E) {
432c0981da4SDimitry Andric // A constant expression of type 'void' generates no code and produces no
433c0981da4SDimitry Andric // value.
434c0981da4SDimitry Andric if (E->getType()->isVoidType())
435c0981da4SDimitry Andric return nullptr;
436c0981da4SDimitry Andric
437cfca06d7SDimitry Andric if (Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
438cfca06d7SDimitry Andric if (E->isGLValue())
439ac9a064cSDimitry Andric return CGF.EmitLoadOfScalar(
440ac9a064cSDimitry Andric Address(Result, CGF.convertTypeForLoadStore(E->getType()),
441ac9a064cSDimitry Andric CGF.getContext().getTypeAlignInChars(E->getType())),
442ac9a064cSDimitry Andric /*Volatile*/ false, E->getType(), E->getExprLoc());
443cfca06d7SDimitry Andric return Result;
444cfca06d7SDimitry Andric }
445676fbe81SDimitry Andric return Visit(E->getSubExpr());
446676fbe81SDimitry Andric }
VisitParenExpr(ParenExpr * PE)447bca07a45SDimitry Andric Value *VisitParenExpr(ParenExpr *PE) {
448bca07a45SDimitry Andric return Visit(PE->getSubExpr());
449bca07a45SDimitry Andric }
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)450180abc3dSDimitry Andric Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
451180abc3dSDimitry Andric return Visit(E->getReplacement());
452180abc3dSDimitry Andric }
VisitGenericSelectionExpr(GenericSelectionExpr * GE)45301af97d3SDimitry Andric Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
45401af97d3SDimitry Andric return Visit(GE->getResultExpr());
45501af97d3SDimitry Andric }
VisitCoawaitExpr(CoawaitExpr * S)4567442d6faSDimitry Andric Value *VisitCoawaitExpr(CoawaitExpr *S) {
4577442d6faSDimitry Andric return CGF.EmitCoawaitExpr(*S).getScalarVal();
4587442d6faSDimitry Andric }
VisitCoyieldExpr(CoyieldExpr * S)4597442d6faSDimitry Andric Value *VisitCoyieldExpr(CoyieldExpr *S) {
4607442d6faSDimitry Andric return CGF.EmitCoyieldExpr(*S).getScalarVal();
4617442d6faSDimitry Andric }
VisitUnaryCoawait(const UnaryOperator * E)4627442d6faSDimitry Andric Value *VisitUnaryCoawait(const UnaryOperator *E) {
4637442d6faSDimitry Andric return Visit(E->getSubExpr());
4647442d6faSDimitry Andric }
465ec2b103cSEd Schouten
466ec2b103cSEd Schouten // Leaves.
VisitIntegerLiteral(const IntegerLiteral * E)467ec2b103cSEd Schouten Value *VisitIntegerLiteral(const IntegerLiteral *E) {
46801af97d3SDimitry Andric return Builder.getInt(E->getValue());
469ec2b103cSEd Schouten }
VisitFixedPointLiteral(const FixedPointLiteral * E)47048675466SDimitry Andric Value *VisitFixedPointLiteral(const FixedPointLiteral *E) {
47148675466SDimitry Andric return Builder.getInt(E->getValue());
47248675466SDimitry Andric }
VisitFloatingLiteral(const FloatingLiteral * E)473ec2b103cSEd Schouten Value *VisitFloatingLiteral(const FloatingLiteral *E) {
4744c8b2481SRoman Divacky return llvm::ConstantFP::get(VMContext, E->getValue());
475ec2b103cSEd Schouten }
VisitCharacterLiteral(const CharacterLiteral * E)476ec2b103cSEd Schouten Value *VisitCharacterLiteral(const CharacterLiteral *E) {
477ec2b103cSEd Schouten return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
478ec2b103cSEd Schouten }
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * E)479dbe13110SDimitry Andric Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
480dbe13110SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
481dbe13110SDimitry Andric }
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * E)482ec2b103cSEd Schouten Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
483ec2b103cSEd Schouten return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
484ec2b103cSEd Schouten }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)4854ba67500SRoman Divacky Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
486e3b55780SDimitry Andric if (E->getType()->isVoidType())
487e3b55780SDimitry Andric return nullptr;
488e3b55780SDimitry Andric
489d7279c4cSRoman Divacky return EmitNullValue(E->getType());
490ec2b103cSEd Schouten }
VisitGNUNullExpr(const GNUNullExpr * E)491ec2b103cSEd Schouten Value *VisitGNUNullExpr(const GNUNullExpr *E) {
492d7279c4cSRoman Divacky return EmitNullValue(E->getType());
493ec2b103cSEd Schouten }
4943d1dcd9bSDimitry Andric Value *VisitOffsetOfExpr(OffsetOfExpr *E);
49501af97d3SDimitry Andric Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
VisitAddrLabelExpr(const AddrLabelExpr * E)496ec2b103cSEd Schouten Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
49751fb8b01SRoman Divacky llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
49851fb8b01SRoman Divacky return Builder.CreateBitCast(V, ConvertType(E->getType()));
499ec2b103cSEd Schouten }
500ec2b103cSEd Schouten
VisitSizeOfPackExpr(SizeOfPackExpr * E)501bca07a45SDimitry Andric Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
50201af97d3SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength());
503bca07a45SDimitry Andric }
504bca07a45SDimitry Andric
VisitPseudoObjectExpr(PseudoObjectExpr * E)505dbe13110SDimitry Andric Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
506dbe13110SDimitry Andric return CGF.EmitPseudoObjectRValue(E).getScalarVal();
507dbe13110SDimitry Andric }
508dbe13110SDimitry Andric
509344a3780SDimitry Andric Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
510ac9a064cSDimitry Andric Value *VisitEmbedExpr(EmbedExpr *E);
511344a3780SDimitry Andric
VisitOpaqueValueExpr(OpaqueValueExpr * E)512bca07a45SDimitry Andric Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
513bca07a45SDimitry Andric if (E->isGLValue())
51448675466SDimitry Andric return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E),
51548675466SDimitry Andric E->getExprLoc());
516bca07a45SDimitry Andric
517bca07a45SDimitry Andric // Otherwise, assume the mapping is the scalar directly.
51848675466SDimitry Andric return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal();
519bca07a45SDimitry Andric }
520bca07a45SDimitry Andric
521ec2b103cSEd Schouten // l-values.
VisitDeclRefExpr(DeclRefExpr * E)522ec2b103cSEd Schouten Value *VisitDeclRefExpr(DeclRefExpr *E) {
523461a67faSDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
524676fbe81SDimitry Andric return CGF.emitScalarConstant(Constant, E);
525ec2b103cSEd Schouten return EmitLoadOfLValue(E);
526bca07a45SDimitry Andric }
527bca07a45SDimitry Andric
VisitObjCSelectorExpr(ObjCSelectorExpr * E)528ec2b103cSEd Schouten Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
529ec2b103cSEd Schouten return CGF.EmitObjCSelectorExpr(E);
530ec2b103cSEd Schouten }
VisitObjCProtocolExpr(ObjCProtocolExpr * E)531ec2b103cSEd Schouten Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
532ec2b103cSEd Schouten return CGF.EmitObjCProtocolExpr(E);
533ec2b103cSEd Schouten }
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)534ec2b103cSEd Schouten Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
535ec2b103cSEd Schouten return EmitLoadOfLValue(E);
536ec2b103cSEd Schouten }
VisitObjCMessageExpr(ObjCMessageExpr * E)537ec2b103cSEd Schouten Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
53801af97d3SDimitry Andric if (E->getMethodDecl() &&
5399f4dbff6SDimitry Andric E->getMethodDecl()->getReturnType()->isReferenceType())
54001af97d3SDimitry Andric return EmitLoadOfLValue(E);
541ec2b103cSEd Schouten return CGF.EmitObjCMessageExpr(E).getScalarVal();
542ec2b103cSEd Schouten }
543ec2b103cSEd Schouten
VisitObjCIsaExpr(ObjCIsaExpr * E)54434d02d0bSRoman Divacky Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
54534d02d0bSRoman Divacky LValue LV = CGF.EmitObjCIsaExpr(E);
546bfef3995SDimitry Andric Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal();
54734d02d0bSRoman Divacky return V;
54834d02d0bSRoman Divacky }
54934d02d0bSRoman Divacky
VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * E)5507442d6faSDimitry Andric Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
5517442d6faSDimitry Andric VersionTuple Version = E->getVersion();
5527442d6faSDimitry Andric
5537442d6faSDimitry Andric // If we're checking for a platform older than our minimum deployment
5547442d6faSDimitry Andric // target, we can fold the check away.
5557442d6faSDimitry Andric if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
5567442d6faSDimitry Andric return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
5577442d6faSDimitry Andric
558b60736ecSDimitry Andric return CGF.EmitBuiltinAvailable(Version);
5597442d6faSDimitry Andric }
5607442d6faSDimitry Andric
561ec2b103cSEd Schouten Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
562cfca06d7SDimitry Andric Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
563ec2b103cSEd Schouten Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
564bfef3995SDimitry Andric Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
5651569ce68SRoman Divacky Value *VisitMemberExpr(MemberExpr *E);
VisitExtVectorElementExpr(Expr * E)566ec2b103cSEd Schouten Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)567ec2b103cSEd Schouten Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
568cfca06d7SDimitry Andric // Strictly speaking, we shouldn't be calling EmitLoadOfLValue, which
569cfca06d7SDimitry Andric // transitively calls EmitCompoundLiteralLValue, here in C++ since compound
570cfca06d7SDimitry Andric // literals aren't l-values in C++. We do so simply because that's the
571cfca06d7SDimitry Andric // cleanest way to handle compound literals in C++.
572cfca06d7SDimitry Andric // See the discussion here: https://reviews.llvm.org/D64464
573ec2b103cSEd Schouten return EmitLoadOfLValue(E);
574ec2b103cSEd Schouten }
575ec2b103cSEd Schouten
57673490b89SRoman Divacky Value *VisitInitListExpr(InitListExpr *E);
577ec2b103cSEd Schouten
VisitArrayInitIndexExpr(ArrayInitIndexExpr * E)578bab175ecSDimitry Andric Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
579bab175ecSDimitry Andric assert(CGF.getArrayInitIndex() &&
580bab175ecSDimitry Andric "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
581bab175ecSDimitry Andric return CGF.getArrayInitIndex();
582bab175ecSDimitry Andric }
583bab175ecSDimitry Andric
VisitImplicitValueInitExpr(const ImplicitValueInitExpr * E)584ec2b103cSEd Schouten Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
585809500fcSDimitry Andric return EmitNullValue(E->getType());
586ec2b103cSEd Schouten }
VisitExplicitCastExpr(ExplicitCastExpr * E)587180abc3dSDimitry Andric Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
58845b53394SDimitry Andric CGF.CGM.EmitExplicitCastExprType(E, &CGF);
589180abc3dSDimitry Andric return VisitCastExpr(E);
590ec2b103cSEd Schouten }
591180abc3dSDimitry Andric Value *VisitCastExpr(CastExpr *E);
592ec2b103cSEd Schouten
VisitCallExpr(const CallExpr * E)593ec2b103cSEd Schouten Value *VisitCallExpr(const CallExpr *E) {
5945e20cdd8SDimitry Andric if (E->getCallReturnType(CGF.getContext())->isReferenceType())
595ec2b103cSEd Schouten return EmitLoadOfLValue(E);
596ec2b103cSEd Schouten
59706d4ba38SDimitry Andric Value *V = CGF.EmitCallExpr(E).getScalarVal();
59806d4ba38SDimitry Andric
59906d4ba38SDimitry Andric EmitLValueAlignmentAssumption(E, V);
60006d4ba38SDimitry Andric return V;
601ec2b103cSEd Schouten }
602ec2b103cSEd Schouten
603ec2b103cSEd Schouten Value *VisitStmtExpr(const StmtExpr *E);
604ec2b103cSEd Schouten
605ec2b103cSEd Schouten // Unary Operators.
VisitUnaryPostDec(const UnaryOperator * E)606ec2b103cSEd Schouten Value *VisitUnaryPostDec(const UnaryOperator *E) {
6074ba67500SRoman Divacky LValue LV = EmitLValue(E->getSubExpr());
6084ba67500SRoman Divacky return EmitScalarPrePostIncDec(E, LV, false, false);
609ec2b103cSEd Schouten }
VisitUnaryPostInc(const UnaryOperator * E)610ec2b103cSEd Schouten Value *VisitUnaryPostInc(const UnaryOperator *E) {
6114ba67500SRoman Divacky LValue LV = EmitLValue(E->getSubExpr());
6124ba67500SRoman Divacky return EmitScalarPrePostIncDec(E, LV, true, false);
613ec2b103cSEd Schouten }
VisitUnaryPreDec(const UnaryOperator * E)614ec2b103cSEd Schouten Value *VisitUnaryPreDec(const UnaryOperator *E) {
6154ba67500SRoman Divacky LValue LV = EmitLValue(E->getSubExpr());
6164ba67500SRoman Divacky return EmitScalarPrePostIncDec(E, LV, false, true);
617ec2b103cSEd Schouten }
VisitUnaryPreInc(const UnaryOperator * E)618ec2b103cSEd Schouten Value *VisitUnaryPreInc(const UnaryOperator *E) {
6194ba67500SRoman Divacky LValue LV = EmitLValue(E->getSubExpr());
6204ba67500SRoman Divacky return EmitScalarPrePostIncDec(E, LV, true, true);
621ec2b103cSEd Schouten }
6224ba67500SRoman Divacky
6235e20cdd8SDimitry Andric llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E,
624bca07a45SDimitry Andric llvm::Value *InVal,
625bca07a45SDimitry Andric bool IsInc);
626bca07a45SDimitry Andric
6274ba67500SRoman Divacky llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
6284ba67500SRoman Divacky bool isInc, bool isPre);
6294ba67500SRoman Divacky
6304ba67500SRoman Divacky
VisitUnaryAddrOf(const UnaryOperator * E)631ec2b103cSEd Schouten Value *VisitUnaryAddrOf(const UnaryOperator *E) {
632bca07a45SDimitry Andric if (isa<MemberPointerType>(E->getType())) // never sugared
633bca07a45SDimitry Andric return CGF.CGM.getMemberPointerConstant(E);
634bca07a45SDimitry Andric
635706b4fc4SDimitry Andric return EmitLValue(E->getSubExpr()).getPointer(CGF);
636ec2b103cSEd Schouten }
VisitUnaryDeref(const UnaryOperator * E)637bca07a45SDimitry Andric Value *VisitUnaryDeref(const UnaryOperator *E) {
638bca07a45SDimitry Andric if (E->getType()->isVoidType())
639bca07a45SDimitry Andric return Visit(E->getSubExpr()); // the actual value should be unused
640bca07a45SDimitry Andric return EmitLoadOfLValue(E);
641bca07a45SDimitry Andric }
642e3b55780SDimitry Andric
643e3b55780SDimitry Andric Value *VisitUnaryPlus(const UnaryOperator *E,
644e3b55780SDimitry Andric QualType PromotionType = QualType());
645e3b55780SDimitry Andric Value *VisitPlus(const UnaryOperator *E, QualType PromotionType);
646e3b55780SDimitry Andric Value *VisitUnaryMinus(const UnaryOperator *E,
647e3b55780SDimitry Andric QualType PromotionType = QualType());
648e3b55780SDimitry Andric Value *VisitMinus(const UnaryOperator *E, QualType PromotionType);
649e3b55780SDimitry Andric
650ec2b103cSEd Schouten Value *VisitUnaryNot (const UnaryOperator *E);
651ec2b103cSEd Schouten Value *VisitUnaryLNot (const UnaryOperator *E);
652e3b55780SDimitry Andric Value *VisitUnaryReal(const UnaryOperator *E,
653e3b55780SDimitry Andric QualType PromotionType = QualType());
654e3b55780SDimitry Andric Value *VisitReal(const UnaryOperator *E, QualType PromotionType);
655e3b55780SDimitry Andric Value *VisitUnaryImag(const UnaryOperator *E,
656e3b55780SDimitry Andric QualType PromotionType = QualType());
657e3b55780SDimitry Andric Value *VisitImag(const UnaryOperator *E, QualType PromotionType);
VisitUnaryExtension(const UnaryOperator * E)658ec2b103cSEd Schouten Value *VisitUnaryExtension(const UnaryOperator *E) {
659ec2b103cSEd Schouten return Visit(E->getSubExpr());
660ec2b103cSEd Schouten }
661ec2b103cSEd Schouten
662ec2b103cSEd Schouten // C++
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * E)66336981b17SDimitry Andric Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {
66436981b17SDimitry Andric return EmitLoadOfLValue(E);
66536981b17SDimitry Andric }
VisitSourceLocExpr(SourceLocExpr * SLE)66622989816SDimitry Andric Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
66722989816SDimitry Andric auto &Ctx = CGF.getContext();
66822989816SDimitry Andric APValue Evaluated =
66922989816SDimitry Andric SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr());
670706b4fc4SDimitry Andric return ConstantEmitter(CGF).emitAbstract(SLE->getLocation(), Evaluated,
671706b4fc4SDimitry Andric SLE->getType());
67222989816SDimitry Andric }
67336981b17SDimitry Andric
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)674ec2b103cSEd Schouten Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
67522989816SDimitry Andric CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
676ec2b103cSEd Schouten return Visit(DAE->getExpr());
677ec2b103cSEd Schouten }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)6786a037251SDimitry Andric Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
67922989816SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
6806a037251SDimitry Andric return Visit(DIE->getExpr());
6816a037251SDimitry Andric }
VisitCXXThisExpr(CXXThisExpr * TE)682ec2b103cSEd Schouten Value *VisitCXXThisExpr(CXXThisExpr *TE) {
683ec2b103cSEd Schouten return CGF.LoadCXXThis();
684ec2b103cSEd Schouten }
685ec2b103cSEd Schouten
6867442d6faSDimitry Andric Value *VisitExprWithCleanups(ExprWithCleanups *E);
VisitCXXNewExpr(const CXXNewExpr * E)687ec2b103cSEd Schouten Value *VisitCXXNewExpr(const CXXNewExpr *E) {
688ec2b103cSEd Schouten return CGF.EmitCXXNewExpr(E);
689ec2b103cSEd Schouten }
VisitCXXDeleteExpr(const CXXDeleteExpr * E)6904c8b2481SRoman Divacky Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
6914c8b2481SRoman Divacky CGF.EmitCXXDeleteExpr(E);
6929f4dbff6SDimitry Andric return nullptr;
693bca07a45SDimitry Andric }
694bca07a45SDimitry Andric
VisitTypeTraitExpr(const TypeTraitExpr * E)6959f4dbff6SDimitry Andric Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
696bca07a45SDimitry Andric return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
69734d02d0bSRoman Divacky }
6984c8b2481SRoman Divacky
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * E)699519fc96cSDimitry Andric Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
700519fc96cSDimitry Andric return Builder.getInt1(E->isSatisfied());
701519fc96cSDimitry Andric }
702519fc96cSDimitry Andric
VisitRequiresExpr(const RequiresExpr * E)703cfca06d7SDimitry Andric Value *VisitRequiresExpr(const RequiresExpr *E) {
704cfca06d7SDimitry Andric return Builder.getInt1(E->isSatisfied());
705cfca06d7SDimitry Andric }
706cfca06d7SDimitry Andric
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)70701af97d3SDimitry Andric Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
70801af97d3SDimitry Andric return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
70901af97d3SDimitry Andric }
71001af97d3SDimitry Andric
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)71101af97d3SDimitry Andric Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
71201af97d3SDimitry Andric return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
71301af97d3SDimitry Andric }
71401af97d3SDimitry Andric
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)7154c8b2481SRoman Divacky Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) {
7164c8b2481SRoman Divacky // C++ [expr.pseudo]p1:
7174c8b2481SRoman Divacky // The result shall only be used as the operand for the function call
7184c8b2481SRoman Divacky // operator (), and the result of such a call has type void. The only
7194c8b2481SRoman Divacky // effect is the evaluation of the postfix-expression before the dot or
7204c8b2481SRoman Divacky // arrow.
7214c8b2481SRoman Divacky CGF.EmitScalarExpr(E->getBase());
7229f4dbff6SDimitry Andric return nullptr;
7234c8b2481SRoman Divacky }
7244c8b2481SRoman Divacky
VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr * E)7254c8b2481SRoman Divacky Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
726d7279c4cSRoman Divacky return EmitNullValue(E->getType());
7274c8b2481SRoman Divacky }
728ec2b103cSEd Schouten
VisitCXXThrowExpr(const CXXThrowExpr * E)72951fb8b01SRoman Divacky Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
73051fb8b01SRoman Divacky CGF.EmitCXXThrowExpr(E);
7319f4dbff6SDimitry Andric return nullptr;
73251fb8b01SRoman Divacky }
73351fb8b01SRoman Divacky
VisitCXXNoexceptExpr(const CXXNoexceptExpr * E)734bca07a45SDimitry Andric Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
73501af97d3SDimitry Andric return Builder.getInt1(E->getValue());
736bca07a45SDimitry Andric }
737bca07a45SDimitry Andric
738ec2b103cSEd Schouten // Binary Operators.
EmitMul(const BinOpInfo & Ops)739ec2b103cSEd Schouten Value *EmitMul(const BinOpInfo &Ops) {
74029cafa66SDimitry Andric if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
74113cc256eSDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
7424ba67500SRoman Divacky case LangOptions::SOB_Defined:
743ac9a064cSDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
7444ba67500SRoman Divacky return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
745ac9a064cSDimitry Andric [[fallthrough]];
74613cc256eSDimitry Andric case LangOptions::SOB_Undefined:
74706d4ba38SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
74813cc256eSDimitry Andric return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
749e3b55780SDimitry Andric [[fallthrough]];
7504ba67500SRoman Divacky case LangOptions::SOB_Trapping:
7517442d6faSDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), Ops))
7527442d6faSDimitry Andric return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
753ec2b103cSEd Schouten return EmitOverflowCheckedBinOp(Ops);
7544ba67500SRoman Divacky }
7554ba67500SRoman Divacky }
7564ba67500SRoman Divacky
757cfca06d7SDimitry Andric if (Ops.Ty->isConstantMatrixType()) {
758145449b1SDimitry Andric llvm::MatrixBuilder MB(Builder);
759cfca06d7SDimitry Andric // We need to check the types of the operands of the operator to get the
760cfca06d7SDimitry Andric // correct matrix dimensions.
761cfca06d7SDimitry Andric auto *BO = cast<BinaryOperator>(Ops.E);
762cfca06d7SDimitry Andric auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
763cfca06d7SDimitry Andric BO->getLHS()->getType().getCanonicalType());
764cfca06d7SDimitry Andric auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
765cfca06d7SDimitry Andric BO->getRHS()->getType().getCanonicalType());
766344a3780SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
767cfca06d7SDimitry Andric if (LHSMatTy && RHSMatTy)
768cfca06d7SDimitry Andric return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
769cfca06d7SDimitry Andric LHSMatTy->getNumColumns(),
770cfca06d7SDimitry Andric RHSMatTy->getNumColumns());
771cfca06d7SDimitry Andric return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
772cfca06d7SDimitry Andric }
773cfca06d7SDimitry Andric
77406d4ba38SDimitry Andric if (Ops.Ty->isUnsignedIntegerType() &&
7757442d6faSDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
7767442d6faSDimitry Andric !CanElideOverflowCheck(CGF.getContext(), Ops))
777809500fcSDimitry Andric return EmitOverflowCheckedBinOp(Ops);
778809500fcSDimitry Andric
7797442d6faSDimitry Andric if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
780cfca06d7SDimitry Andric // Preserve the old values
781cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
782cfca06d7SDimitry Andric return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
7837442d6faSDimitry Andric }
784cfca06d7SDimitry Andric if (Ops.isFixedPointOp())
785cfca06d7SDimitry Andric return EmitFixedPointBinOp(Ops);
786ec2b103cSEd Schouten return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
787ec2b103cSEd Schouten }
788ec2b103cSEd Schouten /// Create a binary op that checks for overflow.
789ec2b103cSEd Schouten /// Currently only supports +, - and *.
790ec2b103cSEd Schouten Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
79113cc256eSDimitry Andric
792bca07a45SDimitry Andric // Check for undefined division and modulus behaviors.
793bca07a45SDimitry Andric void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,
794bca07a45SDimitry Andric llvm::Value *Zero,bool isDiv);
795809500fcSDimitry Andric // Common helper for getting how wide LHS of shift is.
796ac9a064cSDimitry Andric static Value *GetMaximumShiftAmount(Value *LHS, Value *RHS, bool RHSIsSigned);
797cfca06d7SDimitry Andric
798cfca06d7SDimitry Andric // Used for shifting constraints for OpenCL, do mask for powers of 2, URem for
799cfca06d7SDimitry Andric // non powers of two.
800cfca06d7SDimitry Andric Value *ConstrainShiftValue(Value *LHS, Value *RHS, const Twine &Name);
801cfca06d7SDimitry Andric
802ec2b103cSEd Schouten Value *EmitDiv(const BinOpInfo &Ops);
803ec2b103cSEd Schouten Value *EmitRem(const BinOpInfo &Ops);
804ec2b103cSEd Schouten Value *EmitAdd(const BinOpInfo &Ops);
805ec2b103cSEd Schouten Value *EmitSub(const BinOpInfo &Ops);
806ec2b103cSEd Schouten Value *EmitShl(const BinOpInfo &Ops);
807ec2b103cSEd Schouten Value *EmitShr(const BinOpInfo &Ops);
EmitAnd(const BinOpInfo & Ops)808ec2b103cSEd Schouten Value *EmitAnd(const BinOpInfo &Ops) {
809ec2b103cSEd Schouten return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
810ec2b103cSEd Schouten }
EmitXor(const BinOpInfo & Ops)811ec2b103cSEd Schouten Value *EmitXor(const BinOpInfo &Ops) {
812ec2b103cSEd Schouten return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
813ec2b103cSEd Schouten }
EmitOr(const BinOpInfo & Ops)814ec2b103cSEd Schouten Value *EmitOr (const BinOpInfo &Ops) {
815ec2b103cSEd Schouten return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
816ec2b103cSEd Schouten }
817ec2b103cSEd Schouten
81822989816SDimitry Andric // Helper functions for fixed point binary operations.
81922989816SDimitry Andric Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
82022989816SDimitry Andric
821e3b55780SDimitry Andric BinOpInfo EmitBinOps(const BinaryOperator *E,
822e3b55780SDimitry Andric QualType PromotionTy = QualType());
823e3b55780SDimitry Andric
824e3b55780SDimitry Andric Value *EmitPromotedValue(Value *result, QualType PromotionType);
825e3b55780SDimitry Andric Value *EmitUnPromotedValue(Value *result, QualType ExprType);
826e3b55780SDimitry Andric Value *EmitPromoted(const Expr *E, QualType PromotionType);
827e3b55780SDimitry Andric
8280883ccd9SRoman Divacky LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
8290883ccd9SRoman Divacky Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
8304ba67500SRoman Divacky Value *&Result);
8310883ccd9SRoman Divacky
832ec2b103cSEd Schouten Value *EmitCompoundAssign(const CompoundAssignOperator *E,
833ec2b103cSEd Schouten Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
834ec2b103cSEd Schouten
getPromotionType(QualType Ty)835e3b55780SDimitry Andric QualType getPromotionType(QualType Ty) {
8367fa27ce4SDimitry Andric const auto &Ctx = CGF.getContext();
837e3b55780SDimitry Andric if (auto *CT = Ty->getAs<ComplexType>()) {
838e3b55780SDimitry Andric QualType ElementType = CT->getElementType();
8397fa27ce4SDimitry Andric if (ElementType.UseExcessPrecision(Ctx))
8407fa27ce4SDimitry Andric return Ctx.getComplexType(Ctx.FloatTy);
841e3b55780SDimitry Andric }
8427fa27ce4SDimitry Andric
8437fa27ce4SDimitry Andric if (Ty.UseExcessPrecision(Ctx)) {
8447fa27ce4SDimitry Andric if (auto *VT = Ty->getAs<VectorType>()) {
8457fa27ce4SDimitry Andric unsigned NumElements = VT->getNumElements();
8467fa27ce4SDimitry Andric return Ctx.getVectorType(Ctx.FloatTy, NumElements, VT->getVectorKind());
8477fa27ce4SDimitry Andric }
8487fa27ce4SDimitry Andric return Ctx.FloatTy;
8497fa27ce4SDimitry Andric }
8507fa27ce4SDimitry Andric
851e3b55780SDimitry Andric return QualType();
852e3b55780SDimitry Andric }
853e3b55780SDimitry Andric
854ec2b103cSEd Schouten // Binary operators and binary compound assignment operators.
855ec2b103cSEd Schouten #define HANDLEBINOP(OP) \
856ec2b103cSEd Schouten Value *VisitBin##OP(const BinaryOperator *E) { \
857e3b55780SDimitry Andric QualType promotionTy = getPromotionType(E->getType()); \
858e3b55780SDimitry Andric auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
859e3b55780SDimitry Andric if (result && !promotionTy.isNull()) \
860e3b55780SDimitry Andric result = EmitUnPromotedValue(result, E->getType()); \
861e3b55780SDimitry Andric return result; \
862ec2b103cSEd Schouten } \
863ec2b103cSEd Schouten Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
864ec2b103cSEd Schouten return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
865ec2b103cSEd Schouten }
866abe15e55SRoman Divacky HANDLEBINOP(Mul)
867abe15e55SRoman Divacky HANDLEBINOP(Div)
868abe15e55SRoman Divacky HANDLEBINOP(Rem)
869abe15e55SRoman Divacky HANDLEBINOP(Add)
870abe15e55SRoman Divacky HANDLEBINOP(Sub)
871abe15e55SRoman Divacky HANDLEBINOP(Shl)
872abe15e55SRoman Divacky HANDLEBINOP(Shr)
873abe15e55SRoman Divacky HANDLEBINOP(And)
874abe15e55SRoman Divacky HANDLEBINOP(Xor)
875abe15e55SRoman Divacky HANDLEBINOP(Or)
876ec2b103cSEd Schouten #undef HANDLEBINOP
877ec2b103cSEd Schouten
878ec2b103cSEd Schouten // Comparisons.
87945b53394SDimitry Andric Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc,
88045b53394SDimitry Andric llvm::CmpInst::Predicate SICmpOpc,
881706b4fc4SDimitry Andric llvm::CmpInst::Predicate FCmpOpc, bool IsSignaling);
882706b4fc4SDimitry Andric #define VISITCOMP(CODE, UI, SI, FP, SIG) \
883ec2b103cSEd Schouten Value *VisitBin##CODE(const BinaryOperator *E) { \
884ec2b103cSEd Schouten return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
885706b4fc4SDimitry Andric llvm::FCmpInst::FP, SIG); }
886706b4fc4SDimitry Andric VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT, true)
887706b4fc4SDimitry Andric VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT, true)
888706b4fc4SDimitry Andric VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE, true)
889706b4fc4SDimitry Andric VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE, true)
890706b4fc4SDimitry Andric VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ, false)
891706b4fc4SDimitry Andric VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE, false)
892ec2b103cSEd Schouten #undef VISITCOMP
893ec2b103cSEd Schouten
894ec2b103cSEd Schouten Value *VisitBinAssign (const BinaryOperator *E);
895ec2b103cSEd Schouten
896ec2b103cSEd Schouten Value *VisitBinLAnd (const BinaryOperator *E);
897ec2b103cSEd Schouten Value *VisitBinLOr (const BinaryOperator *E);
898ec2b103cSEd Schouten Value *VisitBinComma (const BinaryOperator *E);
899ec2b103cSEd Schouten
VisitBinPtrMemD(const Expr * E)900b3d5a323SRoman Divacky Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
VisitBinPtrMemI(const Expr * E)901b3d5a323SRoman Divacky Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
902b3d5a323SRoman Divacky
VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator * E)903519fc96cSDimitry Andric Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
904519fc96cSDimitry Andric return Visit(E->getSemanticForm());
905519fc96cSDimitry Andric }
906519fc96cSDimitry Andric
907ec2b103cSEd Schouten // Other Operators.
908ec2b103cSEd Schouten Value *VisitBlockExpr(const BlockExpr *BE);
909bca07a45SDimitry Andric Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *);
910ec2b103cSEd Schouten Value *VisitChooseExpr(ChooseExpr *CE);
911ec2b103cSEd Schouten Value *VisitVAArgExpr(VAArgExpr *VE);
VisitObjCStringLiteral(const ObjCStringLiteral * E)912ec2b103cSEd Schouten Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
913ec2b103cSEd Schouten return CGF.EmitObjCStringLiteral(E);
914ec2b103cSEd Schouten }
VisitObjCBoxedExpr(ObjCBoxedExpr * E)91556d91b49SDimitry Andric Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
91656d91b49SDimitry Andric return CGF.EmitObjCBoxedExpr(E);
917dbe13110SDimitry Andric }
VisitObjCArrayLiteral(ObjCArrayLiteral * E)918dbe13110SDimitry Andric Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
919dbe13110SDimitry Andric return CGF.EmitObjCArrayLiteral(E);
920dbe13110SDimitry Andric }
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)921dbe13110SDimitry Andric Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
922dbe13110SDimitry Andric return CGF.EmitObjCDictionaryLiteral(E);
923dbe13110SDimitry Andric }
92429cafa66SDimitry Andric Value *VisitAsTypeExpr(AsTypeExpr *CE);
92536981b17SDimitry Andric Value *VisitAtomicExpr(AtomicExpr *AE);
VisitPackIndexingExpr(PackIndexingExpr * E)926ac9a064cSDimitry Andric Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
927ac9a064cSDimitry Andric return Visit(E->getSelectedExpr());
928ac9a064cSDimitry Andric }
929ec2b103cSEd Schouten };
930ec2b103cSEd Schouten } // end anonymous namespace.
931ec2b103cSEd Schouten
932ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
933ec2b103cSEd Schouten // Utilities
934ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
935ec2b103cSEd Schouten
936ec2b103cSEd Schouten /// EmitConversionToBool - Convert the specified expression value to a
937ec2b103cSEd Schouten /// boolean (i1) truth value. This is equivalent to "Val != 0".
EmitConversionToBool(Value * Src,QualType SrcType)938ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
93973490b89SRoman Divacky assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
940ec2b103cSEd Schouten
941bca07a45SDimitry Andric if (SrcType->isRealFloatingType())
942bca07a45SDimitry Andric return EmitFloatToBoolConversion(Src);
943ec2b103cSEd Schouten
9443d1dcd9bSDimitry Andric if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
9453d1dcd9bSDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT);
9464c8b2481SRoman Divacky
947ec2b103cSEd Schouten assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
948ec2b103cSEd Schouten "Unknown scalar type to convert");
949ec2b103cSEd Schouten
950bca07a45SDimitry Andric if (isa<llvm::IntegerType>(Src->getType()))
951bca07a45SDimitry Andric return EmitIntToBoolConversion(Src);
952ec2b103cSEd Schouten
953bca07a45SDimitry Andric assert(isa<llvm::PointerType>(Src->getType()));
954bab175ecSDimitry Andric return EmitPointerToBoolConversion(Src, SrcType);
955ec2b103cSEd Schouten }
956ec2b103cSEd Schouten
EmitFloatConversionCheck(Value * OrigSrc,QualType OrigSrcType,Value * Src,QualType SrcType,QualType DstType,llvm::Type * DstTy,SourceLocation Loc)95745b53394SDimitry Andric void ScalarExprEmitter::EmitFloatConversionCheck(
95845b53394SDimitry Andric Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
95945b53394SDimitry Andric QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
96022989816SDimitry Andric assert(SrcType->isFloatingType() && "not a conversion from floating point");
96122989816SDimitry Andric if (!isa<llvm::IntegerType>(DstTy))
96222989816SDimitry Andric return;
96322989816SDimitry Andric
9649f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
96513cc256eSDimitry Andric using llvm::APFloat;
96613cc256eSDimitry Andric using llvm::APSInt;
96713cc256eSDimitry Andric
9689f4dbff6SDimitry Andric llvm::Value *Check = nullptr;
96913cc256eSDimitry Andric const llvm::fltSemantics &SrcSema =
97013cc256eSDimitry Andric CGF.getContext().getFloatTypeSemantics(OrigSrcType);
97122989816SDimitry Andric
972809500fcSDimitry Andric // Floating-point to integer. This has undefined behavior if the source is
973809500fcSDimitry Andric // +-Inf, NaN, or doesn't fit into the destination type (after truncation
974809500fcSDimitry Andric // to an integer).
97513cc256eSDimitry Andric unsigned Width = CGF.getContext().getIntWidth(DstType);
97613cc256eSDimitry Andric bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
97713cc256eSDimitry Andric
97813cc256eSDimitry Andric APSInt Min = APSInt::getMinValue(Width, Unsigned);
979809500fcSDimitry Andric APFloat MinSrc(SrcSema, APFloat::uninitialized);
98013cc256eSDimitry Andric if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
98113cc256eSDimitry Andric APFloat::opOverflow)
98213cc256eSDimitry Andric // Don't need an overflow check for lower bound. Just check for
98313cc256eSDimitry Andric // -Inf/NaN.
984809500fcSDimitry Andric MinSrc = APFloat::getInf(SrcSema, true);
985809500fcSDimitry Andric else
986809500fcSDimitry Andric // Find the largest value which is too small to represent (before
987809500fcSDimitry Andric // truncation toward zero).
988809500fcSDimitry Andric MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
98913cc256eSDimitry Andric
99013cc256eSDimitry Andric APSInt Max = APSInt::getMaxValue(Width, Unsigned);
991809500fcSDimitry Andric APFloat MaxSrc(SrcSema, APFloat::uninitialized);
99213cc256eSDimitry Andric if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
99313cc256eSDimitry Andric APFloat::opOverflow)
99413cc256eSDimitry Andric // Don't need an overflow check for upper bound. Just check for
99513cc256eSDimitry Andric // +Inf/NaN.
996809500fcSDimitry Andric MaxSrc = APFloat::getInf(SrcSema, false);
997809500fcSDimitry Andric else
998809500fcSDimitry Andric // Find the smallest value which is too large to represent (before
999809500fcSDimitry Andric // truncation toward zero).
1000809500fcSDimitry Andric MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
100113cc256eSDimitry Andric
100213cc256eSDimitry Andric // If we're converting from __half, convert the range to float to match
100313cc256eSDimitry Andric // the type of src.
100413cc256eSDimitry Andric if (OrigSrcType->isHalfType()) {
100513cc256eSDimitry Andric const llvm::fltSemantics &Sema =
100613cc256eSDimitry Andric CGF.getContext().getFloatTypeSemantics(SrcType);
100713cc256eSDimitry Andric bool IsInexact;
100813cc256eSDimitry Andric MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
100913cc256eSDimitry Andric MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
101013cc256eSDimitry Andric }
101113cc256eSDimitry Andric
101213cc256eSDimitry Andric llvm::Value *GE =
1013809500fcSDimitry Andric Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
101413cc256eSDimitry Andric llvm::Value *LE =
1015809500fcSDimitry Andric Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
101613cc256eSDimitry Andric Check = Builder.CreateAnd(GE, LE);
101713cc256eSDimitry Andric
101845b53394SDimitry Andric llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
101913cc256eSDimitry Andric CGF.EmitCheckTypeDescriptor(OrigSrcType),
102045b53394SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType)};
102106d4ba38SDimitry Andric CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
1022bab175ecSDimitry Andric SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
102313cc256eSDimitry Andric }
102413cc256eSDimitry Andric
1025676fbe81SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
1026676fbe81SDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
1027676fbe81SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1028676fbe81SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)1029676fbe81SDimitry Andric EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
1030676fbe81SDimitry Andric QualType DstType, CGBuilderTy &Builder) {
1031676fbe81SDimitry Andric llvm::Type *SrcTy = Src->getType();
1032676fbe81SDimitry Andric llvm::Type *DstTy = Dst->getType();
1033676fbe81SDimitry Andric (void)DstTy; // Only used in assert()
1034676fbe81SDimitry Andric
1035676fbe81SDimitry Andric // This should be truncation of integral types.
1036676fbe81SDimitry Andric assert(Src != Dst);
1037676fbe81SDimitry Andric assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
1038676fbe81SDimitry Andric assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1039676fbe81SDimitry Andric "non-integer llvm type");
1040676fbe81SDimitry Andric
1041676fbe81SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1042676fbe81SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1043676fbe81SDimitry Andric
1044676fbe81SDimitry Andric // If both (src and dst) types are unsigned, then it's an unsigned truncation.
1045676fbe81SDimitry Andric // Else, it is a signed truncation.
1046676fbe81SDimitry Andric ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1047676fbe81SDimitry Andric SanitizerMask Mask;
1048676fbe81SDimitry Andric if (!SrcSigned && !DstSigned) {
1049676fbe81SDimitry Andric Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1050676fbe81SDimitry Andric Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
1051676fbe81SDimitry Andric } else {
1052676fbe81SDimitry Andric Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1053676fbe81SDimitry Andric Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
1054676fbe81SDimitry Andric }
1055676fbe81SDimitry Andric
1056676fbe81SDimitry Andric llvm::Value *Check = nullptr;
1057676fbe81SDimitry Andric // 1. Extend the truncated value back to the same width as the Src.
1058676fbe81SDimitry Andric Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext");
1059676fbe81SDimitry Andric // 2. Equality-compare with the original source value
1060676fbe81SDimitry Andric Check = Builder.CreateICmpEQ(Check, Src, "truncheck");
1061676fbe81SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1062676fbe81SDimitry Andric return std::make_pair(Kind, std::make_pair(Check, Mask));
1063676fbe81SDimitry Andric }
1064676fbe81SDimitry Andric
PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType,QualType DstType)1065706b4fc4SDimitry Andric static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
1066706b4fc4SDimitry Andric QualType SrcType, QualType DstType) {
1067706b4fc4SDimitry Andric return SrcType->isIntegerType() && DstType->isIntegerType();
1068706b4fc4SDimitry Andric }
1069706b4fc4SDimitry Andric
EmitIntegerTruncationCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)1070c7e70c43SDimitry Andric void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
1071c7e70c43SDimitry Andric Value *Dst, QualType DstType,
1072c7e70c43SDimitry Andric SourceLocation Loc) {
1073676fbe81SDimitry Andric if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation))
1074676fbe81SDimitry Andric return;
1075676fbe81SDimitry Andric
1076676fbe81SDimitry Andric // We only care about int->int conversions here.
1077676fbe81SDimitry Andric // We ignore conversions to/from pointer and/or bool.
1078706b4fc4SDimitry Andric if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1079706b4fc4SDimitry Andric DstType))
1080676fbe81SDimitry Andric return;
1081676fbe81SDimitry Andric
1082676fbe81SDimitry Andric unsigned SrcBits = Src->getType()->getScalarSizeInBits();
1083676fbe81SDimitry Andric unsigned DstBits = Dst->getType()->getScalarSizeInBits();
1084676fbe81SDimitry Andric // This must be truncation. Else we do not care.
1085676fbe81SDimitry Andric if (SrcBits <= DstBits)
1086676fbe81SDimitry Andric return;
1087676fbe81SDimitry Andric
1088676fbe81SDimitry Andric assert(!DstType->isBooleanType() && "we should not get here with booleans.");
1089676fbe81SDimitry Andric
1090676fbe81SDimitry Andric // If the integer sign change sanitizer is enabled,
1091676fbe81SDimitry Andric // and we are truncating from larger unsigned type to smaller signed type,
1092676fbe81SDimitry Andric // let that next sanitizer deal with it.
1093676fbe81SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1094676fbe81SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1095676fbe81SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) &&
1096676fbe81SDimitry Andric (!SrcSigned && DstSigned))
1097676fbe81SDimitry Andric return;
1098676fbe81SDimitry Andric
1099676fbe81SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
1100676fbe81SDimitry Andric
1101676fbe81SDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1102676fbe81SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
1103676fbe81SDimitry Andric Check =
1104676fbe81SDimitry Andric EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
1105676fbe81SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1106676fbe81SDimitry Andric
1107676fbe81SDimitry Andric // Do we care about this type of truncation?
1108676fbe81SDimitry Andric if (!CGF.SanOpts.has(Check.second.second))
1109676fbe81SDimitry Andric return;
1110676fbe81SDimitry Andric
1111676fbe81SDimitry Andric llvm::Constant *StaticArgs[] = {
1112676fbe81SDimitry Andric CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
1113676fbe81SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType),
1114ac9a064cSDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1115ac9a064cSDimitry Andric llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1116ac9a064cSDimitry Andric
1117676fbe81SDimitry Andric CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1118676fbe81SDimitry Andric {Src, Dst});
1119676fbe81SDimitry Andric }
1120676fbe81SDimitry Andric
EmitIsNegativeTestHelper(Value * V,QualType VType,const char * Name,CGBuilderTy & Builder)1121ac9a064cSDimitry Andric static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
1122ac9a064cSDimitry Andric const char *Name,
1123ac9a064cSDimitry Andric CGBuilderTy &Builder) {
1124ac9a064cSDimitry Andric bool VSigned = VType->isSignedIntegerOrEnumerationType();
1125ac9a064cSDimitry Andric llvm::Type *VTy = V->getType();
1126ac9a064cSDimitry Andric if (!VSigned) {
1127ac9a064cSDimitry Andric // If the value is unsigned, then it is never negative.
1128ac9a064cSDimitry Andric return llvm::ConstantInt::getFalse(VTy->getContext());
1129ac9a064cSDimitry Andric }
1130ac9a064cSDimitry Andric llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
1131ac9a064cSDimitry Andric return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
1132ac9a064cSDimitry Andric llvm::Twine(Name) + "." + V->getName() +
1133ac9a064cSDimitry Andric ".negativitycheck");
1134ac9a064cSDimitry Andric }
1135ac9a064cSDimitry Andric
1136676fbe81SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
1137676fbe81SDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
1138676fbe81SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1139676fbe81SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)1140676fbe81SDimitry Andric EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
1141676fbe81SDimitry Andric QualType DstType, CGBuilderTy &Builder) {
1142676fbe81SDimitry Andric llvm::Type *SrcTy = Src->getType();
1143676fbe81SDimitry Andric llvm::Type *DstTy = Dst->getType();
1144676fbe81SDimitry Andric
1145676fbe81SDimitry Andric assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
1146676fbe81SDimitry Andric "non-integer llvm type");
1147676fbe81SDimitry Andric
1148676fbe81SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1149676fbe81SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1150676fbe81SDimitry Andric (void)SrcSigned; // Only used in assert()
1151676fbe81SDimitry Andric (void)DstSigned; // Only used in assert()
1152676fbe81SDimitry Andric unsigned SrcBits = SrcTy->getScalarSizeInBits();
1153676fbe81SDimitry Andric unsigned DstBits = DstTy->getScalarSizeInBits();
1154676fbe81SDimitry Andric (void)SrcBits; // Only used in assert()
1155676fbe81SDimitry Andric (void)DstBits; // Only used in assert()
1156676fbe81SDimitry Andric
1157676fbe81SDimitry Andric assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1158676fbe81SDimitry Andric "either the widths should be different, or the signednesses.");
1159676fbe81SDimitry Andric
1160676fbe81SDimitry Andric // 1. Was the old Value negative?
1161ac9a064cSDimitry Andric llvm::Value *SrcIsNegative =
1162ac9a064cSDimitry Andric EmitIsNegativeTestHelper(Src, SrcType, "src", Builder);
1163676fbe81SDimitry Andric // 2. Is the new Value negative?
1164ac9a064cSDimitry Andric llvm::Value *DstIsNegative =
1165ac9a064cSDimitry Andric EmitIsNegativeTestHelper(Dst, DstType, "dst", Builder);
1166676fbe81SDimitry Andric // 3. Now, was the 'negativity status' preserved during the conversion?
1167676fbe81SDimitry Andric // NOTE: conversion from negative to zero is considered to change the sign.
1168676fbe81SDimitry Andric // (We want to get 'false' when the conversion changed the sign)
1169676fbe81SDimitry Andric // So we should just equality-compare the negativity statuses.
1170676fbe81SDimitry Andric llvm::Value *Check = nullptr;
1171676fbe81SDimitry Andric Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck");
1172676fbe81SDimitry Andric // If the comparison result is 'false', then the conversion changed the sign.
1173676fbe81SDimitry Andric return std::make_pair(
1174676fbe81SDimitry Andric ScalarExprEmitter::ICCK_IntegerSignChange,
1175676fbe81SDimitry Andric std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
1176676fbe81SDimitry Andric }
1177676fbe81SDimitry Andric
EmitIntegerSignChangeCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)1178676fbe81SDimitry Andric void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
1179676fbe81SDimitry Andric Value *Dst, QualType DstType,
1180676fbe81SDimitry Andric SourceLocation Loc) {
1181676fbe81SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange))
1182c7e70c43SDimitry Andric return;
1183c7e70c43SDimitry Andric
1184c7e70c43SDimitry Andric llvm::Type *SrcTy = Src->getType();
1185c7e70c43SDimitry Andric llvm::Type *DstTy = Dst->getType();
1186c7e70c43SDimitry Andric
1187c7e70c43SDimitry Andric // We only care about int->int conversions here.
1188c7e70c43SDimitry Andric // We ignore conversions to/from pointer and/or bool.
1189706b4fc4SDimitry Andric if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1190706b4fc4SDimitry Andric DstType))
1191c7e70c43SDimitry Andric return;
1192c7e70c43SDimitry Andric
1193676fbe81SDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1194676fbe81SDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1195c7e70c43SDimitry Andric unsigned SrcBits = SrcTy->getScalarSizeInBits();
1196c7e70c43SDimitry Andric unsigned DstBits = DstTy->getScalarSizeInBits();
1197c7e70c43SDimitry Andric
1198676fbe81SDimitry Andric // Now, we do not need to emit the check in *all* of the cases.
1199676fbe81SDimitry Andric // We can avoid emitting it in some obvious cases where it would have been
1200676fbe81SDimitry Andric // dropped by the opt passes (instcombine) always anyways.
1201676fbe81SDimitry Andric // If it's a cast between effectively the same type, no check.
1202676fbe81SDimitry Andric // NOTE: this is *not* equivalent to checking the canonical types.
1203676fbe81SDimitry Andric if (SrcSigned == DstSigned && SrcBits == DstBits)
1204676fbe81SDimitry Andric return;
1205676fbe81SDimitry Andric // At least one of the values needs to have signed type.
1206676fbe81SDimitry Andric // If both are unsigned, then obviously, neither of them can be negative.
1207676fbe81SDimitry Andric if (!SrcSigned && !DstSigned)
1208676fbe81SDimitry Andric return;
1209676fbe81SDimitry Andric // If the conversion is to *larger* *signed* type, then no check is needed.
1210676fbe81SDimitry Andric // Because either sign-extension happens (so the sign will remain),
1211676fbe81SDimitry Andric // or zero-extension will happen (the sign bit will be zero.)
1212676fbe81SDimitry Andric if ((DstBits > SrcBits) && DstSigned)
1213676fbe81SDimitry Andric return;
1214676fbe81SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1215676fbe81SDimitry Andric (SrcBits > DstBits) && SrcSigned) {
1216676fbe81SDimitry Andric // If the signed integer truncation sanitizer is enabled,
1217676fbe81SDimitry Andric // and this is a truncation from signed type, then no check is needed.
1218676fbe81SDimitry Andric // Because here sign change check is interchangeable with truncation check.
1219676fbe81SDimitry Andric return;
1220676fbe81SDimitry Andric }
1221676fbe81SDimitry Andric // That's it. We can't rule out any more cases with the data we have.
1222c7e70c43SDimitry Andric
1223c7e70c43SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
1224c7e70c43SDimitry Andric
1225676fbe81SDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1226676fbe81SDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
1227676fbe81SDimitry Andric Check;
1228c7e70c43SDimitry Andric
1229676fbe81SDimitry Andric // Each of these checks needs to return 'false' when an issue was detected.
1230676fbe81SDimitry Andric ImplicitConversionCheckKind CheckKind;
1231676fbe81SDimitry Andric llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
1232676fbe81SDimitry Andric // So we can 'and' all the checks together, and still get 'false',
1233676fbe81SDimitry Andric // if at least one of the checks detected an issue.
1234676fbe81SDimitry Andric
1235676fbe81SDimitry Andric Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
1236676fbe81SDimitry Andric CheckKind = Check.first;
1237676fbe81SDimitry Andric Checks.emplace_back(Check.second);
1238676fbe81SDimitry Andric
1239676fbe81SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1240676fbe81SDimitry Andric (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1241676fbe81SDimitry Andric // If the signed integer truncation sanitizer was enabled,
1242676fbe81SDimitry Andric // and we are truncating from larger unsigned type to smaller signed type,
1243676fbe81SDimitry Andric // let's handle the case we skipped in that check.
1244676fbe81SDimitry Andric Check =
1245676fbe81SDimitry Andric EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
1246676fbe81SDimitry Andric CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1247676fbe81SDimitry Andric Checks.emplace_back(Check.second);
1248c7e70c43SDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1249676fbe81SDimitry Andric }
1250c7e70c43SDimitry Andric
1251c7e70c43SDimitry Andric llvm::Constant *StaticArgs[] = {
1252c7e70c43SDimitry Andric CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
1253c7e70c43SDimitry Andric CGF.EmitCheckTypeDescriptor(DstType),
1254ac9a064cSDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1255ac9a064cSDimitry Andric llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1256676fbe81SDimitry Andric // EmitCheck() will 'and' all the checks together.
1257676fbe81SDimitry Andric CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
1258676fbe81SDimitry Andric {Src, Dst});
1259c7e70c43SDimitry Andric }
1260c7e70c43SDimitry Andric
1261ac9a064cSDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
1262ac9a064cSDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
1263ac9a064cSDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1264ac9a064cSDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitBitfieldTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)1265ac9a064cSDimitry Andric EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
1266ac9a064cSDimitry Andric QualType DstType, CGBuilderTy &Builder) {
1267ac9a064cSDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1268ac9a064cSDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1269ac9a064cSDimitry Andric
1270ac9a064cSDimitry Andric ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1271ac9a064cSDimitry Andric if (!SrcSigned && !DstSigned)
1272ac9a064cSDimitry Andric Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1273ac9a064cSDimitry Andric else
1274ac9a064cSDimitry Andric Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1275ac9a064cSDimitry Andric
1276ac9a064cSDimitry Andric llvm::Value *Check = nullptr;
1277ac9a064cSDimitry Andric // 1. Extend the truncated value back to the same width as the Src.
1278ac9a064cSDimitry Andric Check = Builder.CreateIntCast(Dst, Src->getType(), DstSigned, "bf.anyext");
1279ac9a064cSDimitry Andric // 2. Equality-compare with the original source value
1280ac9a064cSDimitry Andric Check = Builder.CreateICmpEQ(Check, Src, "bf.truncheck");
1281ac9a064cSDimitry Andric // If the comparison result is 'i1 false', then the truncation was lossy.
1282ac9a064cSDimitry Andric
1283ac9a064cSDimitry Andric return std::make_pair(
1284ac9a064cSDimitry Andric Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1285ac9a064cSDimitry Andric }
1286ac9a064cSDimitry Andric
1287ac9a064cSDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
1288ac9a064cSDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
1289ac9a064cSDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1290ac9a064cSDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
EmitBitfieldSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)1291ac9a064cSDimitry Andric EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
1292ac9a064cSDimitry Andric QualType DstType, CGBuilderTy &Builder) {
1293ac9a064cSDimitry Andric // 1. Was the old Value negative?
1294ac9a064cSDimitry Andric llvm::Value *SrcIsNegative =
1295ac9a064cSDimitry Andric EmitIsNegativeTestHelper(Src, SrcType, "bf.src", Builder);
1296ac9a064cSDimitry Andric // 2. Is the new Value negative?
1297ac9a064cSDimitry Andric llvm::Value *DstIsNegative =
1298ac9a064cSDimitry Andric EmitIsNegativeTestHelper(Dst, DstType, "bf.dst", Builder);
1299ac9a064cSDimitry Andric // 3. Now, was the 'negativity status' preserved during the conversion?
1300ac9a064cSDimitry Andric // NOTE: conversion from negative to zero is considered to change the sign.
1301ac9a064cSDimitry Andric // (We want to get 'false' when the conversion changed the sign)
1302ac9a064cSDimitry Andric // So we should just equality-compare the negativity statuses.
1303ac9a064cSDimitry Andric llvm::Value *Check = nullptr;
1304ac9a064cSDimitry Andric Check =
1305ac9a064cSDimitry Andric Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "bf.signchangecheck");
1306ac9a064cSDimitry Andric // If the comparison result is 'false', then the conversion changed the sign.
1307ac9a064cSDimitry Andric return std::make_pair(
1308ac9a064cSDimitry Andric ScalarExprEmitter::ICCK_IntegerSignChange,
1309ac9a064cSDimitry Andric std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
1310ac9a064cSDimitry Andric }
1311ac9a064cSDimitry Andric
EmitBitfieldConversionCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,const CGBitFieldInfo & Info,SourceLocation Loc)1312ac9a064cSDimitry Andric void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
1313ac9a064cSDimitry Andric Value *Dst, QualType DstType,
1314ac9a064cSDimitry Andric const CGBitFieldInfo &Info,
1315ac9a064cSDimitry Andric SourceLocation Loc) {
1316ac9a064cSDimitry Andric
1317ac9a064cSDimitry Andric if (!SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1318ac9a064cSDimitry Andric return;
1319ac9a064cSDimitry Andric
1320ac9a064cSDimitry Andric // We only care about int->int conversions here.
1321ac9a064cSDimitry Andric // We ignore conversions to/from pointer and/or bool.
1322ac9a064cSDimitry Andric if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1323ac9a064cSDimitry Andric DstType))
1324ac9a064cSDimitry Andric return;
1325ac9a064cSDimitry Andric
1326ac9a064cSDimitry Andric if (DstType->isBooleanType() || SrcType->isBooleanType())
1327ac9a064cSDimitry Andric return;
1328ac9a064cSDimitry Andric
1329ac9a064cSDimitry Andric // This should be truncation of integral types.
1330ac9a064cSDimitry Andric assert(isa<llvm::IntegerType>(Src->getType()) &&
1331ac9a064cSDimitry Andric isa<llvm::IntegerType>(Dst->getType()) && "non-integer llvm type");
1332ac9a064cSDimitry Andric
1333ac9a064cSDimitry Andric // TODO: Calculate src width to avoid emitting code
1334ac9a064cSDimitry Andric // for unecessary cases.
1335ac9a064cSDimitry Andric unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits();
1336ac9a064cSDimitry Andric unsigned DstBits = Info.Size;
1337ac9a064cSDimitry Andric
1338ac9a064cSDimitry Andric bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
1339ac9a064cSDimitry Andric bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
1340ac9a064cSDimitry Andric
1341ac9a064cSDimitry Andric CodeGenFunction::SanitizerScope SanScope(this);
1342ac9a064cSDimitry Andric
1343ac9a064cSDimitry Andric std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1344ac9a064cSDimitry Andric std::pair<llvm::Value *, SanitizerMask>>
1345ac9a064cSDimitry Andric Check;
1346ac9a064cSDimitry Andric
1347ac9a064cSDimitry Andric // Truncation
1348ac9a064cSDimitry Andric bool EmitTruncation = DstBits < SrcBits;
1349ac9a064cSDimitry Andric // If Dst is signed and Src unsigned, we want to be more specific
1350ac9a064cSDimitry Andric // about the CheckKind we emit, in this case we want to emit
1351ac9a064cSDimitry Andric // ICCK_SignedIntegerTruncationOrSignChange.
1352ac9a064cSDimitry Andric bool EmitTruncationFromUnsignedToSigned =
1353ac9a064cSDimitry Andric EmitTruncation && DstSigned && !SrcSigned;
1354ac9a064cSDimitry Andric // Sign change
1355ac9a064cSDimitry Andric bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1356ac9a064cSDimitry Andric bool BothUnsigned = !SrcSigned && !DstSigned;
1357ac9a064cSDimitry Andric bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1358ac9a064cSDimitry Andric // We can avoid emitting sign change checks in some obvious cases
1359ac9a064cSDimitry Andric // 1. If Src and Dst have the same signedness and size
1360ac9a064cSDimitry Andric // 2. If both are unsigned sign check is unecessary!
1361ac9a064cSDimitry Andric // 3. If Dst is signed and bigger than Src, either
1362ac9a064cSDimitry Andric // sign-extension or zero-extension will make sure
1363ac9a064cSDimitry Andric // the sign remains.
1364ac9a064cSDimitry Andric bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1365ac9a064cSDimitry Andric
1366ac9a064cSDimitry Andric if (EmitTruncation)
1367ac9a064cSDimitry Andric Check =
1368ac9a064cSDimitry Andric EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
1369ac9a064cSDimitry Andric else if (EmitSignChange) {
1370ac9a064cSDimitry Andric assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1371ac9a064cSDimitry Andric "either the widths should be different, or the signednesses.");
1372ac9a064cSDimitry Andric Check =
1373ac9a064cSDimitry Andric EmitBitfieldSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
1374ac9a064cSDimitry Andric } else
1375ac9a064cSDimitry Andric return;
1376ac9a064cSDimitry Andric
1377ac9a064cSDimitry Andric ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1378ac9a064cSDimitry Andric if (EmitTruncationFromUnsignedToSigned)
1379ac9a064cSDimitry Andric CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1380ac9a064cSDimitry Andric
1381ac9a064cSDimitry Andric llvm::Constant *StaticArgs[] = {
1382ac9a064cSDimitry Andric EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(SrcType),
1383ac9a064cSDimitry Andric EmitCheckTypeDescriptor(DstType),
1384ac9a064cSDimitry Andric llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1385ac9a064cSDimitry Andric llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)};
1386ac9a064cSDimitry Andric
1387ac9a064cSDimitry Andric EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
1388ac9a064cSDimitry Andric {Src, Dst});
1389ac9a064cSDimitry Andric }
1390ac9a064cSDimitry Andric
EmitScalarCast(Value * Src,QualType SrcType,QualType DstType,llvm::Type * SrcTy,llvm::Type * DstTy,ScalarConversionOpts Opts)1391344a3780SDimitry Andric Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
1392344a3780SDimitry Andric QualType DstType, llvm::Type *SrcTy,
1393344a3780SDimitry Andric llvm::Type *DstTy,
1394344a3780SDimitry Andric ScalarConversionOpts Opts) {
1395344a3780SDimitry Andric // The Element types determine the type of cast to perform.
1396344a3780SDimitry Andric llvm::Type *SrcElementTy;
1397344a3780SDimitry Andric llvm::Type *DstElementTy;
1398344a3780SDimitry Andric QualType SrcElementType;
1399344a3780SDimitry Andric QualType DstElementType;
1400344a3780SDimitry Andric if (SrcType->isMatrixType() && DstType->isMatrixType()) {
1401344a3780SDimitry Andric SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1402344a3780SDimitry Andric DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1403344a3780SDimitry Andric SrcElementType = SrcType->castAs<MatrixType>()->getElementType();
1404344a3780SDimitry Andric DstElementType = DstType->castAs<MatrixType>()->getElementType();
1405344a3780SDimitry Andric } else {
1406344a3780SDimitry Andric assert(!SrcType->isMatrixType() && !DstType->isMatrixType() &&
1407344a3780SDimitry Andric "cannot cast between matrix and non-matrix types");
1408344a3780SDimitry Andric SrcElementTy = SrcTy;
1409344a3780SDimitry Andric DstElementTy = DstTy;
1410344a3780SDimitry Andric SrcElementType = SrcType;
1411344a3780SDimitry Andric DstElementType = DstType;
1412344a3780SDimitry Andric }
1413344a3780SDimitry Andric
1414344a3780SDimitry Andric if (isa<llvm::IntegerType>(SrcElementTy)) {
1415344a3780SDimitry Andric bool InputSigned = SrcElementType->isSignedIntegerOrEnumerationType();
1416344a3780SDimitry Andric if (SrcElementType->isBooleanType() && Opts.TreatBooleanAsSigned) {
1417344a3780SDimitry Andric InputSigned = true;
1418344a3780SDimitry Andric }
1419344a3780SDimitry Andric
1420344a3780SDimitry Andric if (isa<llvm::IntegerType>(DstElementTy))
1421344a3780SDimitry Andric return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1422344a3780SDimitry Andric if (InputSigned)
1423344a3780SDimitry Andric return Builder.CreateSIToFP(Src, DstTy, "conv");
1424344a3780SDimitry Andric return Builder.CreateUIToFP(Src, DstTy, "conv");
1425344a3780SDimitry Andric }
1426344a3780SDimitry Andric
1427344a3780SDimitry Andric if (isa<llvm::IntegerType>(DstElementTy)) {
1428344a3780SDimitry Andric assert(SrcElementTy->isFloatingPointTy() && "Unknown real conversion");
142977fc4c14SDimitry Andric bool IsSigned = DstElementType->isSignedIntegerOrEnumerationType();
143077fc4c14SDimitry Andric
143177fc4c14SDimitry Andric // If we can't recognize overflow as undefined behavior, assume that
143277fc4c14SDimitry Andric // overflow saturates. This protects against normal optimizations if we are
143377fc4c14SDimitry Andric // compiling with non-standard FP semantics.
143477fc4c14SDimitry Andric if (!CGF.CGM.getCodeGenOpts().StrictFloatCastOverflow) {
143577fc4c14SDimitry Andric llvm::Intrinsic::ID IID =
143677fc4c14SDimitry Andric IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
143777fc4c14SDimitry Andric return Builder.CreateCall(CGF.CGM.getIntrinsic(IID, {DstTy, SrcTy}), Src);
143877fc4c14SDimitry Andric }
143977fc4c14SDimitry Andric
144077fc4c14SDimitry Andric if (IsSigned)
1441344a3780SDimitry Andric return Builder.CreateFPToSI(Src, DstTy, "conv");
1442344a3780SDimitry Andric return Builder.CreateFPToUI(Src, DstTy, "conv");
1443344a3780SDimitry Andric }
1444344a3780SDimitry Andric
1445344a3780SDimitry Andric if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1446344a3780SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy, "conv");
1447344a3780SDimitry Andric return Builder.CreateFPExt(Src, DstTy, "conv");
1448344a3780SDimitry Andric }
1449344a3780SDimitry Andric
145045b53394SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
145145b53394SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcType,QualType DstType,SourceLocation Loc,ScalarConversionOpts Opts)1452ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
145345b53394SDimitry Andric QualType DstType,
145445b53394SDimitry Andric SourceLocation Loc,
1455c7e70c43SDimitry Andric ScalarConversionOpts Opts) {
1456676fbe81SDimitry Andric // All conversions involving fixed point types should be handled by the
1457676fbe81SDimitry Andric // EmitFixedPoint family functions. This is done to prevent bloating up this
1458676fbe81SDimitry Andric // function more, and although fixed point numbers are represented by
1459676fbe81SDimitry Andric // integers, we do not want to follow any logic that assumes they should be
1460676fbe81SDimitry Andric // treated as integers.
1461676fbe81SDimitry Andric // TODO(leonardchan): When necessary, add another if statement checking for
1462676fbe81SDimitry Andric // conversions to fixed point types from other types.
1463676fbe81SDimitry Andric if (SrcType->isFixedPointType()) {
146422989816SDimitry Andric if (DstType->isBooleanType())
146522989816SDimitry Andric // It is important that we check this before checking if the dest type is
146622989816SDimitry Andric // an integer because booleans are technically integer types.
1467676fbe81SDimitry Andric // We do not need to check the padding bit on unsigned types if unsigned
1468676fbe81SDimitry Andric // padding is enabled because overflow into this bit is undefined
1469676fbe81SDimitry Andric // behavior.
1470676fbe81SDimitry Andric return Builder.CreateIsNotNull(Src, "tobool");
1471b60736ecSDimitry Andric if (DstType->isFixedPointType() || DstType->isIntegerType() ||
1472b60736ecSDimitry Andric DstType->isRealFloatingType())
147322989816SDimitry Andric return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1474676fbe81SDimitry Andric
1475676fbe81SDimitry Andric llvm_unreachable(
147622989816SDimitry Andric "Unhandled scalar conversion from a fixed point type to another type.");
147722989816SDimitry Andric } else if (DstType->isFixedPointType()) {
1478b60736ecSDimitry Andric if (SrcType->isIntegerType() || SrcType->isRealFloatingType())
147922989816SDimitry Andric // This also includes converting booleans and enums to fixed point types.
148022989816SDimitry Andric return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
148122989816SDimitry Andric
148222989816SDimitry Andric llvm_unreachable(
148322989816SDimitry Andric "Unhandled scalar conversion to a fixed point type from another type.");
1484676fbe81SDimitry Andric }
1485676fbe81SDimitry Andric
1486c7e70c43SDimitry Andric QualType NoncanonicalSrcType = SrcType;
1487c7e70c43SDimitry Andric QualType NoncanonicalDstType = DstType;
1488c7e70c43SDimitry Andric
1489ec2b103cSEd Schouten SrcType = CGF.getContext().getCanonicalType(SrcType);
1490ec2b103cSEd Schouten DstType = CGF.getContext().getCanonicalType(DstType);
1491ec2b103cSEd Schouten if (SrcType == DstType) return Src;
1492ec2b103cSEd Schouten
14939f4dbff6SDimitry Andric if (DstType->isVoidType()) return nullptr;
1494ec2b103cSEd Schouten
149513cc256eSDimitry Andric llvm::Value *OrigSrc = Src;
149613cc256eSDimitry Andric QualType OrigSrcType = SrcType;
149736981b17SDimitry Andric llvm::Type *SrcTy = Src->getType();
149836981b17SDimitry Andric
1499ec2b103cSEd Schouten // Handle conversions to bool first, they are special: comparisons against 0.
1500ec2b103cSEd Schouten if (DstType->isBooleanType())
1501ec2b103cSEd Schouten return EmitConversionToBool(Src, SrcType);
1502ec2b103cSEd Schouten
150336981b17SDimitry Andric llvm::Type *DstTy = ConvertType(DstType);
1504ec2b103cSEd Schouten
15055e20cdd8SDimitry Andric // Cast from half through float if half isn't a native type.
15065e20cdd8SDimitry Andric if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
15075e20cdd8SDimitry Andric // Cast to FP using the intrinsic if the half type itself isn't supported.
15085e20cdd8SDimitry Andric if (DstTy->isFloatingPointTy()) {
1509461a67faSDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
15105e20cdd8SDimitry Andric return Builder.CreateCall(
15115e20cdd8SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy),
15125e20cdd8SDimitry Andric Src);
15135e20cdd8SDimitry Andric } else {
15145e20cdd8SDimitry Andric // Cast to other types through float, using either the intrinsic or FPExt,
15155e20cdd8SDimitry Andric // depending on whether the half type itself is supported
15165e20cdd8SDimitry Andric // (as opposed to operations on half, available with NativeHalfType).
1517461a67faSDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
15185e20cdd8SDimitry Andric Src = Builder.CreateCall(
15195e20cdd8SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
15205e20cdd8SDimitry Andric CGF.CGM.FloatTy),
15215e20cdd8SDimitry Andric Src);
15225e20cdd8SDimitry Andric } else {
15235e20cdd8SDimitry Andric Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
15245e20cdd8SDimitry Andric }
15255e20cdd8SDimitry Andric SrcType = CGF.getContext().FloatTy;
15265e20cdd8SDimitry Andric SrcTy = CGF.FloatTy;
15275e20cdd8SDimitry Andric }
15285e20cdd8SDimitry Andric }
15295e20cdd8SDimitry Andric
1530ec2b103cSEd Schouten // Ignore conversions like int -> uint.
1531676fbe81SDimitry Andric if (SrcTy == DstTy) {
1532676fbe81SDimitry Andric if (Opts.EmitImplicitIntegerSignChangeChecks)
1533676fbe81SDimitry Andric EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1534676fbe81SDimitry Andric NoncanonicalDstType, Loc);
1535676fbe81SDimitry Andric
1536ec2b103cSEd Schouten return Src;
1537676fbe81SDimitry Andric }
1538ec2b103cSEd Schouten
15394c8b2481SRoman Divacky // Handle pointer conversions next: pointers can only be converted to/from
15404c8b2481SRoman Divacky // other pointers and integers. Check for pointer types in terms of LLVM, as
15414c8b2481SRoman Divacky // some native types (like Obj-C id) may map to a pointer type.
1542bab175ecSDimitry Andric if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1543ec2b103cSEd Schouten // The source value may be an integer, or a pointer.
154436981b17SDimitry Andric if (isa<llvm::PointerType>(SrcTy))
1545ac9a064cSDimitry Andric return Src;
15464c8b2481SRoman Divacky
1547ec2b103cSEd Schouten assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
1548ec2b103cSEd Schouten // First, convert to the correct width so that we control the kind of
1549ec2b103cSEd Schouten // extension.
1550bab175ecSDimitry Andric llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT);
155129cafa66SDimitry Andric bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
1552ec2b103cSEd Schouten llvm::Value* IntResult =
1553ec2b103cSEd Schouten Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
1554ec2b103cSEd Schouten // Then, cast to pointer.
1555ec2b103cSEd Schouten return Builder.CreateIntToPtr(IntResult, DstTy, "conv");
1556ec2b103cSEd Schouten }
1557ec2b103cSEd Schouten
155836981b17SDimitry Andric if (isa<llvm::PointerType>(SrcTy)) {
1559ec2b103cSEd Schouten // Must be an ptr to int cast.
1560ec2b103cSEd Schouten assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
1561ec2b103cSEd Schouten return Builder.CreatePtrToInt(Src, DstTy, "conv");
1562ec2b103cSEd Schouten }
1563ec2b103cSEd Schouten
1564ec2b103cSEd Schouten // A scalar can be splatted to an extended vector of the same element type
15654c8b2481SRoman Divacky if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
15660414e226SDimitry Andric // Sema should add casts to make sure that the source expression's type is
15670414e226SDimitry Andric // the same as the vector's element type (sans qualifiers)
15680414e226SDimitry Andric assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
15690414e226SDimitry Andric SrcType.getTypePtr() &&
15700414e226SDimitry Andric "Splatted expr doesn't match with vector element type?");
1571ec2b103cSEd Schouten
1572ec2b103cSEd Schouten // Splat the element across to all elements
1573b60736ecSDimitry Andric unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
15740414e226SDimitry Andric return Builder.CreateVectorSplat(NumElements, Src, "splat");
1575ec2b103cSEd Schouten }
1576ec2b103cSEd Schouten
1577344a3780SDimitry Andric if (SrcType->isMatrixType() && DstType->isMatrixType())
1578344a3780SDimitry Andric return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1579344a3780SDimitry Andric
1580461a67faSDimitry Andric if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
1581ec2b103cSEd Schouten // Allow bitcast from vector to integer/fp of the same size.
1582145449b1SDimitry Andric llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1583145449b1SDimitry Andric llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1584461a67faSDimitry Andric if (SrcSize == DstSize)
1585ec2b103cSEd Schouten return Builder.CreateBitCast(Src, DstTy, "conv");
1586ec2b103cSEd Schouten
1587461a67faSDimitry Andric // Conversions between vectors of different sizes are not allowed except
1588461a67faSDimitry Andric // when vectors of half are involved. Operations on storage-only half
1589461a67faSDimitry Andric // vectors require promoting half vector operands to float vectors and
1590461a67faSDimitry Andric // truncating the result, which is either an int or float vector, to a
1591461a67faSDimitry Andric // short or half vector.
1592461a67faSDimitry Andric
1593461a67faSDimitry Andric // Source and destination are both expected to be vectors.
1594cfca06d7SDimitry Andric llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1595cfca06d7SDimitry Andric llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1596461a67faSDimitry Andric (void)DstElementTy;
1597461a67faSDimitry Andric
1598461a67faSDimitry Andric assert(((SrcElementTy->isIntegerTy() &&
1599461a67faSDimitry Andric DstElementTy->isIntegerTy()) ||
1600461a67faSDimitry Andric (SrcElementTy->isFloatingPointTy() &&
1601461a67faSDimitry Andric DstElementTy->isFloatingPointTy())) &&
1602461a67faSDimitry Andric "unexpected conversion between a floating-point vector and an "
1603461a67faSDimitry Andric "integer vector");
1604461a67faSDimitry Andric
1605461a67faSDimitry Andric // Truncate an i32 vector to an i16 vector.
1606461a67faSDimitry Andric if (SrcElementTy->isIntegerTy())
1607461a67faSDimitry Andric return Builder.CreateIntCast(Src, DstTy, false, "conv");
1608461a67faSDimitry Andric
1609461a67faSDimitry Andric // Truncate a float vector to a half vector.
1610461a67faSDimitry Andric if (SrcSize > DstSize)
1611461a67faSDimitry Andric return Builder.CreateFPTrunc(Src, DstTy, "conv");
1612461a67faSDimitry Andric
1613461a67faSDimitry Andric // Promote a half vector to a float vector.
1614461a67faSDimitry Andric return Builder.CreateFPExt(Src, DstTy, "conv");
1615461a67faSDimitry Andric }
1616461a67faSDimitry Andric
1617ec2b103cSEd Schouten // Finally, we have the arithmetic types: real int/float.
16189f4dbff6SDimitry Andric Value *Res = nullptr;
161936981b17SDimitry Andric llvm::Type *ResTy = DstTy;
162036981b17SDimitry Andric
162113cc256eSDimitry Andric // An overflowing conversion has undefined behavior if either the source type
162222989816SDimitry Andric // or the destination type is a floating-point type. However, we consider the
162322989816SDimitry Andric // range of representable values for all floating-point types to be
162422989816SDimitry Andric // [-inf,+inf], so no overflow can ever happen when the destination type is a
162522989816SDimitry Andric // floating-point type.
162606d4ba38SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
162722989816SDimitry Andric OrigSrcType->isFloatingType())
162845b53394SDimitry Andric EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
162945b53394SDimitry Andric Loc);
163013cc256eSDimitry Andric
16315e20cdd8SDimitry Andric // Cast to half through float if half isn't a native type.
16325e20cdd8SDimitry Andric if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
16335e20cdd8SDimitry Andric // Make sure we cast in a single step if from another FP type.
16345e20cdd8SDimitry Andric if (SrcTy->isFloatingPointTy()) {
16355e20cdd8SDimitry Andric // Use the intrinsic if the half type itself isn't supported
16365e20cdd8SDimitry Andric // (as opposed to operations on half, available with NativeHalfType).
1637461a67faSDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
16385e20cdd8SDimitry Andric return Builder.CreateCall(
16395e20cdd8SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src);
16405e20cdd8SDimitry Andric // If the half type is supported, just use an fptrunc.
16415e20cdd8SDimitry Andric return Builder.CreateFPTrunc(Src, DstTy);
16425e20cdd8SDimitry Andric }
1643dbe13110SDimitry Andric DstTy = CGF.FloatTy;
16445e20cdd8SDimitry Andric }
164536981b17SDimitry Andric
1646344a3780SDimitry Andric Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1647ec2b103cSEd Schouten
164836981b17SDimitry Andric if (DstTy != ResTy) {
1649461a67faSDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
165036981b17SDimitry Andric assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion");
16519f4dbff6SDimitry Andric Res = Builder.CreateCall(
16529f4dbff6SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy),
16539f4dbff6SDimitry Andric Res);
16545e20cdd8SDimitry Andric } else {
16555e20cdd8SDimitry Andric Res = Builder.CreateFPTrunc(Res, ResTy, "conv");
16565e20cdd8SDimitry Andric }
165736981b17SDimitry Andric }
165836981b17SDimitry Andric
1659c7e70c43SDimitry Andric if (Opts.EmitImplicitIntegerTruncationChecks)
1660c7e70c43SDimitry Andric EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1661c7e70c43SDimitry Andric NoncanonicalDstType, Loc);
1662c7e70c43SDimitry Andric
1663676fbe81SDimitry Andric if (Opts.EmitImplicitIntegerSignChangeChecks)
1664676fbe81SDimitry Andric EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1665676fbe81SDimitry Andric NoncanonicalDstType, Loc);
1666676fbe81SDimitry Andric
166736981b17SDimitry Andric return Res;
1668ec2b103cSEd Schouten }
1669ec2b103cSEd Schouten
EmitFixedPointConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)1670676fbe81SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
1671676fbe81SDimitry Andric QualType DstTy,
1672676fbe81SDimitry Andric SourceLocation Loc) {
1673b60736ecSDimitry Andric llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1674b60736ecSDimitry Andric llvm::Value *Result;
1675b60736ecSDimitry Andric if (SrcTy->isRealFloatingType())
1676b60736ecSDimitry Andric Result = FPBuilder.CreateFloatingToFixed(Src,
1677b60736ecSDimitry Andric CGF.getContext().getFixedPointSemantics(DstTy));
1678b60736ecSDimitry Andric else if (DstTy->isRealFloatingType())
1679b60736ecSDimitry Andric Result = FPBuilder.CreateFixedToFloating(Src,
1680b60736ecSDimitry Andric CGF.getContext().getFixedPointSemantics(SrcTy),
1681b60736ecSDimitry Andric ConvertType(DstTy));
1682b60736ecSDimitry Andric else {
1683b60736ecSDimitry Andric auto SrcFPSema = CGF.getContext().getFixedPointSemantics(SrcTy);
1684b60736ecSDimitry Andric auto DstFPSema = CGF.getContext().getFixedPointSemantics(DstTy);
168522989816SDimitry Andric
1686b60736ecSDimitry Andric if (DstTy->isIntegerType())
1687b60736ecSDimitry Andric Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1688b60736ecSDimitry Andric DstFPSema.getWidth(),
1689b60736ecSDimitry Andric DstFPSema.isSigned());
1690b60736ecSDimitry Andric else if (SrcTy->isIntegerType())
1691b60736ecSDimitry Andric Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1692b60736ecSDimitry Andric DstFPSema);
1693b60736ecSDimitry Andric else
1694b60736ecSDimitry Andric Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1695676fbe81SDimitry Andric }
1696676fbe81SDimitry Andric return Result;
1697676fbe81SDimitry Andric }
1698676fbe81SDimitry Andric
169945b53394SDimitry Andric /// Emit a conversion from the specified complex type to the specified
170045b53394SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)170145b53394SDimitry Andric Value *ScalarExprEmitter::EmitComplexToScalarConversion(
170245b53394SDimitry Andric CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
170345b53394SDimitry Andric SourceLocation Loc) {
1704ec2b103cSEd Schouten // Get the source element type.
1705809500fcSDimitry Andric SrcTy = SrcTy->castAs<ComplexType>()->getElementType();
1706ec2b103cSEd Schouten
1707ec2b103cSEd Schouten // Handle conversions to bool first, they are special: comparisons against 0.
1708ec2b103cSEd Schouten if (DstTy->isBooleanType()) {
1709ec2b103cSEd Schouten // Complex != 0 -> (Real != 0) | (Imag != 0)
171045b53394SDimitry Andric Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
171145b53394SDimitry Andric Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1712ec2b103cSEd Schouten return Builder.CreateOr(Src.first, Src.second, "tobool");
1713ec2b103cSEd Schouten }
1714ec2b103cSEd Schouten
1715ec2b103cSEd Schouten // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
1716ec2b103cSEd Schouten // the imaginary part of the complex value is discarded and the value of the
1717ec2b103cSEd Schouten // real part is converted according to the conversion rules for the
1718ec2b103cSEd Schouten // corresponding real type.
171945b53394SDimitry Andric return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1720ec2b103cSEd Schouten }
1721ec2b103cSEd Schouten
EmitNullValue(QualType Ty)1722d7279c4cSRoman Divacky Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1723809500fcSDimitry Andric return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty);
1724d7279c4cSRoman Divacky }
1725ec2b103cSEd Schouten
172648675466SDimitry Andric /// Emit a sanitization check for the given "binary" operation (which
172713cc256eSDimitry Andric /// might actually be a unary increment which has been lowered to a binary
172806d4ba38SDimitry Andric /// operation). The check passes if all values in \p Checks (which are \c i1),
172906d4ba38SDimitry Andric /// are \c true.
EmitBinOpCheck(ArrayRef<std::pair<Value *,SanitizerMask>> Checks,const BinOpInfo & Info)173006d4ba38SDimitry Andric void ScalarExprEmitter::EmitBinOpCheck(
17315e20cdd8SDimitry Andric ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {
17329f4dbff6SDimitry Andric assert(CGF.IsSanitizerScope);
1733bab175ecSDimitry Andric SanitizerHandler Check;
1734809500fcSDimitry Andric SmallVector<llvm::Constant *, 4> StaticData;
1735809500fcSDimitry Andric SmallVector<llvm::Value *, 2> DynamicData;
173613cc256eSDimitry Andric
173713cc256eSDimitry Andric BinaryOperatorKind Opcode = Info.Opcode;
173813cc256eSDimitry Andric if (BinaryOperator::isCompoundAssignmentOp(Opcode))
173913cc256eSDimitry Andric Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode);
174013cc256eSDimitry Andric
174113cc256eSDimitry Andric StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc()));
174213cc256eSDimitry Andric const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
174313cc256eSDimitry Andric if (UO && UO->getOpcode() == UO_Minus) {
1744bab175ecSDimitry Andric Check = SanitizerHandler::NegateOverflow;
174513cc256eSDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
174613cc256eSDimitry Andric DynamicData.push_back(Info.RHS);
174713cc256eSDimitry Andric } else {
174813cc256eSDimitry Andric if (BinaryOperator::isShiftOp(Opcode)) {
174913cc256eSDimitry Andric // Shift LHS negative or too large, or RHS out of bounds.
1750bab175ecSDimitry Andric Check = SanitizerHandler::ShiftOutOfBounds;
175113cc256eSDimitry Andric const BinaryOperator *BO = cast<BinaryOperator>(Info.E);
175213cc256eSDimitry Andric StaticData.push_back(
175313cc256eSDimitry Andric CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType()));
175413cc256eSDimitry Andric StaticData.push_back(
175513cc256eSDimitry Andric CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType()));
175613cc256eSDimitry Andric } else if (Opcode == BO_Div || Opcode == BO_Rem) {
175713cc256eSDimitry Andric // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1).
1758bab175ecSDimitry Andric Check = SanitizerHandler::DivremOverflow;
1759809500fcSDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
176013cc256eSDimitry Andric } else {
176106d4ba38SDimitry Andric // Arithmetic overflow (+, -, *).
176213cc256eSDimitry Andric switch (Opcode) {
1763bab175ecSDimitry Andric case BO_Add: Check = SanitizerHandler::AddOverflow; break;
1764bab175ecSDimitry Andric case BO_Sub: Check = SanitizerHandler::SubOverflow; break;
1765bab175ecSDimitry Andric case BO_Mul: Check = SanitizerHandler::MulOverflow; break;
176613cc256eSDimitry Andric default: llvm_unreachable("unexpected opcode for bin op check");
176713cc256eSDimitry Andric }
1768809500fcSDimitry Andric StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
176913cc256eSDimitry Andric }
177013cc256eSDimitry Andric DynamicData.push_back(Info.LHS);
177113cc256eSDimitry Andric DynamicData.push_back(Info.RHS);
177213cc256eSDimitry Andric }
177313cc256eSDimitry Andric
1774bab175ecSDimitry Andric CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
177513cc256eSDimitry Andric }
177613cc256eSDimitry Andric
1777ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
1778ec2b103cSEd Schouten // Visitor Methods
1779ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
1780ec2b103cSEd Schouten
VisitExpr(Expr * E)1781ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1782ec2b103cSEd Schouten CGF.ErrorUnsupported(E, "scalar expression");
1783ec2b103cSEd Schouten if (E->getType()->isVoidType())
17849f4dbff6SDimitry Andric return nullptr;
1785ec2b103cSEd Schouten return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
1786ec2b103cSEd Schouten }
1787ec2b103cSEd Schouten
1788344a3780SDimitry Andric Value *
VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr * E)1789344a3780SDimitry Andric ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1790344a3780SDimitry Andric ASTContext &Context = CGF.getContext();
1791e3b55780SDimitry Andric unsigned AddrSpace =
1792e3b55780SDimitry Andric Context.getTargetAddressSpace(CGF.CGM.GetGlobalConstantAddressSpace());
1793344a3780SDimitry Andric llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1794e3b55780SDimitry Andric E->ComputeName(Context), "__usn_str", AddrSpace);
1795344a3780SDimitry Andric
1796e3b55780SDimitry Andric llvm::Type *ExprTy = ConvertType(E->getType());
1797e3b55780SDimitry Andric return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1798e3b55780SDimitry Andric "usn_addr_cast");
1799344a3780SDimitry Andric }
1800344a3780SDimitry Andric
VisitEmbedExpr(EmbedExpr * E)1801ac9a064cSDimitry Andric Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1802ac9a064cSDimitry Andric assert(E->getDataElementCount() == 1);
1803ac9a064cSDimitry Andric auto It = E->begin();
1804ac9a064cSDimitry Andric return Builder.getInt((*It)->getValue());
1805ac9a064cSDimitry Andric }
1806ac9a064cSDimitry Andric
VisitShuffleVectorExpr(ShuffleVectorExpr * E)1807ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
18084ba67500SRoman Divacky // Vector Mask Case
18092b6b257fSDimitry Andric if (E->getNumSubExprs() == 2) {
18104ba67500SRoman Divacky Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));
18114ba67500SRoman Divacky Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));
18124ba67500SRoman Divacky Value *Mask;
18134ba67500SRoman Divacky
1814b60736ecSDimitry Andric auto *LTy = cast<llvm::FixedVectorType>(LHS->getType());
18154ba67500SRoman Divacky unsigned LHSElts = LTy->getNumElements();
18164ba67500SRoman Divacky
18174ba67500SRoman Divacky Mask = RHS;
18184ba67500SRoman Divacky
1819b60736ecSDimitry Andric auto *MTy = cast<llvm::FixedVectorType>(Mask->getType());
18204ba67500SRoman Divacky
18214ba67500SRoman Divacky // Mask off the high bits of each shuffle index.
182245b53394SDimitry Andric Value *MaskBits =
182345b53394SDimitry Andric llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
18244ba67500SRoman Divacky Mask = Builder.CreateAnd(Mask, MaskBits, "mask");
18254ba67500SRoman Divacky
18264ba67500SRoman Divacky // newv = undef
18274ba67500SRoman Divacky // mask = mask & maskbits
18284ba67500SRoman Divacky // for each elt
18294ba67500SRoman Divacky // n = extract mask i
18304ba67500SRoman Divacky // x = extract val n
18314ba67500SRoman Divacky // newv = insert newv, x, i
1832cfca06d7SDimitry Andric auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
18334ba67500SRoman Divacky MTy->getNumElements());
1834e3b55780SDimitry Andric Value* NewV = llvm::PoisonValue::get(RTy);
18354ba67500SRoman Divacky for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
18369f4dbff6SDimitry Andric Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
1837dbe13110SDimitry Andric Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
18384ba67500SRoman Divacky
18394ba67500SRoman Divacky Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
1840dbe13110SDimitry Andric NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
18414ba67500SRoman Divacky }
18424ba67500SRoman Divacky return NewV;
18434ba67500SRoman Divacky }
18444ba67500SRoman Divacky
1845ec2b103cSEd Schouten Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
1846ec2b103cSEd Schouten Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
18474ba67500SRoman Divacky
1848cfca06d7SDimitry Andric SmallVector<int, 32> Indices;
1849bfef3995SDimitry Andric for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
1850bfef3995SDimitry Andric llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
1851bfef3995SDimitry Andric // Check for -1 and output it as undef in the IR.
1852c0981da4SDimitry Andric if (Idx.isSigned() && Idx.isAllOnes())
1853cfca06d7SDimitry Andric Indices.push_back(-1);
1854bfef3995SDimitry Andric else
1855cfca06d7SDimitry Andric Indices.push_back(Idx.getZExtValue());
18564ba67500SRoman Divacky }
18574ba67500SRoman Divacky
1858cfca06d7SDimitry Andric return Builder.CreateShuffleVector(V1, V2, Indices, "shuffle");
1859ec2b103cSEd Schouten }
1860bfef3995SDimitry Andric
VisitConvertVectorExpr(ConvertVectorExpr * E)1861bfef3995SDimitry Andric Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1862bfef3995SDimitry Andric QualType SrcType = E->getSrcExpr()->getType(),
1863bfef3995SDimitry Andric DstType = E->getType();
1864bfef3995SDimitry Andric
1865bfef3995SDimitry Andric Value *Src = CGF.EmitScalarExpr(E->getSrcExpr());
1866bfef3995SDimitry Andric
1867bfef3995SDimitry Andric SrcType = CGF.getContext().getCanonicalType(SrcType);
1868bfef3995SDimitry Andric DstType = CGF.getContext().getCanonicalType(DstType);
1869bfef3995SDimitry Andric if (SrcType == DstType) return Src;
1870bfef3995SDimitry Andric
1871bfef3995SDimitry Andric assert(SrcType->isVectorType() &&
1872bfef3995SDimitry Andric "ConvertVector source type must be a vector");
1873bfef3995SDimitry Andric assert(DstType->isVectorType() &&
1874bfef3995SDimitry Andric "ConvertVector destination type must be a vector");
1875bfef3995SDimitry Andric
1876bfef3995SDimitry Andric llvm::Type *SrcTy = Src->getType();
1877bfef3995SDimitry Andric llvm::Type *DstTy = ConvertType(DstType);
1878bfef3995SDimitry Andric
1879bfef3995SDimitry Andric // Ignore conversions like int -> uint.
1880bfef3995SDimitry Andric if (SrcTy == DstTy)
1881bfef3995SDimitry Andric return Src;
1882bfef3995SDimitry Andric
1883519fc96cSDimitry Andric QualType SrcEltType = SrcType->castAs<VectorType>()->getElementType(),
1884519fc96cSDimitry Andric DstEltType = DstType->castAs<VectorType>()->getElementType();
1885bfef3995SDimitry Andric
1886bfef3995SDimitry Andric assert(SrcTy->isVectorTy() &&
1887bfef3995SDimitry Andric "ConvertVector source IR type must be a vector");
1888bfef3995SDimitry Andric assert(DstTy->isVectorTy() &&
1889bfef3995SDimitry Andric "ConvertVector destination IR type must be a vector");
1890bfef3995SDimitry Andric
1891cfca06d7SDimitry Andric llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
1892cfca06d7SDimitry Andric *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
1893bfef3995SDimitry Andric
1894bfef3995SDimitry Andric if (DstEltType->isBooleanType()) {
1895bfef3995SDimitry Andric assert((SrcEltTy->isFloatingPointTy() ||
1896bfef3995SDimitry Andric isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion");
1897bfef3995SDimitry Andric
1898bfef3995SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
1899bfef3995SDimitry Andric if (SrcEltTy->isFloatingPointTy()) {
1900bfef3995SDimitry Andric return Builder.CreateFCmpUNE(Src, Zero, "tobool");
1901bfef3995SDimitry Andric } else {
1902bfef3995SDimitry Andric return Builder.CreateICmpNE(Src, Zero, "tobool");
1903bfef3995SDimitry Andric }
1904bfef3995SDimitry Andric }
1905bfef3995SDimitry Andric
1906bfef3995SDimitry Andric // We have the arithmetic types: real int/float.
19079f4dbff6SDimitry Andric Value *Res = nullptr;
1908bfef3995SDimitry Andric
1909bfef3995SDimitry Andric if (isa<llvm::IntegerType>(SrcEltTy)) {
1910bfef3995SDimitry Andric bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType();
1911bfef3995SDimitry Andric if (isa<llvm::IntegerType>(DstEltTy))
1912bfef3995SDimitry Andric Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1913bfef3995SDimitry Andric else if (InputSigned)
1914bfef3995SDimitry Andric Res = Builder.CreateSIToFP(Src, DstTy, "conv");
1915bfef3995SDimitry Andric else
1916bfef3995SDimitry Andric Res = Builder.CreateUIToFP(Src, DstTy, "conv");
1917bfef3995SDimitry Andric } else if (isa<llvm::IntegerType>(DstEltTy)) {
1918bfef3995SDimitry Andric assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion");
1919bfef3995SDimitry Andric if (DstEltType->isSignedIntegerOrEnumerationType())
1920bfef3995SDimitry Andric Res = Builder.CreateFPToSI(Src, DstTy, "conv");
1921bfef3995SDimitry Andric else
1922bfef3995SDimitry Andric Res = Builder.CreateFPToUI(Src, DstTy, "conv");
1923bfef3995SDimitry Andric } else {
1924bfef3995SDimitry Andric assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
1925bfef3995SDimitry Andric "Unknown real conversion");
1926bfef3995SDimitry Andric if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
1927bfef3995SDimitry Andric Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
1928bfef3995SDimitry Andric else
1929bfef3995SDimitry Andric Res = Builder.CreateFPExt(Src, DstTy, "conv");
1930bfef3995SDimitry Andric }
1931bfef3995SDimitry Andric
1932bfef3995SDimitry Andric return Res;
1933bfef3995SDimitry Andric }
1934bfef3995SDimitry Andric
VisitMemberExpr(MemberExpr * E)19351569ce68SRoman Divacky Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
1936461a67faSDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) {
1937461a67faSDimitry Andric CGF.EmitIgnoredExpr(E->getBase());
1938676fbe81SDimitry Andric return CGF.emitScalarConstant(Constant, E);
1939461a67faSDimitry Andric } else {
1940676fbe81SDimitry Andric Expr::EvalResult Result;
1941676fbe81SDimitry Andric if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) {
1942676fbe81SDimitry Andric llvm::APSInt Value = Result.Val.getInt();
1943461a67faSDimitry Andric CGF.EmitIgnoredExpr(E->getBase());
1944dbe13110SDimitry Andric return Builder.getInt(Value);
19451569ce68SRoman Divacky }
1946461a67faSDimitry Andric }
1947bca07a45SDimitry Andric
1948ac9a064cSDimitry Andric llvm::Value *Result = EmitLoadOfLValue(E);
1949ac9a064cSDimitry Andric
1950ac9a064cSDimitry Andric // If -fdebug-info-for-profiling is specified, emit a pseudo variable and its
1951ac9a064cSDimitry Andric // debug info for the pointer, even if there is no variable associated with
1952ac9a064cSDimitry Andric // the pointer's expression.
1953ac9a064cSDimitry Andric if (CGF.CGM.getCodeGenOpts().DebugInfoForProfiling && CGF.getDebugInfo()) {
1954ac9a064cSDimitry Andric if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(Result)) {
1955ac9a064cSDimitry Andric if (llvm::GetElementPtrInst *GEP =
1956ac9a064cSDimitry Andric dyn_cast<llvm::GetElementPtrInst>(Load->getPointerOperand())) {
1957ac9a064cSDimitry Andric if (llvm::Instruction *Pointer =
1958ac9a064cSDimitry Andric dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
1959ac9a064cSDimitry Andric QualType Ty = E->getBase()->getType();
1960ac9a064cSDimitry Andric if (!E->isArrow())
1961ac9a064cSDimitry Andric Ty = CGF.getContext().getPointerType(Ty);
1962ac9a064cSDimitry Andric CGF.getDebugInfo()->EmitPseudoVariable(Builder, Pointer, Ty);
1963ac9a064cSDimitry Andric }
1964ac9a064cSDimitry Andric }
1965ac9a064cSDimitry Andric }
1966ac9a064cSDimitry Andric }
1967ac9a064cSDimitry Andric return Result;
19681569ce68SRoman Divacky }
1969ec2b103cSEd Schouten
VisitArraySubscriptExpr(ArraySubscriptExpr * E)1970ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
1971ec2b103cSEd Schouten TestAndClearIgnoreResultAssign();
1972ec2b103cSEd Schouten
1973ec2b103cSEd Schouten // Emit subscript expressions in rvalue context's. For most cases, this just
1974ec2b103cSEd Schouten // loads the lvalue formed by the subscript expr. However, we have to be
1975ec2b103cSEd Schouten // careful, because the base of a vector subscript is occasionally an rvalue,
1976ec2b103cSEd Schouten // so we can't get it as an lvalue.
1977145449b1SDimitry Andric if (!E->getBase()->getType()->isVectorType() &&
1978b1c73532SDimitry Andric !E->getBase()->getType()->isSveVLSBuiltinType())
1979ec2b103cSEd Schouten return EmitLoadOfLValue(E);
1980ec2b103cSEd Schouten
1981ec2b103cSEd Schouten // Handle the vector case. The base must be a vector, the index must be an
1982ec2b103cSEd Schouten // integer value.
1983ec2b103cSEd Schouten Value *Base = Visit(E->getBase());
1984ec2b103cSEd Schouten Value *Idx = Visit(E->getIdx());
1985809500fcSDimitry Andric QualType IdxTy = E->getIdx()->getType();
1986809500fcSDimitry Andric
198706d4ba38SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
1988809500fcSDimitry Andric CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
1989809500fcSDimitry Andric
1990ec2b103cSEd Schouten return Builder.CreateExtractElement(Base, Idx, "vecext");
1991ec2b103cSEd Schouten }
1992ec2b103cSEd Schouten
VisitMatrixSubscriptExpr(MatrixSubscriptExpr * E)1993cfca06d7SDimitry Andric Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
1994cfca06d7SDimitry Andric TestAndClearIgnoreResultAssign();
1995cfca06d7SDimitry Andric
1996cfca06d7SDimitry Andric // Handle the vector case. The base must be a vector, the index must be an
1997cfca06d7SDimitry Andric // integer value.
1998cfca06d7SDimitry Andric Value *RowIdx = Visit(E->getRowIdx());
1999cfca06d7SDimitry Andric Value *ColumnIdx = Visit(E->getColumnIdx());
2000c0981da4SDimitry Andric
2001c0981da4SDimitry Andric const auto *MatrixTy = E->getBase()->getType()->castAs<ConstantMatrixType>();
2002c0981da4SDimitry Andric unsigned NumRows = MatrixTy->getNumRows();
2003145449b1SDimitry Andric llvm::MatrixBuilder MB(Builder);
2004c0981da4SDimitry Andric Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2005c0981da4SDimitry Andric if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0)
2006c0981da4SDimitry Andric MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2007c0981da4SDimitry Andric
2008cfca06d7SDimitry Andric Value *Matrix = Visit(E->getBase());
2009cfca06d7SDimitry Andric
2010cfca06d7SDimitry Andric // TODO: Should we emit bounds checks with SanitizerKind::ArrayBounds?
2011c0981da4SDimitry Andric return Builder.CreateExtractElement(Matrix, Idx, "matrixext");
201273490b89SRoman Divacky }
201373490b89SRoman Divacky
getMaskElt(llvm::ShuffleVectorInst * SVI,unsigned Idx,unsigned Off)2014cfca06d7SDimitry Andric static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
2015cfca06d7SDimitry Andric unsigned Off) {
2016cfca06d7SDimitry Andric int MV = SVI->getMaskValue(Idx);
2017cfca06d7SDimitry Andric if (MV == -1)
2018cfca06d7SDimitry Andric return -1;
2019cfca06d7SDimitry Andric return Off + MV;
202036c5ade2SDimitry Andric }
2021cfca06d7SDimitry Andric
getAsInt32(llvm::ConstantInt * C,llvm::Type * I32Ty)2022cfca06d7SDimitry Andric static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {
2023cfca06d7SDimitry Andric assert(llvm::ConstantInt::isValueValidForType(I32Ty, C->getZExtValue()) &&
2024cfca06d7SDimitry Andric "Index operand too large for shufflevector mask!");
2025cfca06d7SDimitry Andric return C->getZExtValue();
202636c5ade2SDimitry Andric }
202736c5ade2SDimitry Andric
VisitInitListExpr(InitListExpr * E)202873490b89SRoman Divacky Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
202973490b89SRoman Divacky bool Ignore = TestAndClearIgnoreResultAssign();
203073490b89SRoman Divacky (void)Ignore;
203173490b89SRoman Divacky assert (Ignore == false && "init list ignored");
203273490b89SRoman Divacky unsigned NumInitElements = E->getNumInits();
203373490b89SRoman Divacky
203473490b89SRoman Divacky if (E->hadArrayRangeDesignator())
203573490b89SRoman Divacky CGF.ErrorUnsupported(E, "GNU array range designator extension");
203673490b89SRoman Divacky
203736981b17SDimitry Andric llvm::VectorType *VType =
203873490b89SRoman Divacky dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
203973490b89SRoman Divacky
204036981b17SDimitry Andric if (!VType) {
204136981b17SDimitry Andric if (NumInitElements == 0) {
204236981b17SDimitry Andric // C++11 value-initialization for the scalar.
204336981b17SDimitry Andric return EmitNullValue(E->getType());
204436981b17SDimitry Andric }
204573490b89SRoman Divacky // We have a scalar in braces. Just use the first element.
204673490b89SRoman Divacky return Visit(E->getInit(0));
204736981b17SDimitry Andric }
204873490b89SRoman Divacky
20497fa27ce4SDimitry Andric if (isa<llvm::ScalableVectorType>(VType)) {
20507fa27ce4SDimitry Andric if (NumInitElements == 0) {
20517fa27ce4SDimitry Andric // C++11 value-initialization for the vector.
20527fa27ce4SDimitry Andric return EmitNullValue(E->getType());
20537fa27ce4SDimitry Andric }
20547fa27ce4SDimitry Andric
20557fa27ce4SDimitry Andric if (NumInitElements == 1) {
20567fa27ce4SDimitry Andric Expr *InitVector = E->getInit(0);
20577fa27ce4SDimitry Andric
20587fa27ce4SDimitry Andric // Initialize from another scalable vector of the same type.
20597fa27ce4SDimitry Andric if (InitVector->getType() == E->getType())
20607fa27ce4SDimitry Andric return Visit(InitVector);
20617fa27ce4SDimitry Andric }
20627fa27ce4SDimitry Andric
20637fa27ce4SDimitry Andric llvm_unreachable("Unexpected initialization of a scalable vector!");
20647fa27ce4SDimitry Andric }
20657fa27ce4SDimitry Andric
2066b60736ecSDimitry Andric unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
206773490b89SRoman Divacky
206873490b89SRoman Divacky // Loop over initializers collecting the Value for each, and remembering
206973490b89SRoman Divacky // whether the source was swizzle (ExtVectorElementExpr). This will allow
207073490b89SRoman Divacky // us to fold the shuffle for the swizzle into the shuffle for the vector
207173490b89SRoman Divacky // initializer, since LLVM optimizers generally do not want to touch
207273490b89SRoman Divacky // shuffles.
207373490b89SRoman Divacky unsigned CurIdx = 0;
207499aabd70SDimitry Andric bool VIsPoisonShuffle = false;
207599aabd70SDimitry Andric llvm::Value *V = llvm::PoisonValue::get(VType);
207673490b89SRoman Divacky for (unsigned i = 0; i != NumInitElements; ++i) {
207773490b89SRoman Divacky Expr *IE = E->getInit(i);
207873490b89SRoman Divacky Value *Init = Visit(IE);
2079cfca06d7SDimitry Andric SmallVector<int, 16> Args;
208073490b89SRoman Divacky
208136981b17SDimitry Andric llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
208273490b89SRoman Divacky
208373490b89SRoman Divacky // Handle scalar elements. If the scalar initializer is actually one
208473490b89SRoman Divacky // element of a different vector of the same width, use shuffle instead of
208573490b89SRoman Divacky // extract+insert.
208673490b89SRoman Divacky if (!VVT) {
208773490b89SRoman Divacky if (isa<ExtVectorElementExpr>(IE)) {
208873490b89SRoman Divacky llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
208973490b89SRoman Divacky
2090b60736ecSDimitry Andric if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2091b60736ecSDimitry Andric ->getNumElements() == ResElts) {
209273490b89SRoman Divacky llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
20939f4dbff6SDimitry Andric Value *LHS = nullptr, *RHS = nullptr;
209473490b89SRoman Divacky if (CurIdx == 0) {
209599aabd70SDimitry Andric // insert into poison -> shuffle (src, poison)
209636c5ade2SDimitry Andric // shufflemask must use an i32
209736c5ade2SDimitry Andric Args.push_back(getAsInt32(C, CGF.Int32Ty));
2098cfca06d7SDimitry Andric Args.resize(ResElts, -1);
209973490b89SRoman Divacky
210073490b89SRoman Divacky LHS = EI->getVectorOperand();
210173490b89SRoman Divacky RHS = V;
210299aabd70SDimitry Andric VIsPoisonShuffle = true;
210399aabd70SDimitry Andric } else if (VIsPoisonShuffle) {
210499aabd70SDimitry Andric // insert into poison shuffle && size match -> shuffle (v, src)
210573490b89SRoman Divacky llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
210673490b89SRoman Divacky for (unsigned j = 0; j != CurIdx; ++j)
2107cfca06d7SDimitry Andric Args.push_back(getMaskElt(SVV, j, 0));
2108cfca06d7SDimitry Andric Args.push_back(ResElts + C->getZExtValue());
2109cfca06d7SDimitry Andric Args.resize(ResElts, -1);
211073490b89SRoman Divacky
211173490b89SRoman Divacky LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
211273490b89SRoman Divacky RHS = EI->getVectorOperand();
211399aabd70SDimitry Andric VIsPoisonShuffle = false;
211473490b89SRoman Divacky }
211573490b89SRoman Divacky if (!Args.empty()) {
2116cfca06d7SDimitry Andric V = Builder.CreateShuffleVector(LHS, RHS, Args);
211773490b89SRoman Divacky ++CurIdx;
211873490b89SRoman Divacky continue;
211973490b89SRoman Divacky }
212073490b89SRoman Divacky }
212173490b89SRoman Divacky }
212201af97d3SDimitry Andric V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
212301af97d3SDimitry Andric "vecinit");
212499aabd70SDimitry Andric VIsPoisonShuffle = false;
212573490b89SRoman Divacky ++CurIdx;
212673490b89SRoman Divacky continue;
212773490b89SRoman Divacky }
212873490b89SRoman Divacky
2129b60736ecSDimitry Andric unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
213073490b89SRoman Divacky
213173490b89SRoman Divacky // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's
213273490b89SRoman Divacky // input is the same width as the vector being constructed, generate an
213373490b89SRoman Divacky // optimized shuffle of the swizzle input into the result.
213451fb8b01SRoman Divacky unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
213573490b89SRoman Divacky if (isa<ExtVectorElementExpr>(IE)) {
213673490b89SRoman Divacky llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
213773490b89SRoman Divacky Value *SVOp = SVI->getOperand(0);
2138b60736ecSDimitry Andric auto *OpTy = cast<llvm::FixedVectorType>(SVOp->getType());
213973490b89SRoman Divacky
214073490b89SRoman Divacky if (OpTy->getNumElements() == ResElts) {
214173490b89SRoman Divacky for (unsigned j = 0; j != CurIdx; ++j) {
214299aabd70SDimitry Andric // If the current vector initializer is a shuffle with poison, merge
214373490b89SRoman Divacky // this shuffle directly into it.
214499aabd70SDimitry Andric if (VIsPoisonShuffle) {
2145cfca06d7SDimitry Andric Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0));
214673490b89SRoman Divacky } else {
2147cfca06d7SDimitry Andric Args.push_back(j);
214873490b89SRoman Divacky }
214973490b89SRoman Divacky }
215073490b89SRoman Divacky for (unsigned j = 0, je = InitElts; j != je; ++j)
2151cfca06d7SDimitry Andric Args.push_back(getMaskElt(SVI, j, Offset));
2152cfca06d7SDimitry Andric Args.resize(ResElts, -1);
215373490b89SRoman Divacky
215499aabd70SDimitry Andric if (VIsPoisonShuffle)
215573490b89SRoman Divacky V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
215673490b89SRoman Divacky
215773490b89SRoman Divacky Init = SVOp;
215873490b89SRoman Divacky }
215973490b89SRoman Divacky }
216073490b89SRoman Divacky
216173490b89SRoman Divacky // Extend init to result vector length, and then shuffle its contribution
216273490b89SRoman Divacky // to the vector initializer into V.
216373490b89SRoman Divacky if (Args.empty()) {
216473490b89SRoman Divacky for (unsigned j = 0; j != InitElts; ++j)
2165cfca06d7SDimitry Andric Args.push_back(j);
2166cfca06d7SDimitry Andric Args.resize(ResElts, -1);
2167b60736ecSDimitry Andric Init = Builder.CreateShuffleVector(Init, Args, "vext");
216873490b89SRoman Divacky
216973490b89SRoman Divacky Args.clear();
217073490b89SRoman Divacky for (unsigned j = 0; j != CurIdx; ++j)
2171cfca06d7SDimitry Andric Args.push_back(j);
217273490b89SRoman Divacky for (unsigned j = 0; j != InitElts; ++j)
2173cfca06d7SDimitry Andric Args.push_back(j + Offset);
2174cfca06d7SDimitry Andric Args.resize(ResElts, -1);
217573490b89SRoman Divacky }
217673490b89SRoman Divacky
217799aabd70SDimitry Andric // If V is poison, make sure it ends up on the RHS of the shuffle to aid
217873490b89SRoman Divacky // merging subsequent shuffles into this one.
217973490b89SRoman Divacky if (CurIdx == 0)
218073490b89SRoman Divacky std::swap(V, Init);
2181cfca06d7SDimitry Andric V = Builder.CreateShuffleVector(V, Init, Args, "vecinit");
218299aabd70SDimitry Andric VIsPoisonShuffle = isa<llvm::PoisonValue>(Init);
218373490b89SRoman Divacky CurIdx += InitElts;
218473490b89SRoman Divacky }
218573490b89SRoman Divacky
218673490b89SRoman Divacky // FIXME: evaluate codegen vs. shuffling against constant null vector.
218773490b89SRoman Divacky // Emit remaining default initializers.
218836981b17SDimitry Andric llvm::Type *EltTy = VType->getElementType();
218973490b89SRoman Divacky
219073490b89SRoman Divacky // Emit remaining default initializers
219173490b89SRoman Divacky for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
219201af97d3SDimitry Andric Value *Idx = Builder.getInt32(CurIdx);
219373490b89SRoman Divacky llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
219473490b89SRoman Divacky V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
219573490b89SRoman Divacky }
219673490b89SRoman Divacky return V;
219773490b89SRoman Divacky }
219873490b89SRoman Divacky
ShouldNullCheckClassCastValue(const CastExpr * CE)219945b53394SDimitry Andric bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) {
22001569ce68SRoman Divacky const Expr *E = CE->getSubExpr();
22011569ce68SRoman Divacky
22023d1dcd9bSDimitry Andric if (CE->getCastKind() == CK_UncheckedDerivedToBase)
220311d2b2d2SRoman Divacky return false;
220411d2b2d2SRoman Divacky
220545b53394SDimitry Andric if (isa<CXXThisExpr>(E->IgnoreParens())) {
22061569ce68SRoman Divacky // We always assume that 'this' is never null.
22071569ce68SRoman Divacky return false;
22081569ce68SRoman Divacky }
22091569ce68SRoman Divacky
22101569ce68SRoman Divacky if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
22113d1dcd9bSDimitry Andric // And that glvalue casts are never null.
2212344a3780SDimitry Andric if (ICE->isGLValue())
22131569ce68SRoman Divacky return false;
22141569ce68SRoman Divacky }
22151569ce68SRoman Divacky
22161569ce68SRoman Divacky return true;
22171569ce68SRoman Divacky }
22181569ce68SRoman Divacky
22194c8b2481SRoman Divacky // VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts
22204c8b2481SRoman Divacky // have to handle a more broad range of conversions than explicit casts, as they
22214c8b2481SRoman Divacky // handle things like function to ptr-to-function decay etc.
VisitCastExpr(CastExpr * CE)2222180abc3dSDimitry Andric Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
22231569ce68SRoman Divacky Expr *E = CE->getSubExpr();
22244c8b2481SRoman Divacky QualType DestTy = CE->getType();
22253d1dcd9bSDimitry Andric CastKind Kind = CE->getCastKind();
2226e3b55780SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2227ec2b103cSEd Schouten
22282b6b257fSDimitry Andric // These cases are generally not written to ignore the result of
22292b6b257fSDimitry Andric // evaluating their sub-expressions, so we clear this now.
22302b6b257fSDimitry Andric bool Ignored = TestAndClearIgnoreResultAssign();
22314c8b2481SRoman Divacky
22321569ce68SRoman Divacky // Since almost all cast kinds apply to scalars, this switch doesn't have
22331569ce68SRoman Divacky // a default case, so the compiler will warn on a missing case. The cases
22341569ce68SRoman Divacky // are in the same order as in the CastKind enum.
22354c8b2481SRoman Divacky switch (Kind) {
2236bca07a45SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
223713cc256eSDimitry Andric case CK_BuiltinFnToFnPtr:
223813cc256eSDimitry Andric llvm_unreachable("builtin functions are handled elsewhere");
2239b3d5a323SRoman Divacky
22403d1dcd9bSDimitry Andric case CK_LValueBitCast:
22413d1dcd9bSDimitry Andric case CK_ObjCObjectLValueCast: {
2242ac9a064cSDimitry Andric Address Addr = EmitLValue(E).getAddress();
22437fa27ce4SDimitry Andric Addr = Addr.withElementType(CGF.ConvertTypeForMem(DestTy));
224445b53394SDimitry Andric LValue LV = CGF.MakeAddrLValue(Addr, DestTy);
224545b53394SDimitry Andric return EmitLoadOfLValue(LV, CE->getExprLoc());
22464e58654bSRoman Divacky }
22474e58654bSRoman Divacky
224822989816SDimitry Andric case CK_LValueToRValueBitCast: {
224922989816SDimitry Andric LValue SourceLVal = CGF.EmitLValue(E);
2250ac9a064cSDimitry Andric Address Addr =
2251ac9a064cSDimitry Andric SourceLVal.getAddress().withElementType(CGF.ConvertTypeForMem(DestTy));
225222989816SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
225322989816SDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
225422989816SDimitry Andric return EmitLoadOfLValue(DestLV, CE->getExprLoc());
225522989816SDimitry Andric }
225622989816SDimitry Andric
225736981b17SDimitry Andric case CK_CPointerToObjCPointerCast:
225836981b17SDimitry Andric case CK_BlockPointerToObjCPointerCast:
22593d1dcd9bSDimitry Andric case CK_AnyPointerToBlockPointerCast:
22603d1dcd9bSDimitry Andric case CK_BitCast: {
22614c8b2481SRoman Divacky Value *Src = Visit(const_cast<Expr*>(E));
22629f4dbff6SDimitry Andric llvm::Type *SrcTy = Src->getType();
22639f4dbff6SDimitry Andric llvm::Type *DstTy = ConvertType(DestTy);
2264b1c73532SDimitry Andric assert(
2265b1c73532SDimitry Andric (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2266b1c73532SDimitry Andric SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2267b1c73532SDimitry Andric "Address-space cast must be used to convert address spaces");
22685e20cdd8SDimitry Andric
22695e20cdd8SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
2270145449b1SDimitry Andric if (auto *PT = DestTy->getAs<PointerType>()) {
2271145449b1SDimitry Andric CGF.EmitVTablePtrCheckForCast(
2272145449b1SDimitry Andric PT->getPointeeType(),
2273145449b1SDimitry Andric Address(Src,
2274145449b1SDimitry Andric CGF.ConvertTypeForMem(
2275145449b1SDimitry Andric E->getType()->castAs<PointerType>()->getPointeeType()),
2276145449b1SDimitry Andric CGF.getPointerAlign()),
2277145449b1SDimitry Andric /*MayBeNull=*/true, CodeGenFunction::CFITCK_UnrelatedCast,
2278676fbe81SDimitry Andric CE->getBeginLoc());
22795e20cdd8SDimitry Andric }
2280145449b1SDimitry Andric }
22815e20cdd8SDimitry Andric
228248675466SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
228348675466SDimitry Andric const QualType SrcType = E->getType();
228448675466SDimitry Andric
228548675466SDimitry Andric if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) {
228648675466SDimitry Andric // Casting to pointer that could carry dynamic information (provided by
228748675466SDimitry Andric // invariant.group) requires launder.
228848675466SDimitry Andric Src = Builder.CreateLaunderInvariantGroup(Src);
228948675466SDimitry Andric } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) {
229048675466SDimitry Andric // Casting to pointer that does not carry dynamic information (provided
229148675466SDimitry Andric // by invariant.group) requires stripping it. Note that we don't do it
229248675466SDimitry Andric // if the source could not be dynamic type and destination could be
229348675466SDimitry Andric // dynamic because dynamic information is already laundered. It is
229448675466SDimitry Andric // because launder(strip(src)) == launder(src), so there is no need to
229548675466SDimitry Andric // add extra strip before launder.
229648675466SDimitry Andric Src = Builder.CreateStripInvariantGroup(Src);
229748675466SDimitry Andric }
229848675466SDimitry Andric }
229948675466SDimitry Andric
2300cfca06d7SDimitry Andric // Update heapallocsite metadata when there is an explicit pointer cast.
2301cfca06d7SDimitry Andric if (auto *CI = dyn_cast<llvm::CallBase>(Src)) {
23027fa27ce4SDimitry Andric if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE) &&
23037fa27ce4SDimitry Andric !isa<CastExpr>(E)) {
2304cfca06d7SDimitry Andric QualType PointeeType = DestTy->getPointeeType();
2305cfca06d7SDimitry Andric if (!PointeeType.isNull())
2306cfca06d7SDimitry Andric CGF.getDebugInfo()->addHeapAllocSiteMetadata(CI, PointeeType,
2307cfca06d7SDimitry Andric CE->getExprLoc());
2308cfca06d7SDimitry Andric }
2309cfca06d7SDimitry Andric }
231022989816SDimitry Andric
2311b60736ecSDimitry Andric // If Src is a fixed vector and Dst is a scalable vector, and both have the
2312145449b1SDimitry Andric // same element type, use the llvm.vector.insert intrinsic to perform the
2313145449b1SDimitry Andric // bitcast.
2314ac9a064cSDimitry Andric if (auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2315ac9a064cSDimitry Andric if (auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2316ac9a064cSDimitry Andric // If we are casting a fixed i8 vector to a scalable i1 predicate
2317c0981da4SDimitry Andric // vector, use a vector insert and bitcast the result.
2318ac9a064cSDimitry Andric if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2319ac9a064cSDimitry Andric ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
2320ac9a064cSDimitry Andric FixedSrcTy->getElementType()->isIntegerTy(8)) {
2321ac9a064cSDimitry Andric ScalableDstTy = llvm::ScalableVectorType::get(
2322ac9a064cSDimitry Andric FixedSrcTy->getElementType(),
2323ac9a064cSDimitry Andric ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2324c0981da4SDimitry Andric }
2325ac9a064cSDimitry Andric if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2326ac9a064cSDimitry Andric llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2327b60736ecSDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2328c0981da4SDimitry Andric llvm::Value *Result = Builder.CreateInsertVector(
2329ac9a064cSDimitry Andric ScalableDstTy, UndefVec, Src, Zero, "cast.scalable");
2330ac9a064cSDimitry Andric if (Result->getType() != DstTy)
2331ac9a064cSDimitry Andric Result = Builder.CreateBitCast(Result, DstTy);
2332c0981da4SDimitry Andric return Result;
2333b60736ecSDimitry Andric }
2334b60736ecSDimitry Andric }
2335b60736ecSDimitry Andric }
2336b60736ecSDimitry Andric
2337b60736ecSDimitry Andric // If Src is a scalable vector and Dst is a fixed vector, and both have the
2338145449b1SDimitry Andric // same element type, use the llvm.vector.extract intrinsic to perform the
2339145449b1SDimitry Andric // bitcast.
2340ac9a064cSDimitry Andric if (auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2341ac9a064cSDimitry Andric if (auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2342ac9a064cSDimitry Andric // If we are casting a scalable i1 predicate vector to a fixed i8
2343c0981da4SDimitry Andric // vector, bitcast the source and use a vector extract.
2344ac9a064cSDimitry Andric if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2345ac9a064cSDimitry Andric ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
2346ac9a064cSDimitry Andric FixedDstTy->getElementType()->isIntegerTy(8)) {
2347ac9a064cSDimitry Andric ScalableSrcTy = llvm::ScalableVectorType::get(
2348ac9a064cSDimitry Andric FixedDstTy->getElementType(),
2349ac9a064cSDimitry Andric ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2350ac9a064cSDimitry Andric Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2351c0981da4SDimitry Andric }
2352ac9a064cSDimitry Andric if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2353b60736ecSDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
23547fa27ce4SDimitry Andric return Builder.CreateExtractVector(DstTy, Src, Zero, "cast.fixed");
2355b60736ecSDimitry Andric }
2356b60736ecSDimitry Andric }
2357b60736ecSDimitry Andric }
2358b60736ecSDimitry Andric
2359b60736ecSDimitry Andric // Perform VLAT <-> VLST bitcast through memory.
2360ac9a064cSDimitry Andric // TODO: since the llvm.vector.{insert,extract} intrinsics
2361b60736ecSDimitry Andric // require the element types of the vectors to be the same, we
2362c0981da4SDimitry Andric // need to keep this around for bitcasts between VLAT <-> VLST where
2363c0981da4SDimitry Andric // the element types of the vectors are not the same, until we figure
2364c0981da4SDimitry Andric // out a better way of doing these casts.
2365b60736ecSDimitry Andric if ((isa<llvm::FixedVectorType>(SrcTy) &&
2366b60736ecSDimitry Andric isa<llvm::ScalableVectorType>(DstTy)) ||
2367b60736ecSDimitry Andric (isa<llvm::ScalableVectorType>(SrcTy) &&
2368b60736ecSDimitry Andric isa<llvm::FixedVectorType>(DstTy))) {
2369344a3780SDimitry Andric Address Addr = CGF.CreateDefaultAlignTempAlloca(SrcTy, "saved-value");
2370344a3780SDimitry Andric LValue LV = CGF.MakeAddrLValue(Addr, E->getType());
2371b60736ecSDimitry Andric CGF.EmitStoreOfScalar(Src, LV);
23727fa27ce4SDimitry Andric Addr = Addr.withElementType(CGF.ConvertTypeForMem(DestTy));
2373b60736ecSDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
2374b60736ecSDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
2375b60736ecSDimitry Andric return EmitLoadOfLValue(DestLV, CE->getExprLoc());
2376b60736ecSDimitry Andric }
2377ac9a064cSDimitry Andric
2378ac9a064cSDimitry Andric llvm::Value *Result = Builder.CreateBitCast(Src, DstTy);
2379ac9a064cSDimitry Andric return CGF.authPointerToPointerCast(Result, E->getType(), DestTy);
23809f4dbff6SDimitry Andric }
23819f4dbff6SDimitry Andric case CK_AddressSpaceConversion: {
2382bab175ecSDimitry Andric Expr::EvalResult Result;
2383bab175ecSDimitry Andric if (E->EvaluateAsRValue(Result, CGF.getContext()) &&
2384bab175ecSDimitry Andric Result.Val.isNullPointer()) {
2385bab175ecSDimitry Andric // If E has side effect, it is emitted even if its final result is a
2386bab175ecSDimitry Andric // null pointer. In that case, a DCE pass should be able to
2387bab175ecSDimitry Andric // eliminate the useless instructions emitted during translating E.
2388bab175ecSDimitry Andric if (Result.HasSideEffects)
2389bab175ecSDimitry Andric Visit(E);
2390bab175ecSDimitry Andric return CGF.CGM.getNullPointer(cast<llvm::PointerType>(
2391bab175ecSDimitry Andric ConvertType(DestTy)), DestTy);
2392bab175ecSDimitry Andric }
23932b6b257fSDimitry Andric // Since target may map different address spaces in AST to the same address
23942b6b257fSDimitry Andric // space, an address space conversion may end up as a bitcast.
2395aa803409SDimitry Andric return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
2396aa803409SDimitry Andric CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
2397aa803409SDimitry Andric DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
23984c8b2481SRoman Divacky }
2399dbe13110SDimitry Andric case CK_AtomicToNonAtomic:
2400dbe13110SDimitry Andric case CK_NonAtomicToAtomic:
24013d1dcd9bSDimitry Andric case CK_UserDefinedConversion:
2402b3d5a323SRoman Divacky return Visit(const_cast<Expr*>(E));
2403ec2b103cSEd Schouten
2404c0981da4SDimitry Andric case CK_NoOp: {
2405b1c73532SDimitry Andric return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
2406b1c73532SDimitry Andric : Visit(const_cast<Expr *>(E));
2407c0981da4SDimitry Andric }
2408c0981da4SDimitry Andric
24093d1dcd9bSDimitry Andric case CK_BaseToDerived: {
241013cc256eSDimitry Andric const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl();
241113cc256eSDimitry Andric assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!");
24121569ce68SRoman Divacky
241345b53394SDimitry Andric Address Base = CGF.EmitPointerWithAlignment(E);
241445b53394SDimitry Andric Address Derived =
241545b53394SDimitry Andric CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl,
2416bfef3995SDimitry Andric CE->path_begin(), CE->path_end(),
241745b53394SDimitry Andric CGF.ShouldNullCheckClassCastValue(CE));
2418bfef3995SDimitry Andric
2419809500fcSDimitry Andric // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
2420809500fcSDimitry Andric // performed and the object is not of the derived type.
24219f4dbff6SDimitry Andric if (CGF.sanitizePerformTypeCheck())
2422809500fcSDimitry Andric CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
2423ac9a064cSDimitry Andric Derived, DestTy->getPointeeType());
2424809500fcSDimitry Andric
24255e20cdd8SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast))
2426145449b1SDimitry Andric CGF.EmitVTablePtrCheckForCast(DestTy->getPointeeType(), Derived,
2427145449b1SDimitry Andric /*MayBeNull=*/true,
2428145449b1SDimitry Andric CodeGenFunction::CFITCK_DerivedCast,
2429676fbe81SDimitry Andric CE->getBeginLoc());
24305e20cdd8SDimitry Andric
2431ac9a064cSDimitry Andric return CGF.getAsNaturalPointerTo(Derived, CE->getType()->getPointeeType());
24321569ce68SRoman Divacky }
24333d1dcd9bSDimitry Andric case CK_UncheckedDerivedToBase:
24343d1dcd9bSDimitry Andric case CK_DerivedToBase: {
243545b53394SDimitry Andric // The EmitPointerWithAlignment path does this fine; just discard
243645b53394SDimitry Andric // the alignment.
2437ac9a064cSDimitry Andric return CGF.getAsNaturalPointerTo(CGF.EmitPointerWithAlignment(CE),
2438ac9a064cSDimitry Andric CE->getType()->getPointeeType());
2439ec2b103cSEd Schouten }
244045b53394SDimitry Andric
24413d1dcd9bSDimitry Andric case CK_Dynamic: {
244245b53394SDimitry Andric Address V = CGF.EmitPointerWithAlignment(E);
24431569ce68SRoman Divacky const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
24441569ce68SRoman Divacky return CGF.EmitDynamicCast(V, DCE);
24451569ce68SRoman Divacky }
24461569ce68SRoman Divacky
244745b53394SDimitry Andric case CK_ArrayToPointerDecay:
2448ac9a064cSDimitry Andric return CGF.getAsNaturalPointerTo(CGF.EmitArrayToPointerDecay(E),
2449ac9a064cSDimitry Andric CE->getType()->getPointeeType());
24503d1dcd9bSDimitry Andric case CK_FunctionToPointerDecay:
2451706b4fc4SDimitry Andric return EmitLValue(E).getPointer(CGF);
2452b3d5a323SRoman Divacky
2453bca07a45SDimitry Andric case CK_NullToPointer:
2454bca07a45SDimitry Andric if (MustVisitNullValue(E))
245522989816SDimitry Andric CGF.EmitIgnoredExpr(E);
2456bca07a45SDimitry Andric
2457bab175ecSDimitry Andric return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
2458bab175ecSDimitry Andric DestTy);
2459bca07a45SDimitry Andric
24603d1dcd9bSDimitry Andric case CK_NullToMemberPointer: {
2461bca07a45SDimitry Andric if (MustVisitNullValue(E))
246222989816SDimitry Andric CGF.EmitIgnoredExpr(E);
2463ec2b103cSEd Schouten
24643d1dcd9bSDimitry Andric const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
24653d1dcd9bSDimitry Andric return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
24663d1dcd9bSDimitry Andric }
24673d1dcd9bSDimitry Andric
2468dbe13110SDimitry Andric case CK_ReinterpretMemberPointer:
24693d1dcd9bSDimitry Andric case CK_BaseToDerivedMemberPointer:
24703d1dcd9bSDimitry Andric case CK_DerivedToBaseMemberPointer: {
24711569ce68SRoman Divacky Value *Src = Visit(E);
24721569ce68SRoman Divacky
24733d1dcd9bSDimitry Andric // Note that the AST doesn't distinguish between checked and
24743d1dcd9bSDimitry Andric // unchecked member pointer conversions, so we always have to
24753d1dcd9bSDimitry Andric // implement checked conversions here. This is inefficient when
24763d1dcd9bSDimitry Andric // actual control flow may be required in order to perform the
24773d1dcd9bSDimitry Andric // check, which it is for data member pointers (but not member
24783d1dcd9bSDimitry Andric // function pointers on Itanium and ARM).
24793d1dcd9bSDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);
24801569ce68SRoman Divacky }
24814ba67500SRoman Divacky
248236981b17SDimitry Andric case CK_ARCProduceObject:
2483180abc3dSDimitry Andric return CGF.EmitARCRetainScalarExpr(E);
248436981b17SDimitry Andric case CK_ARCConsumeObject:
2485180abc3dSDimitry Andric return CGF.EmitObjCConsumeObject(E->getType(), Visit(E));
24862b6b257fSDimitry Andric case CK_ARCReclaimReturnedObject:
24872b6b257fSDimitry Andric return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored);
248836981b17SDimitry Andric case CK_ARCExtendBlockObject:
248936981b17SDimitry Andric return CGF.EmitARCExtendBlockObject(E);
2490180abc3dSDimitry Andric
2491dbe13110SDimitry Andric case CK_CopyAndAutoreleaseBlockObject:
2492dbe13110SDimitry Andric return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType());
2493dbe13110SDimitry Andric
2494bca07a45SDimitry Andric case CK_FloatingRealToComplex:
2495bca07a45SDimitry Andric case CK_FloatingComplexCast:
2496bca07a45SDimitry Andric case CK_IntegralRealToComplex:
2497bca07a45SDimitry Andric case CK_IntegralComplexCast:
2498bca07a45SDimitry Andric case CK_IntegralComplexToFloatingComplex:
2499bca07a45SDimitry Andric case CK_FloatingComplexToIntegralComplex:
25003d1dcd9bSDimitry Andric case CK_ConstructorConversion:
2501bca07a45SDimitry Andric case CK_ToUnion:
2502ac9a064cSDimitry Andric case CK_HLSLArrayRValue:
2503bca07a45SDimitry Andric llvm_unreachable("scalar cast to non-scalar value");
2504bca07a45SDimitry Andric
2505bca07a45SDimitry Andric case CK_LValueToRValue:
2506bca07a45SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
2507bca07a45SDimitry Andric assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!");
2508bca07a45SDimitry Andric return Visit(const_cast<Expr*>(E));
2509bca07a45SDimitry Andric
25103d1dcd9bSDimitry Andric case CK_IntegralToPointer: {
25114c8b2481SRoman Divacky Value *Src = Visit(const_cast<Expr*>(E));
251273490b89SRoman Divacky
251373490b89SRoman Divacky // First, convert to the correct width so that we control the kind of
251473490b89SRoman Divacky // extension.
2515bab175ecSDimitry Andric auto DestLLVMTy = ConvertType(DestTy);
2516bab175ecSDimitry Andric llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy);
251729cafa66SDimitry Andric bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType();
251873490b89SRoman Divacky llvm::Value* IntResult =
251973490b89SRoman Divacky Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
252073490b89SRoman Divacky
252148675466SDimitry Andric auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
25223d1dcd9bSDimitry Andric
252348675466SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
252448675466SDimitry Andric // Going from integer to pointer that could be dynamic requires reloading
252548675466SDimitry Andric // dynamic information from invariant.group.
252648675466SDimitry Andric if (DestTy.mayBeDynamicClass())
252748675466SDimitry Andric IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
252848675466SDimitry Andric }
2529ac9a064cSDimitry Andric
2530ac9a064cSDimitry Andric IntToPtr = CGF.authPointerToPointerCast(IntToPtr, E->getType(), DestTy);
253148675466SDimitry Andric return IntToPtr;
253248675466SDimitry Andric }
253348675466SDimitry Andric case CK_PointerToIntegral: {
253448675466SDimitry Andric assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
253548675466SDimitry Andric auto *PtrExpr = Visit(E);
253648675466SDimitry Andric
253748675466SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
253848675466SDimitry Andric const QualType SrcType = E->getType();
253948675466SDimitry Andric
254048675466SDimitry Andric // Casting to integer requires stripping dynamic information as it does
254148675466SDimitry Andric // not carries it.
254248675466SDimitry Andric if (SrcType.mayBeDynamicClass())
254348675466SDimitry Andric PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
254448675466SDimitry Andric }
254548675466SDimitry Andric
2546ac9a064cSDimitry Andric PtrExpr = CGF.authPointerToPointerCast(PtrExpr, E->getType(), DestTy);
254748675466SDimitry Andric return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
254848675466SDimitry Andric }
25493d1dcd9bSDimitry Andric case CK_ToVoid: {
2550bca07a45SDimitry Andric CGF.EmitIgnoredExpr(E);
25519f4dbff6SDimitry Andric return nullptr;
2552b3d5a323SRoman Divacky }
2553344a3780SDimitry Andric case CK_MatrixCast: {
2554344a3780SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2555344a3780SDimitry Andric CE->getExprLoc());
2556344a3780SDimitry Andric }
25573d1dcd9bSDimitry Andric case CK_VectorSplat: {
255836981b17SDimitry Andric llvm::Type *DstTy = ConvertType(DestTy);
25590414e226SDimitry Andric Value *Elt = Visit(const_cast<Expr *>(E));
2560b3d5a323SRoman Divacky // Splat the element across to all elements
2561145449b1SDimitry Andric llvm::ElementCount NumElements =
2562145449b1SDimitry Andric cast<llvm::VectorType>(DstTy)->getElementCount();
25639f4dbff6SDimitry Andric return Builder.CreateVectorSplat(NumElements, Elt, "splat");
2564b3d5a323SRoman Divacky }
2565bca07a45SDimitry Andric
2566676fbe81SDimitry Andric case CK_FixedPointCast:
2567676fbe81SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2568676fbe81SDimitry Andric CE->getExprLoc());
2569676fbe81SDimitry Andric
2570676fbe81SDimitry Andric case CK_FixedPointToBoolean:
2571676fbe81SDimitry Andric assert(E->getType()->isFixedPointType() &&
2572676fbe81SDimitry Andric "Expected src type to be fixed point type");
2573676fbe81SDimitry Andric assert(DestTy->isBooleanType() && "Expected dest type to be boolean type");
2574676fbe81SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2575676fbe81SDimitry Andric CE->getExprLoc());
2576676fbe81SDimitry Andric
257722989816SDimitry Andric case CK_FixedPointToIntegral:
257822989816SDimitry Andric assert(E->getType()->isFixedPointType() &&
257922989816SDimitry Andric "Expected src type to be fixed point type");
258022989816SDimitry Andric assert(DestTy->isIntegerType() && "Expected dest type to be an integer");
258122989816SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
258222989816SDimitry Andric CE->getExprLoc());
258322989816SDimitry Andric
258422989816SDimitry Andric case CK_IntegralToFixedPoint:
258522989816SDimitry Andric assert(E->getType()->isIntegerType() &&
258622989816SDimitry Andric "Expected src type to be an integer");
258722989816SDimitry Andric assert(DestTy->isFixedPointType() &&
258822989816SDimitry Andric "Expected dest type to be fixed point type");
258922989816SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
259022989816SDimitry Andric CE->getExprLoc());
259122989816SDimitry Andric
2592c7e70c43SDimitry Andric case CK_IntegralCast: {
2593ac9a064cSDimitry Andric if (E->getType()->isExtVectorType() && DestTy->isExtVectorType()) {
2594ac9a064cSDimitry Andric QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType();
2595ac9a064cSDimitry Andric return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2596ac9a064cSDimitry Andric SrcElTy->isSignedIntegerOrEnumerationType(),
2597ac9a064cSDimitry Andric "conv");
2598ac9a064cSDimitry Andric }
2599c7e70c43SDimitry Andric ScalarConversionOpts Opts;
2600676fbe81SDimitry Andric if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2601676fbe81SDimitry Andric if (!ICE->isPartOfExplicitCast())
2602676fbe81SDimitry Andric Opts = ScalarConversionOpts(CGF.SanOpts);
2603c7e70c43SDimitry Andric }
2604c7e70c43SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2605c7e70c43SDimitry Andric CE->getExprLoc(), Opts);
2606c7e70c43SDimitry Andric }
2607ac9a064cSDimitry Andric case CK_IntegralToFloating: {
2608ac9a064cSDimitry Andric if (E->getType()->isVectorType() && DestTy->isVectorType()) {
2609ac9a064cSDimitry Andric // TODO: Support constrained FP intrinsics.
2610ac9a064cSDimitry Andric QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType();
2611ac9a064cSDimitry Andric if (SrcElTy->isSignedIntegerOrEnumerationType())
2612ac9a064cSDimitry Andric return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy), "conv");
2613ac9a064cSDimitry Andric return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy), "conv");
2614ac9a064cSDimitry Andric }
2615ac9a064cSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2616ac9a064cSDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2617ac9a064cSDimitry Andric CE->getExprLoc());
2618ac9a064cSDimitry Andric }
2619ac9a064cSDimitry Andric case CK_FloatingToIntegral: {
2620ac9a064cSDimitry Andric if (E->getType()->isVectorType() && DestTy->isVectorType()) {
2621ac9a064cSDimitry Andric // TODO: Support constrained FP intrinsics.
2622ac9a064cSDimitry Andric QualType DstElTy = DestTy->castAs<VectorType>()->getElementType();
2623ac9a064cSDimitry Andric if (DstElTy->isSignedIntegerOrEnumerationType())
2624ac9a064cSDimitry Andric return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy), "conv");
2625ac9a064cSDimitry Andric return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy), "conv");
2626ac9a064cSDimitry Andric }
2627ac9a064cSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2628ac9a064cSDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2629ac9a064cSDimitry Andric CE->getExprLoc());
2630ac9a064cSDimitry Andric }
2631ac9a064cSDimitry Andric case CK_FloatingCast: {
2632ac9a064cSDimitry Andric if (E->getType()->isVectorType() && DestTy->isVectorType()) {
2633ac9a064cSDimitry Andric // TODO: Support constrained FP intrinsics.
2634ac9a064cSDimitry Andric QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType();
2635ac9a064cSDimitry Andric QualType DstElTy = DestTy->castAs<VectorType>()->getElementType();
2636ac9a064cSDimitry Andric if (DstElTy->castAs<BuiltinType>()->getKind() <
2637ac9a064cSDimitry Andric SrcElTy->castAs<BuiltinType>()->getKind())
2638ac9a064cSDimitry Andric return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy), "conv");
2639ac9a064cSDimitry Andric return Builder.CreateFPExt(Visit(E), ConvertType(DestTy), "conv");
2640ac9a064cSDimitry Andric }
2641ac9a064cSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2642ac9a064cSDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2643ac9a064cSDimitry Andric CE->getExprLoc());
2644ac9a064cSDimitry Andric }
2645b60736ecSDimitry Andric case CK_FixedPointToFloating:
2646b60736ecSDimitry Andric case CK_FloatingToFixedPoint: {
2647b60736ecSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
264845b53394SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
264945b53394SDimitry Andric CE->getExprLoc());
2650b60736ecSDimitry Andric }
2651c7e70c43SDimitry Andric case CK_BooleanToSignedIntegral: {
2652c7e70c43SDimitry Andric ScalarConversionOpts Opts;
2653c7e70c43SDimitry Andric Opts.TreatBooleanAsSigned = true;
26540414e226SDimitry Andric return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2655c7e70c43SDimitry Andric CE->getExprLoc(), Opts);
2656c7e70c43SDimitry Andric }
2657bca07a45SDimitry Andric case CK_IntegralToBoolean:
2658bca07a45SDimitry Andric return EmitIntToBoolConversion(Visit(E));
2659bca07a45SDimitry Andric case CK_PointerToBoolean:
2660bab175ecSDimitry Andric return EmitPointerToBoolConversion(Visit(E), E->getType());
2661b60736ecSDimitry Andric case CK_FloatingToBoolean: {
2662b60736ecSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2663bca07a45SDimitry Andric return EmitFloatToBoolConversion(Visit(E));
2664b60736ecSDimitry Andric }
26653d1dcd9bSDimitry Andric case CK_MemberPointerToBoolean: {
26663d1dcd9bSDimitry Andric llvm::Value *MemPtr = Visit(E);
26673d1dcd9bSDimitry Andric const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
26683d1dcd9bSDimitry Andric return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
26693d1dcd9bSDimitry Andric }
2670ec2b103cSEd Schouten
2671bca07a45SDimitry Andric case CK_FloatingComplexToReal:
2672bca07a45SDimitry Andric case CK_IntegralComplexToReal:
2673bca07a45SDimitry Andric return CGF.EmitComplexExpr(E, false, true).first;
2674ec2b103cSEd Schouten
2675bca07a45SDimitry Andric case CK_FloatingComplexToBoolean:
2676bca07a45SDimitry Andric case CK_IntegralComplexToBoolean: {
2677bca07a45SDimitry Andric CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
2678ec2b103cSEd Schouten
2679bca07a45SDimitry Andric // TODO: kill this function off, inline appropriate case here
268045b53394SDimitry Andric return EmitComplexToScalarConversion(V, E->getType(), DestTy,
268145b53394SDimitry Andric CE->getExprLoc());
2682ec2b103cSEd Schouten }
2683ec2b103cSEd Schouten
2684676fbe81SDimitry Andric case CK_ZeroToOCLOpaqueType: {
2685676fbe81SDimitry Andric assert((DestTy->isEventT() || DestTy->isQueueT() ||
2686676fbe81SDimitry Andric DestTy->isOCLIntelSubgroupAVCType()) &&
2687676fbe81SDimitry Andric "CK_ZeroToOCLEvent cast on non-event type");
2688bab175ecSDimitry Andric return llvm::Constant::getNullValue(ConvertType(DestTy));
2689bca07a45SDimitry Andric }
2690bca07a45SDimitry Andric
2691bab175ecSDimitry Andric case CK_IntToOCLSampler:
2692bab175ecSDimitry Andric return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
2693bab175ecSDimitry Andric
2694ac9a064cSDimitry Andric case CK_HLSLVectorTruncation: {
2695ac9a064cSDimitry Andric assert(DestTy->isVectorType() && "Expected dest type to be vector type");
2696ac9a064cSDimitry Andric Value *Vec = Visit(const_cast<Expr *>(E));
2697ac9a064cSDimitry Andric SmallVector<int, 16> Mask;
2698ac9a064cSDimitry Andric unsigned NumElts = DestTy->castAs<VectorType>()->getNumElements();
2699ac9a064cSDimitry Andric for (unsigned I = 0; I != NumElts; ++I)
2700ac9a064cSDimitry Andric Mask.push_back(I);
2701ac9a064cSDimitry Andric
2702ac9a064cSDimitry Andric return Builder.CreateShuffleVector(Vec, Mask, "trunc");
2703ac9a064cSDimitry Andric }
2704ac9a064cSDimitry Andric
2705bab175ecSDimitry Andric } // end of switch
2706bab175ecSDimitry Andric
2707bca07a45SDimitry Andric llvm_unreachable("unknown scalar cast");
2708ec2b103cSEd Schouten }
2709ec2b103cSEd Schouten
VisitStmtExpr(const StmtExpr * E)2710ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
2711bca07a45SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF);
271245b53394SDimitry Andric Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(),
2713bfef3995SDimitry Andric !E->getType()->isVoidType());
271445b53394SDimitry Andric if (!RetAlloca.isValid())
27159f4dbff6SDimitry Andric return nullptr;
2716bfef3995SDimitry Andric return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()),
2717bfef3995SDimitry Andric E->getExprLoc());
2718ec2b103cSEd Schouten }
2719ec2b103cSEd Schouten
VisitExprWithCleanups(ExprWithCleanups * E)27207442d6faSDimitry Andric Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
27217442d6faSDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF);
27227442d6faSDimitry Andric Value *V = Visit(E->getSubExpr());
27237442d6faSDimitry Andric // Defend against dominance problems caused by jumps out of expression
27247442d6faSDimitry Andric // evaluation through the shared cleanup block.
27257442d6faSDimitry Andric Scope.ForceCleanup({&V});
27267442d6faSDimitry Andric return V;
27277442d6faSDimitry Andric }
27287442d6faSDimitry Andric
2729ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
2730ec2b103cSEd Schouten // Unary Operators
2731ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
2732ec2b103cSEd Schouten
createBinOpInfoFromIncDec(const UnaryOperator * E,llvm::Value * InVal,bool IsInc,FPOptions FPFeatures)27335e20cdd8SDimitry Andric static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
2734cfca06d7SDimitry Andric llvm::Value *InVal, bool IsInc,
2735cfca06d7SDimitry Andric FPOptions FPFeatures) {
27364ba67500SRoman Divacky BinOpInfo BinOp;
27374ba67500SRoman Divacky BinOp.LHS = InVal;
27385e20cdd8SDimitry Andric BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
27394ba67500SRoman Divacky BinOp.Ty = E->getType();
27405e20cdd8SDimitry Andric BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
2741cfca06d7SDimitry Andric BinOp.FPFeatures = FPFeatures;
27424ba67500SRoman Divacky BinOp.E = E;
27435e20cdd8SDimitry Andric return BinOp;
27445e20cdd8SDimitry Andric }
27455e20cdd8SDimitry Andric
EmitIncDecConsiderOverflowBehavior(const UnaryOperator * E,llvm::Value * InVal,bool IsInc)27465e20cdd8SDimitry Andric llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
27475e20cdd8SDimitry Andric const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {
27485e20cdd8SDimitry Andric llvm::Value *Amount =
27495e20cdd8SDimitry Andric llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true);
27505e20cdd8SDimitry Andric StringRef Name = IsInc ? "inc" : "dec";
27515e20cdd8SDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
27525e20cdd8SDimitry Andric case LangOptions::SOB_Defined:
2753ac9a064cSDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
27545e20cdd8SDimitry Andric return Builder.CreateAdd(InVal, Amount, Name);
2755ac9a064cSDimitry Andric [[fallthrough]];
27565e20cdd8SDimitry Andric case LangOptions::SOB_Undefined:
27575e20cdd8SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
27585e20cdd8SDimitry Andric return Builder.CreateNSWAdd(InVal, Amount, Name);
2759e3b55780SDimitry Andric [[fallthrough]];
27605e20cdd8SDimitry Andric case LangOptions::SOB_Trapping:
276148675466SDimitry Andric if (!E->canOverflow())
27627442d6faSDimitry Andric return Builder.CreateNSWAdd(InVal, Amount, Name);
2763cfca06d7SDimitry Andric return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
2764cfca06d7SDimitry Andric E, InVal, IsInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
27654ba67500SRoman Divacky }
276636981b17SDimitry Andric llvm_unreachable("Unknown SignedOverflowBehaviorTy");
27674ba67500SRoman Divacky }
2768bca07a45SDimitry Andric
2769706b4fc4SDimitry Andric namespace {
2770706b4fc4SDimitry Andric /// Handles check and update for lastprivate conditional variables.
2771706b4fc4SDimitry Andric class OMPLastprivateConditionalUpdateRAII {
2772706b4fc4SDimitry Andric private:
2773706b4fc4SDimitry Andric CodeGenFunction &CGF;
2774706b4fc4SDimitry Andric const UnaryOperator *E;
2775706b4fc4SDimitry Andric
2776706b4fc4SDimitry Andric public:
OMPLastprivateConditionalUpdateRAII(CodeGenFunction & CGF,const UnaryOperator * E)2777706b4fc4SDimitry Andric OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
2778706b4fc4SDimitry Andric const UnaryOperator *E)
2779706b4fc4SDimitry Andric : CGF(CGF), E(E) {}
~OMPLastprivateConditionalUpdateRAII()2780706b4fc4SDimitry Andric ~OMPLastprivateConditionalUpdateRAII() {
2781706b4fc4SDimitry Andric if (CGF.getLangOpts().OpenMP)
2782706b4fc4SDimitry Andric CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(
2783706b4fc4SDimitry Andric CGF, E->getSubExpr());
2784706b4fc4SDimitry Andric }
2785706b4fc4SDimitry Andric };
2786706b4fc4SDimitry Andric } // namespace
2787706b4fc4SDimitry Andric
2788bca07a45SDimitry Andric llvm::Value *
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)2789bca07a45SDimitry Andric ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
2790bca07a45SDimitry Andric bool isInc, bool isPre) {
2791706b4fc4SDimitry Andric OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
2792bca07a45SDimitry Andric QualType type = E->getSubExpr()->getType();
27939f4dbff6SDimitry Andric llvm::PHINode *atomicPHI = nullptr;
2794809500fcSDimitry Andric llvm::Value *value;
2795809500fcSDimitry Andric llvm::Value *input;
2796ac9a064cSDimitry Andric llvm::Value *Previous = nullptr;
2797ac9a064cSDimitry Andric QualType SrcType = E->getType();
2798bca07a45SDimitry Andric
2799bca07a45SDimitry Andric int amount = (isInc ? 1 : -1);
2800de51d671SDimitry Andric bool isSubtraction = !isInc;
2801bca07a45SDimitry Andric
2802dbe13110SDimitry Andric if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
2803809500fcSDimitry Andric type = atomicTy->getValueType();
2804809500fcSDimitry Andric if (isInc && type->isBooleanType()) {
2805809500fcSDimitry Andric llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type);
2806809500fcSDimitry Andric if (isPre) {
2807ac9a064cSDimitry Andric Builder.CreateStore(True, LV.getAddress(), LV.isVolatileQualified())
28082b6b257fSDimitry Andric ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
2809809500fcSDimitry Andric return Builder.getTrue();
2810809500fcSDimitry Andric }
2811809500fcSDimitry Andric // For atomic bool increment, we just store true and return it for
2812809500fcSDimitry Andric // preincrement, do an atomic swap with true for postincrement
28132b6b257fSDimitry Andric return Builder.CreateAtomicRMW(
2814ac9a064cSDimitry Andric llvm::AtomicRMWInst::Xchg, LV.getAddress(), True,
28152b6b257fSDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
2816809500fcSDimitry Andric }
2817809500fcSDimitry Andric // Special case for atomic increment / decrement on integers, emit
2818809500fcSDimitry Andric // atomicrmw instructions. We skip this if we want to be doing overflow
2819809500fcSDimitry Andric // checking, and fall into the slow path with the atomic cmpxchg loop.
2820809500fcSDimitry Andric if (!type->isBooleanType() && type->isIntegerType() &&
2821809500fcSDimitry Andric !(type->isUnsignedIntegerType() &&
282206d4ba38SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
2823809500fcSDimitry Andric CGF.getLangOpts().getSignedOverflowBehavior() !=
2824809500fcSDimitry Andric LangOptions::SOB_Trapping) {
2825809500fcSDimitry Andric llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
2826809500fcSDimitry Andric llvm::AtomicRMWInst::Sub;
2827809500fcSDimitry Andric llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
2828809500fcSDimitry Andric llvm::Instruction::Sub;
2829809500fcSDimitry Andric llvm::Value *amt = CGF.EmitToMemory(
2830809500fcSDimitry Andric llvm::ConstantInt::get(ConvertType(type), 1, true), type);
2831706b4fc4SDimitry Andric llvm::Value *old =
2832ac9a064cSDimitry Andric Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
2833ac9a064cSDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
2834ac9a064cSDimitry Andric return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2835ac9a064cSDimitry Andric }
283603706295SDimitry Andric // Special case for atomic increment/decrement on floats.
283703706295SDimitry Andric // Bail out non-power-of-2-sized floating point types (e.g., x86_fp80).
2838ac9a064cSDimitry Andric if (type->isFloatingType()) {
283903706295SDimitry Andric llvm::Type *Ty = ConvertType(type);
284003706295SDimitry Andric if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
2841ac9a064cSDimitry Andric llvm::AtomicRMWInst::BinOp aop =
2842ac9a064cSDimitry Andric isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
2843ac9a064cSDimitry Andric llvm::Instruction::BinaryOps op =
2844ac9a064cSDimitry Andric isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
284503706295SDimitry Andric llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
284603706295SDimitry Andric llvm::AtomicRMWInst *old = Builder.CreateAtomicRMW(
284703706295SDimitry Andric aop, LV.getAddress(), amt,
2848706b4fc4SDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
284903706295SDimitry Andric
2850809500fcSDimitry Andric return isPre ? Builder.CreateBinOp(op, old, amt) : old;
2851809500fcSDimitry Andric }
285203706295SDimitry Andric }
2853bfef3995SDimitry Andric value = EmitLoadOfLValue(LV, E->getExprLoc());
2854809500fcSDimitry Andric input = value;
2855809500fcSDimitry Andric // For every other atomic operation, we need to emit a load-op-cmpxchg loop
2856dbe13110SDimitry Andric llvm::BasicBlock *startBB = Builder.GetInsertBlock();
2857dbe13110SDimitry Andric llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
2858809500fcSDimitry Andric value = CGF.EmitToMemory(value, type);
2859dbe13110SDimitry Andric Builder.CreateBr(opBB);
2860dbe13110SDimitry Andric Builder.SetInsertPoint(opBB);
2861dbe13110SDimitry Andric atomicPHI = Builder.CreatePHI(value->getType(), 2);
2862dbe13110SDimitry Andric atomicPHI->addIncoming(value, startBB);
2863dbe13110SDimitry Andric value = atomicPHI;
2864809500fcSDimitry Andric } else {
2865bfef3995SDimitry Andric value = EmitLoadOfLValue(LV, E->getExprLoc());
2866809500fcSDimitry Andric input = value;
2867dbe13110SDimitry Andric }
2868dbe13110SDimitry Andric
2869bca07a45SDimitry Andric // Special case of integer increment that we have to check first: bool++.
2870bca07a45SDimitry Andric // Due to promotion rules, we get:
2871bca07a45SDimitry Andric // bool++ -> bool = bool + 1
2872bca07a45SDimitry Andric // -> bool = (int)bool + 1
2873bca07a45SDimitry Andric // -> bool = ((int)bool + 1 != 0)
2874bca07a45SDimitry Andric // An interesting aspect of this is that increment is always true.
2875bca07a45SDimitry Andric // Decrement does not have this property.
2876bca07a45SDimitry Andric if (isInc && type->isBooleanType()) {
2877bca07a45SDimitry Andric value = Builder.getTrue();
2878bca07a45SDimitry Andric
2879bca07a45SDimitry Andric // Most common case by far: integer increment.
2880bca07a45SDimitry Andric } else if (type->isIntegerType()) {
2881706b4fc4SDimitry Andric QualType promotedType;
2882706b4fc4SDimitry Andric bool canPerformLossyDemotionCheck = false;
2883e3b55780SDimitry Andric if (CGF.getContext().isPromotableIntegerType(type)) {
2884706b4fc4SDimitry Andric promotedType = CGF.getContext().getPromotedIntegerType(type);
2885706b4fc4SDimitry Andric assert(promotedType != type && "Shouldn't promote to the same type.");
2886706b4fc4SDimitry Andric canPerformLossyDemotionCheck = true;
2887706b4fc4SDimitry Andric canPerformLossyDemotionCheck &=
2888706b4fc4SDimitry Andric CGF.getContext().getCanonicalType(type) !=
2889706b4fc4SDimitry Andric CGF.getContext().getCanonicalType(promotedType);
2890706b4fc4SDimitry Andric canPerformLossyDemotionCheck &=
2891706b4fc4SDimitry Andric PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
2892706b4fc4SDimitry Andric type, promotedType);
2893706b4fc4SDimitry Andric assert((!canPerformLossyDemotionCheck ||
2894706b4fc4SDimitry Andric type->isSignedIntegerOrEnumerationType() ||
2895706b4fc4SDimitry Andric promotedType->isSignedIntegerOrEnumerationType() ||
2896706b4fc4SDimitry Andric ConvertType(type)->getScalarSizeInBits() ==
2897706b4fc4SDimitry Andric ConvertType(promotedType)->getScalarSizeInBits()) &&
2898706b4fc4SDimitry Andric "The following check expects that if we do promotion to different "
2899706b4fc4SDimitry Andric "underlying canonical type, at least one of the types (either "
2900706b4fc4SDimitry Andric "base or promoted) will be signed, or the bitwidths will match.");
2901706b4fc4SDimitry Andric }
2902706b4fc4SDimitry Andric if (CGF.SanOpts.hasOneOf(
2903ac9a064cSDimitry Andric SanitizerKind::ImplicitIntegerArithmeticValueChange |
2904ac9a064cSDimitry Andric SanitizerKind::ImplicitBitfieldConversion) &&
2905706b4fc4SDimitry Andric canPerformLossyDemotionCheck) {
2906706b4fc4SDimitry Andric // While `x += 1` (for `x` with width less than int) is modeled as
2907706b4fc4SDimitry Andric // promotion+arithmetics+demotion, and we can catch lossy demotion with
2908706b4fc4SDimitry Andric // ease; inc/dec with width less than int can't overflow because of
2909706b4fc4SDimitry Andric // promotion rules, so we omit promotion+demotion, which means that we can
2910706b4fc4SDimitry Andric // not catch lossy "demotion". Because we still want to catch these cases
2911706b4fc4SDimitry Andric // when the sanitizer is enabled, we perform the promotion, then perform
2912706b4fc4SDimitry Andric // the increment/decrement in the wider type, and finally
2913706b4fc4SDimitry Andric // perform the demotion. This will catch lossy demotions.
2914706b4fc4SDimitry Andric
2915ac9a064cSDimitry Andric // We have a special case for bitfields defined using all the bits of the
2916ac9a064cSDimitry Andric // type. In this case we need to do the same trick as for the integer
2917ac9a064cSDimitry Andric // sanitizer checks, i.e., promotion -> increment/decrement -> demotion.
2918ac9a064cSDimitry Andric
2919706b4fc4SDimitry Andric value = EmitScalarConversion(value, type, promotedType, E->getExprLoc());
2920706b4fc4SDimitry Andric Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
2921706b4fc4SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
2922706b4fc4SDimitry Andric // Do pass non-default ScalarConversionOpts so that sanitizer check is
2923ac9a064cSDimitry Andric // emitted if LV is not a bitfield, otherwise the bitfield sanitizer
2924ac9a064cSDimitry Andric // checks will take care of the conversion.
2925ac9a064cSDimitry Andric ScalarConversionOpts Opts;
2926ac9a064cSDimitry Andric if (!LV.isBitField())
2927ac9a064cSDimitry Andric Opts = ScalarConversionOpts(CGF.SanOpts);
2928ac9a064cSDimitry Andric else if (CGF.SanOpts.has(SanitizerKind::ImplicitBitfieldConversion)) {
2929ac9a064cSDimitry Andric Previous = value;
2930ac9a064cSDimitry Andric SrcType = promotedType;
2931ac9a064cSDimitry Andric }
2932ac9a064cSDimitry Andric
2933706b4fc4SDimitry Andric value = EmitScalarConversion(value, promotedType, type, E->getExprLoc(),
2934ac9a064cSDimitry Andric Opts);
2935706b4fc4SDimitry Andric
293601af97d3SDimitry Andric // Note that signed integer inc/dec with width less than int can't
2937706b4fc4SDimitry Andric // overflow because of promotion rules; we're just eliding a few steps
2938706b4fc4SDimitry Andric // here.
2939706b4fc4SDimitry Andric } else if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
29405e20cdd8SDimitry Andric value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
294148675466SDimitry Andric } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
294206d4ba38SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
2943cfca06d7SDimitry Andric value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
2944cfca06d7SDimitry Andric E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
29455e20cdd8SDimitry Andric } else {
29465e20cdd8SDimitry Andric llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
2947bca07a45SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
29485e20cdd8SDimitry Andric }
2949bca07a45SDimitry Andric
2950bca07a45SDimitry Andric // Next most common: pointer increment.
2951bca07a45SDimitry Andric } else if (const PointerType *ptr = type->getAs<PointerType>()) {
2952bca07a45SDimitry Andric QualType type = ptr->getPointeeType();
2953bca07a45SDimitry Andric
2954bca07a45SDimitry Andric // VLA types don't have constant size.
2955180abc3dSDimitry Andric if (const VariableArrayType *vla
2956180abc3dSDimitry Andric = CGF.getContext().getAsVariableArrayType(type)) {
295748675466SDimitry Andric llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
2958180abc3dSDimitry Andric if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
2959145449b1SDimitry Andric llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
296013cc256eSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
296177fc4c14SDimitry Andric value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc");
296201af97d3SDimitry Andric else
2963de51d671SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(
296477fc4c14SDimitry Andric elemTy, value, numElts, /*SignedIndices=*/false, isSubtraction,
2965325377b5SDimitry Andric E->getExprLoc(), "vla.inc");
2966bca07a45SDimitry Andric
2967bca07a45SDimitry Andric // Arithmetic on function pointers (!) is just +-1.
2968bca07a45SDimitry Andric } else if (type->isFunctionType()) {
296901af97d3SDimitry Andric llvm::Value *amt = Builder.getInt32(amount);
2970bca07a45SDimitry Andric
297113cc256eSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
2972344a3780SDimitry Andric value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
297301af97d3SDimitry Andric else
29747fa27ce4SDimitry Andric value =
29757fa27ce4SDimitry Andric CGF.EmitCheckedInBoundsGEP(CGF.Int8Ty, value, amt,
29767fa27ce4SDimitry Andric /*SignedIndices=*/false, isSubtraction,
29777fa27ce4SDimitry Andric E->getExprLoc(), "incdec.funcptr");
2978bca07a45SDimitry Andric
2979bca07a45SDimitry Andric // For everything else, we can just do a simple increment.
29804ba67500SRoman Divacky } else {
298101af97d3SDimitry Andric llvm::Value *amt = Builder.getInt32(amount);
298277fc4c14SDimitry Andric llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
298313cc256eSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
298477fc4c14SDimitry Andric value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr");
298501af97d3SDimitry Andric else
298677fc4c14SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(
298777fc4c14SDimitry Andric elemTy, value, amt, /*SignedIndices=*/false, isSubtraction,
298877fc4c14SDimitry Andric E->getExprLoc(), "incdec.ptr");
2989bca07a45SDimitry Andric }
2990bca07a45SDimitry Andric
2991bca07a45SDimitry Andric // Vector increment/decrement.
2992bca07a45SDimitry Andric } else if (type->isVectorType()) {
2993bca07a45SDimitry Andric if (type->hasIntegerRepresentation()) {
2994bca07a45SDimitry Andric llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
2995bca07a45SDimitry Andric
2996bca07a45SDimitry Andric value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
2997bca07a45SDimitry Andric } else {
2998bca07a45SDimitry Andric value = Builder.CreateFAdd(
2999bca07a45SDimitry Andric value,
3000bca07a45SDimitry Andric llvm::ConstantFP::get(value->getType(), amount),
3001bca07a45SDimitry Andric isInc ? "inc" : "dec");
3002bca07a45SDimitry Andric }
3003bca07a45SDimitry Andric
3004bca07a45SDimitry Andric // Floating point.
3005bca07a45SDimitry Andric } else if (type->isRealFloatingType()) {
30064ba67500SRoman Divacky // Add the inc/dec to the real part.
3007bca07a45SDimitry Andric llvm::Value *amt;
3008b60736ecSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
300936981b17SDimitry Andric
30105e20cdd8SDimitry Andric if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
301136981b17SDimitry Andric // Another special case: half FP increment should be done via float
3012461a67faSDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
30139f4dbff6SDimitry Andric value = Builder.CreateCall(
30149f4dbff6SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
30159f4dbff6SDimitry Andric CGF.CGM.FloatTy),
30165e20cdd8SDimitry Andric input, "incdec.conv");
30175e20cdd8SDimitry Andric } else {
30185e20cdd8SDimitry Andric value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv");
30195e20cdd8SDimitry Andric }
302036981b17SDimitry Andric }
302136981b17SDimitry Andric
3022bca07a45SDimitry Andric if (value->getType()->isFloatTy())
3023bca07a45SDimitry Andric amt = llvm::ConstantFP::get(VMContext,
3024bca07a45SDimitry Andric llvm::APFloat(static_cast<float>(amount)));
3025bca07a45SDimitry Andric else if (value->getType()->isDoubleTy())
3026bca07a45SDimitry Andric amt = llvm::ConstantFP::get(VMContext,
3027bca07a45SDimitry Andric llvm::APFloat(static_cast<double>(amount)));
30284ba67500SRoman Divacky else {
3029b1c73532SDimitry Andric // Remaining types are Half, Bfloat16, LongDouble, __ibm128 or __float128.
3030b1c73532SDimitry Andric // Convert from float.
3031bca07a45SDimitry Andric llvm::APFloat F(static_cast<float>(amount));
30324ba67500SRoman Divacky bool ignored;
30332b6b257fSDimitry Andric const llvm::fltSemantics *FS;
30345e20cdd8SDimitry Andric // Don't use getFloatTypeSemantics because Half isn't
30355e20cdd8SDimitry Andric // necessarily represented using the "half" LLVM type.
30362b6b257fSDimitry Andric if (value->getType()->isFP128Ty())
30372b6b257fSDimitry Andric FS = &CGF.getTarget().getFloat128Format();
30382b6b257fSDimitry Andric else if (value->getType()->isHalfTy())
30392b6b257fSDimitry Andric FS = &CGF.getTarget().getHalfFormat();
3040b1c73532SDimitry Andric else if (value->getType()->isBFloatTy())
3041b1c73532SDimitry Andric FS = &CGF.getTarget().getBFloat16Format();
3042c0981da4SDimitry Andric else if (value->getType()->isPPC_FP128Ty())
3043c0981da4SDimitry Andric FS = &CGF.getTarget().getIbm128Format();
30442b6b257fSDimitry Andric else
30452b6b257fSDimitry Andric FS = &CGF.getTarget().getLongDoubleFormat();
30462b6b257fSDimitry Andric F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3047bca07a45SDimitry Andric amt = llvm::ConstantFP::get(VMContext, F);
30484ba67500SRoman Divacky }
3049bca07a45SDimitry Andric value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
3050bca07a45SDimitry Andric
30515e20cdd8SDimitry Andric if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
3052461a67faSDimitry Andric if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
30539f4dbff6SDimitry Andric value = Builder.CreateCall(
30549f4dbff6SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,
30559f4dbff6SDimitry Andric CGF.CGM.FloatTy),
30565e20cdd8SDimitry Andric value, "incdec.conv");
30575e20cdd8SDimitry Andric } else {
30585e20cdd8SDimitry Andric value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv");
30595e20cdd8SDimitry Andric }
30605e20cdd8SDimitry Andric }
306136981b17SDimitry Andric
3062cfca06d7SDimitry Andric // Fixed-point types.
3063cfca06d7SDimitry Andric } else if (type->isFixedPointType()) {
3064cfca06d7SDimitry Andric // Fixed-point types are tricky. In some cases, it isn't possible to
3065cfca06d7SDimitry Andric // represent a 1 or a -1 in the type at all. Piggyback off of
3066cfca06d7SDimitry Andric // EmitFixedPointBinOp to avoid having to reimplement saturation.
3067cfca06d7SDimitry Andric BinOpInfo Info;
3068cfca06d7SDimitry Andric Info.E = E;
3069cfca06d7SDimitry Andric Info.Ty = E->getType();
3070cfca06d7SDimitry Andric Info.Opcode = isInc ? BO_Add : BO_Sub;
3071cfca06d7SDimitry Andric Info.LHS = value;
3072cfca06d7SDimitry Andric Info.RHS = llvm::ConstantInt::get(value->getType(), 1, false);
3073cfca06d7SDimitry Andric // If the type is signed, it's better to represent this as +(-1) or -(-1),
3074cfca06d7SDimitry Andric // since -1 is guaranteed to be representable.
3075cfca06d7SDimitry Andric if (type->isSignedFixedPointType()) {
3076cfca06d7SDimitry Andric Info.Opcode = isInc ? BO_Sub : BO_Add;
3077cfca06d7SDimitry Andric Info.RHS = Builder.CreateNeg(Info.RHS);
3078cfca06d7SDimitry Andric }
3079cfca06d7SDimitry Andric // Now, convert from our invented integer literal to the type of the unary
3080cfca06d7SDimitry Andric // op. This will upscale and saturate if necessary. This value can become
3081cfca06d7SDimitry Andric // undef in some cases.
3082b60736ecSDimitry Andric llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3083b60736ecSDimitry Andric auto DstSema = CGF.getContext().getFixedPointSemantics(Info.Ty);
3084b60736ecSDimitry Andric Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS, true, DstSema);
3085cfca06d7SDimitry Andric value = EmitFixedPointBinOp(Info);
3086cfca06d7SDimitry Andric
3087bca07a45SDimitry Andric // Objective-C pointer types.
3088bca07a45SDimitry Andric } else {
3089bca07a45SDimitry Andric const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>();
3090bca07a45SDimitry Andric
3091bca07a45SDimitry Andric CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType());
3092bca07a45SDimitry Andric if (!isInc) size = -size;
3093bca07a45SDimitry Andric llvm::Value *sizeValue =
3094bca07a45SDimitry Andric llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
3095bca07a45SDimitry Andric
309613cc256eSDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
3097344a3780SDimitry Andric value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
309801af97d3SDimitry Andric else
309977fc4c14SDimitry Andric value = CGF.EmitCheckedInBoundsGEP(
310077fc4c14SDimitry Andric CGF.Int8Ty, value, sizeValue, /*SignedIndices=*/false, isSubtraction,
3101325377b5SDimitry Andric E->getExprLoc(), "incdec.objptr");
3102bca07a45SDimitry Andric value = Builder.CreateBitCast(value, input->getType());
31034ba67500SRoman Divacky }
31044ba67500SRoman Divacky
3105dbe13110SDimitry Andric if (atomicPHI) {
310622989816SDimitry Andric llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3107dbe13110SDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
310806d4ba38SDimitry Andric auto Pair = CGF.EmitAtomicCompareExchange(
31095e20cdd8SDimitry Andric LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
31105e20cdd8SDimitry Andric llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
31115e20cdd8SDimitry Andric llvm::Value *success = Pair.second;
311222989816SDimitry Andric atomicPHI->addIncoming(old, curBlock);
311322989816SDimitry Andric Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3114dbe13110SDimitry Andric Builder.SetInsertPoint(contBB);
3115dbe13110SDimitry Andric return isPre ? value : input;
3116dbe13110SDimitry Andric }
3117dbe13110SDimitry Andric
31184ba67500SRoman Divacky // Store the updated result through the lvalue.
3119ac9a064cSDimitry Andric if (LV.isBitField()) {
3120ac9a064cSDimitry Andric Value *Src = Previous ? Previous : value;
3121180abc3dSDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
3122ac9a064cSDimitry Andric CGF.EmitBitfieldConversionCheck(Src, SrcType, value, E->getType(),
3123ac9a064cSDimitry Andric LV.getBitFieldInfo(), E->getExprLoc());
3124ac9a064cSDimitry Andric } else
3125180abc3dSDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(value), LV);
31264ba67500SRoman Divacky
31274ba67500SRoman Divacky // If this is a postinc, return the value read from memory, otherwise use the
31284ba67500SRoman Divacky // updated value.
3129bca07a45SDimitry Andric return isPre ? value : input;
31304ba67500SRoman Divacky }
31314ba67500SRoman Divacky
31324ba67500SRoman Divacky
VisitUnaryPlus(const UnaryOperator * E,QualType PromotionType)3133e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
3134e3b55780SDimitry Andric QualType PromotionType) {
3135e3b55780SDimitry Andric QualType promotionTy = PromotionType.isNull()
3136e3b55780SDimitry Andric ? getPromotionType(E->getSubExpr()->getType())
3137e3b55780SDimitry Andric : PromotionType;
3138e3b55780SDimitry Andric Value *result = VisitPlus(E, promotionTy);
3139e3b55780SDimitry Andric if (result && !promotionTy.isNull())
3140e3b55780SDimitry Andric result = EmitUnPromotedValue(result, E->getType());
3141e3b55780SDimitry Andric return result;
3142e3b55780SDimitry Andric }
31434ba67500SRoman Divacky
VisitPlus(const UnaryOperator * E,QualType PromotionType)3144e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitPlus(const UnaryOperator *E,
3145e3b55780SDimitry Andric QualType PromotionType) {
3146e3b55780SDimitry Andric // This differs from gcc, though, most likely due to a bug in gcc.
3147ec2b103cSEd Schouten TestAndClearIgnoreResultAssign();
3148e3b55780SDimitry Andric if (!PromotionType.isNull())
3149e3b55780SDimitry Andric return CGF.EmitPromotedScalarExpr(E->getSubExpr(), PromotionType);
3150e3b55780SDimitry Andric return Visit(E->getSubExpr());
3151e3b55780SDimitry Andric }
3152e3b55780SDimitry Andric
VisitUnaryMinus(const UnaryOperator * E,QualType PromotionType)3153e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
3154e3b55780SDimitry Andric QualType PromotionType) {
3155e3b55780SDimitry Andric QualType promotionTy = PromotionType.isNull()
3156e3b55780SDimitry Andric ? getPromotionType(E->getSubExpr()->getType())
3157e3b55780SDimitry Andric : PromotionType;
3158e3b55780SDimitry Andric Value *result = VisitMinus(E, promotionTy);
3159e3b55780SDimitry Andric if (result && !promotionTy.isNull())
3160e3b55780SDimitry Andric result = EmitUnPromotedValue(result, E->getType());
3161e3b55780SDimitry Andric return result;
3162e3b55780SDimitry Andric }
3163e3b55780SDimitry Andric
VisitMinus(const UnaryOperator * E,QualType PromotionType)3164e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitMinus(const UnaryOperator *E,
3165e3b55780SDimitry Andric QualType PromotionType) {
3166e3b55780SDimitry Andric TestAndClearIgnoreResultAssign();
3167e3b55780SDimitry Andric Value *Op;
3168e3b55780SDimitry Andric if (!PromotionType.isNull())
3169e3b55780SDimitry Andric Op = CGF.EmitPromotedScalarExpr(E->getSubExpr(), PromotionType);
3170e3b55780SDimitry Andric else
3171e3b55780SDimitry Andric Op = Visit(E->getSubExpr());
3172519fc96cSDimitry Andric
3173519fc96cSDimitry Andric // Generate a unary FNeg for FP ops.
3174519fc96cSDimitry Andric if (Op->getType()->isFPOrFPVectorTy())
3175519fc96cSDimitry Andric return Builder.CreateFNeg(Op, "fneg");
3176519fc96cSDimitry Andric
31774ba67500SRoman Divacky // Emit unary minus with EmitSub so we handle overflow cases etc.
31784ba67500SRoman Divacky BinOpInfo BinOp;
3179519fc96cSDimitry Andric BinOp.RHS = Op;
31804ba67500SRoman Divacky BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
31814ba67500SRoman Divacky BinOp.Ty = E->getType();
31823d1dcd9bSDimitry Andric BinOp.Opcode = BO_Sub;
3183cfca06d7SDimitry Andric BinOp.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
31844ba67500SRoman Divacky BinOp.E = E;
31854ba67500SRoman Divacky return EmitSub(BinOp);
3186ec2b103cSEd Schouten }
3187ec2b103cSEd Schouten
VisitUnaryNot(const UnaryOperator * E)3188ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
3189ec2b103cSEd Schouten TestAndClearIgnoreResultAssign();
3190ec2b103cSEd Schouten Value *Op = Visit(E->getSubExpr());
3191e3b55780SDimitry Andric return Builder.CreateNot(Op, "not");
3192ec2b103cSEd Schouten }
3193ec2b103cSEd Schouten
VisitUnaryLNot(const UnaryOperator * E)3194ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
3195dbe13110SDimitry Andric // Perform vector logical not on comparison with zero vector.
3196cfca06d7SDimitry Andric if (E->getType()->isVectorType() &&
3197cfca06d7SDimitry Andric E->getType()->castAs<VectorType>()->getVectorKind() ==
3198b1c73532SDimitry Andric VectorKind::Generic) {
3199dbe13110SDimitry Andric Value *Oper = Visit(E->getSubExpr());
3200dbe13110SDimitry Andric Value *Zero = llvm::Constant::getNullValue(Oper->getType());
3201809500fcSDimitry Andric Value *Result;
3202cfca06d7SDimitry Andric if (Oper->getType()->isFPOrFPVectorTy()) {
3203cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3204cfca06d7SDimitry Andric CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
3205809500fcSDimitry Andric Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
3206cfca06d7SDimitry Andric } else
3207809500fcSDimitry Andric Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
3208dbe13110SDimitry Andric return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
3209dbe13110SDimitry Andric }
3210dbe13110SDimitry Andric
3211ec2b103cSEd Schouten // Compare operand to zero.
3212ec2b103cSEd Schouten Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
3213ec2b103cSEd Schouten
3214ec2b103cSEd Schouten // Invert value.
3215ec2b103cSEd Schouten // TODO: Could dynamically modify easy computations here. For example, if
3216ec2b103cSEd Schouten // the operand is an icmp ne, turn into icmp eq.
3217ec2b103cSEd Schouten BoolVal = Builder.CreateNot(BoolVal, "lnot");
3218ec2b103cSEd Schouten
3219ec2b103cSEd Schouten // ZExt result to the expr type.
3220ec2b103cSEd Schouten return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
3221ec2b103cSEd Schouten }
3222ec2b103cSEd Schouten
VisitOffsetOfExpr(OffsetOfExpr * E)32233d1dcd9bSDimitry Andric Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
32243d1dcd9bSDimitry Andric // Try folding the offsetof to a constant.
3225676fbe81SDimitry Andric Expr::EvalResult EVResult;
3226676fbe81SDimitry Andric if (E->EvaluateAsInt(EVResult, CGF.getContext())) {
3227676fbe81SDimitry Andric llvm::APSInt Value = EVResult.Val.getInt();
3228dbe13110SDimitry Andric return Builder.getInt(Value);
3229676fbe81SDimitry Andric }
32300883ccd9SRoman Divacky
32313d1dcd9bSDimitry Andric // Loop over the components of the offsetof to compute the value.
32323d1dcd9bSDimitry Andric unsigned n = E->getNumComponents();
323336981b17SDimitry Andric llvm::Type* ResultType = ConvertType(E->getType());
32343d1dcd9bSDimitry Andric llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
32353d1dcd9bSDimitry Andric QualType CurrentType = E->getTypeSourceInfo()->getType();
32363d1dcd9bSDimitry Andric for (unsigned i = 0; i != n; ++i) {
323745b53394SDimitry Andric OffsetOfNode ON = E->getComponent(i);
32389f4dbff6SDimitry Andric llvm::Value *Offset = nullptr;
32393d1dcd9bSDimitry Andric switch (ON.getKind()) {
324045b53394SDimitry Andric case OffsetOfNode::Array: {
32413d1dcd9bSDimitry Andric // Compute the index
32423d1dcd9bSDimitry Andric Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
32433d1dcd9bSDimitry Andric llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
324429cafa66SDimitry Andric bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType();
32453d1dcd9bSDimitry Andric Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv");
32460883ccd9SRoman Divacky
32473d1dcd9bSDimitry Andric // Save the element type
32483d1dcd9bSDimitry Andric CurrentType =
32493d1dcd9bSDimitry Andric CGF.getContext().getAsArrayType(CurrentType)->getElementType();
32503d1dcd9bSDimitry Andric
32513d1dcd9bSDimitry Andric // Compute the element size
32523d1dcd9bSDimitry Andric llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
32533d1dcd9bSDimitry Andric CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity());
32543d1dcd9bSDimitry Andric
32553d1dcd9bSDimitry Andric // Multiply out to compute the result
32563d1dcd9bSDimitry Andric Offset = Builder.CreateMul(Idx, ElemSize);
32573d1dcd9bSDimitry Andric break;
32583d1dcd9bSDimitry Andric }
32593d1dcd9bSDimitry Andric
326045b53394SDimitry Andric case OffsetOfNode::Field: {
32613d1dcd9bSDimitry Andric FieldDecl *MemberDecl = ON.getField();
3262519fc96cSDimitry Andric RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
32633d1dcd9bSDimitry Andric const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
32643d1dcd9bSDimitry Andric
32653d1dcd9bSDimitry Andric // Compute the index of the field in its parent.
32663d1dcd9bSDimitry Andric unsigned i = 0;
32673d1dcd9bSDimitry Andric // FIXME: It would be nice if we didn't have to loop here!
32683d1dcd9bSDimitry Andric for (RecordDecl::field_iterator Field = RD->field_begin(),
32693d1dcd9bSDimitry Andric FieldEnd = RD->field_end();
327056d91b49SDimitry Andric Field != FieldEnd; ++Field, ++i) {
32713d1dcd9bSDimitry Andric if (*Field == MemberDecl)
32723d1dcd9bSDimitry Andric break;
32733d1dcd9bSDimitry Andric }
32743d1dcd9bSDimitry Andric assert(i < RL.getFieldCount() && "offsetof field in wrong type");
32753d1dcd9bSDimitry Andric
32763d1dcd9bSDimitry Andric // Compute the offset to the field
32773d1dcd9bSDimitry Andric int64_t OffsetInt = RL.getFieldOffset(i) /
32783d1dcd9bSDimitry Andric CGF.getContext().getCharWidth();
32793d1dcd9bSDimitry Andric Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
32803d1dcd9bSDimitry Andric
32813d1dcd9bSDimitry Andric // Save the element type.
32823d1dcd9bSDimitry Andric CurrentType = MemberDecl->getType();
32833d1dcd9bSDimitry Andric break;
32843d1dcd9bSDimitry Andric }
32853d1dcd9bSDimitry Andric
328645b53394SDimitry Andric case OffsetOfNode::Identifier:
32873d1dcd9bSDimitry Andric llvm_unreachable("dependent __builtin_offsetof");
32883d1dcd9bSDimitry Andric
328945b53394SDimitry Andric case OffsetOfNode::Base: {
32903d1dcd9bSDimitry Andric if (ON.getBase()->isVirtual()) {
32913d1dcd9bSDimitry Andric CGF.ErrorUnsupported(E, "virtual base in offsetof");
32923d1dcd9bSDimitry Andric continue;
32933d1dcd9bSDimitry Andric }
32943d1dcd9bSDimitry Andric
3295519fc96cSDimitry Andric RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
32963d1dcd9bSDimitry Andric const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
32973d1dcd9bSDimitry Andric
32983d1dcd9bSDimitry Andric // Save the element type.
32993d1dcd9bSDimitry Andric CurrentType = ON.getBase()->getType();
33003d1dcd9bSDimitry Andric
33013d1dcd9bSDimitry Andric // Compute the offset to the base.
3302145449b1SDimitry Andric auto *BaseRT = CurrentType->castAs<RecordType>();
3303145449b1SDimitry Andric auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
330456d91b49SDimitry Andric CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD);
330556d91b49SDimitry Andric Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
33063d1dcd9bSDimitry Andric break;
33073d1dcd9bSDimitry Andric }
33083d1dcd9bSDimitry Andric }
33093d1dcd9bSDimitry Andric Result = Builder.CreateAdd(Result, Offset);
33103d1dcd9bSDimitry Andric }
33113d1dcd9bSDimitry Andric return Result;
33120883ccd9SRoman Divacky }
33130883ccd9SRoman Divacky
331401af97d3SDimitry Andric /// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of
3315ec2b103cSEd Schouten /// argument of the sizeof expression as an integer.
3316ec2b103cSEd Schouten Value *
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)331701af97d3SDimitry Andric ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
331801af97d3SDimitry Andric const UnaryExprOrTypeTraitExpr *E) {
3319ec2b103cSEd Schouten QualType TypeToSize = E->getTypeOfArgument();
3320b1c73532SDimitry Andric if (auto Kind = E->getKind();
3321b1c73532SDimitry Andric Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
3322ec2b103cSEd Schouten if (const VariableArrayType *VAT =
3323ec2b103cSEd Schouten CGF.getContext().getAsVariableArrayType(TypeToSize)) {
3324ec2b103cSEd Schouten if (E->isArgumentType()) {
3325ec2b103cSEd Schouten // sizeof(type) - make sure to emit the VLA size.
3326180abc3dSDimitry Andric CGF.EmitVariablyModifiedType(TypeToSize);
3327ec2b103cSEd Schouten } else {
3328ec2b103cSEd Schouten // C99 6.5.3.4p2: If the argument is an expression of type
3329ec2b103cSEd Schouten // VLA, it is evaluated.
3330bca07a45SDimitry Andric CGF.EmitIgnoredExpr(E->getArgumentExpr());
3331ec2b103cSEd Schouten }
3332ec2b103cSEd Schouten
333348675466SDimitry Andric auto VlaSize = CGF.getVLASize(VAT);
333448675466SDimitry Andric llvm::Value *size = VlaSize.NumElts;
3335180abc3dSDimitry Andric
3336180abc3dSDimitry Andric // Scale the number of non-VLA elements by the non-VLA element size.
333748675466SDimitry Andric CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type);
3338180abc3dSDimitry Andric if (!eltSize.isOne())
333948675466SDimitry Andric size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size);
3340180abc3dSDimitry Andric
3341180abc3dSDimitry Andric return size;
3342ec2b103cSEd Schouten }
3343c192b3dcSDimitry Andric } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) {
3344c192b3dcSDimitry Andric auto Alignment =
3345c192b3dcSDimitry Andric CGF.getContext()
3346c192b3dcSDimitry Andric .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
3347c192b3dcSDimitry Andric E->getTypeOfArgument()->getPointeeType()))
3348c192b3dcSDimitry Andric .getQuantity();
3349c192b3dcSDimitry Andric return llvm::ConstantInt::get(CGF.SizeTy, Alignment);
3350b1c73532SDimitry Andric } else if (E->getKind() == UETT_VectorElements) {
3351b1c73532SDimitry Andric auto *VecTy = cast<llvm::VectorType>(ConvertType(E->getTypeOfArgument()));
3352b1c73532SDimitry Andric return Builder.CreateElementCount(CGF.SizeTy, VecTy->getElementCount());
3353ec2b103cSEd Schouten }
3354ec2b103cSEd Schouten
33554c8b2481SRoman Divacky // If this isn't sizeof(vla), the result must be constant; use the constant
33564c8b2481SRoman Divacky // folding logic so we don't have to duplicate it here.
3357dbe13110SDimitry Andric return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext()));
3358ec2b103cSEd Schouten }
3359ec2b103cSEd Schouten
VisitUnaryReal(const UnaryOperator * E,QualType PromotionType)3360e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E,
3361e3b55780SDimitry Andric QualType PromotionType) {
3362e3b55780SDimitry Andric QualType promotionTy = PromotionType.isNull()
3363e3b55780SDimitry Andric ? getPromotionType(E->getSubExpr()->getType())
3364e3b55780SDimitry Andric : PromotionType;
3365e3b55780SDimitry Andric Value *result = VisitReal(E, promotionTy);
3366e3b55780SDimitry Andric if (result && !promotionTy.isNull())
3367e3b55780SDimitry Andric result = EmitUnPromotedValue(result, E->getType());
3368e3b55780SDimitry Andric return result;
3369e3b55780SDimitry Andric }
3370e3b55780SDimitry Andric
VisitReal(const UnaryOperator * E,QualType PromotionType)3371e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitReal(const UnaryOperator *E,
3372e3b55780SDimitry Andric QualType PromotionType) {
3373ec2b103cSEd Schouten Expr *Op = E->getSubExpr();
3374bca07a45SDimitry Andric if (Op->getType()->isAnyComplexType()) {
3375bca07a45SDimitry Andric // If it's an l-value, load through the appropriate subobject l-value.
3376bca07a45SDimitry Andric // Note that we have to ask E because Op might be an l-value that
3377bca07a45SDimitry Andric // this won't work for, e.g. an Obj-C property.
3378e3b55780SDimitry Andric if (E->isGLValue()) {
3379e3b55780SDimitry Andric if (!PromotionType.isNull()) {
3380e3b55780SDimitry Andric CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
3381e3b55780SDimitry Andric Op, /*IgnoreReal*/ IgnoreResultAssign, /*IgnoreImag*/ true);
3382e3b55780SDimitry Andric if (result.first)
3383e3b55780SDimitry Andric result.first = CGF.EmitPromotedValue(result, PromotionType).first;
3384e3b55780SDimitry Andric return result.first;
3385e3b55780SDimitry Andric } else {
3386e3b55780SDimitry Andric return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3387e3b55780SDimitry Andric .getScalarVal();
3388e3b55780SDimitry Andric }
3389e3b55780SDimitry Andric }
3390bca07a45SDimitry Andric // Otherwise, calculate and project.
3391bca07a45SDimitry Andric return CGF.EmitComplexExpr(Op, false, true).first;
3392bca07a45SDimitry Andric }
3393bca07a45SDimitry Andric
3394e3b55780SDimitry Andric if (!PromotionType.isNull())
3395e3b55780SDimitry Andric return CGF.EmitPromotedScalarExpr(Op, PromotionType);
3396ec2b103cSEd Schouten return Visit(Op);
3397ec2b103cSEd Schouten }
3398bca07a45SDimitry Andric
VisitUnaryImag(const UnaryOperator * E,QualType PromotionType)3399e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E,
3400e3b55780SDimitry Andric QualType PromotionType) {
3401e3b55780SDimitry Andric QualType promotionTy = PromotionType.isNull()
3402e3b55780SDimitry Andric ? getPromotionType(E->getSubExpr()->getType())
3403e3b55780SDimitry Andric : PromotionType;
3404e3b55780SDimitry Andric Value *result = VisitImag(E, promotionTy);
3405e3b55780SDimitry Andric if (result && !promotionTy.isNull())
3406e3b55780SDimitry Andric result = EmitUnPromotedValue(result, E->getType());
3407e3b55780SDimitry Andric return result;
3408e3b55780SDimitry Andric }
3409e3b55780SDimitry Andric
VisitImag(const UnaryOperator * E,QualType PromotionType)3410e3b55780SDimitry Andric Value *ScalarExprEmitter::VisitImag(const UnaryOperator *E,
3411e3b55780SDimitry Andric QualType PromotionType) {
3412ec2b103cSEd Schouten Expr *Op = E->getSubExpr();
3413bca07a45SDimitry Andric if (Op->getType()->isAnyComplexType()) {
3414bca07a45SDimitry Andric // If it's an l-value, load through the appropriate subobject l-value.
3415bca07a45SDimitry Andric // Note that we have to ask E because Op might be an l-value that
3416bca07a45SDimitry Andric // this won't work for, e.g. an Obj-C property.
3417e3b55780SDimitry Andric if (Op->isGLValue()) {
3418e3b55780SDimitry Andric if (!PromotionType.isNull()) {
3419e3b55780SDimitry Andric CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
3420e3b55780SDimitry Andric Op, /*IgnoreReal*/ true, /*IgnoreImag*/ IgnoreResultAssign);
3421e3b55780SDimitry Andric if (result.second)
3422e3b55780SDimitry Andric result.second = CGF.EmitPromotedValue(result, PromotionType).second;
3423e3b55780SDimitry Andric return result.second;
3424e3b55780SDimitry Andric } else {
3425e3b55780SDimitry Andric return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3426e3b55780SDimitry Andric .getScalarVal();
3427e3b55780SDimitry Andric }
3428e3b55780SDimitry Andric }
3429bca07a45SDimitry Andric // Otherwise, calculate and project.
3430bca07a45SDimitry Andric return CGF.EmitComplexExpr(Op, true, false).second;
3431bca07a45SDimitry Andric }
3432ec2b103cSEd Schouten
3433ec2b103cSEd Schouten // __imag on a scalar returns zero. Emit the subexpr to ensure side
3434ec2b103cSEd Schouten // effects are evaluated, but not the actual value.
3435dbe13110SDimitry Andric if (Op->isGLValue())
3436dbe13110SDimitry Andric CGF.EmitLValue(Op);
3437e3b55780SDimitry Andric else if (!PromotionType.isNull())
3438e3b55780SDimitry Andric CGF.EmitPromotedScalarExpr(Op, PromotionType);
3439dbe13110SDimitry Andric else
3440ec2b103cSEd Schouten CGF.EmitScalarExpr(Op, true);
3441e3b55780SDimitry Andric if (!PromotionType.isNull())
3442e3b55780SDimitry Andric return llvm::Constant::getNullValue(ConvertType(PromotionType));
3443ec2b103cSEd Schouten return llvm::Constant::getNullValue(ConvertType(E->getType()));
3444ec2b103cSEd Schouten }
3445ec2b103cSEd Schouten
3446ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
3447ec2b103cSEd Schouten // Binary Operators
3448ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
3449ec2b103cSEd Schouten
EmitPromotedValue(Value * result,QualType PromotionType)3450e3b55780SDimitry Andric Value *ScalarExprEmitter::EmitPromotedValue(Value *result,
3451e3b55780SDimitry Andric QualType PromotionType) {
3452e3b55780SDimitry Andric return CGF.Builder.CreateFPExt(result, ConvertType(PromotionType), "ext");
3453e3b55780SDimitry Andric }
3454e3b55780SDimitry Andric
EmitUnPromotedValue(Value * result,QualType ExprType)3455e3b55780SDimitry Andric Value *ScalarExprEmitter::EmitUnPromotedValue(Value *result,
3456e3b55780SDimitry Andric QualType ExprType) {
3457e3b55780SDimitry Andric return CGF.Builder.CreateFPTrunc(result, ConvertType(ExprType), "unpromotion");
3458e3b55780SDimitry Andric }
3459e3b55780SDimitry Andric
EmitPromoted(const Expr * E,QualType PromotionType)3460e3b55780SDimitry Andric Value *ScalarExprEmitter::EmitPromoted(const Expr *E, QualType PromotionType) {
3461e3b55780SDimitry Andric E = E->IgnoreParens();
3462e3b55780SDimitry Andric if (auto BO = dyn_cast<BinaryOperator>(E)) {
3463e3b55780SDimitry Andric switch (BO->getOpcode()) {
3464e3b55780SDimitry Andric #define HANDLE_BINOP(OP) \
3465e3b55780SDimitry Andric case BO_##OP: \
3466e3b55780SDimitry Andric return Emit##OP(EmitBinOps(BO, PromotionType));
3467e3b55780SDimitry Andric HANDLE_BINOP(Add)
3468e3b55780SDimitry Andric HANDLE_BINOP(Sub)
3469e3b55780SDimitry Andric HANDLE_BINOP(Mul)
3470e3b55780SDimitry Andric HANDLE_BINOP(Div)
3471e3b55780SDimitry Andric #undef HANDLE_BINOP
3472e3b55780SDimitry Andric default:
3473e3b55780SDimitry Andric break;
3474e3b55780SDimitry Andric }
3475e3b55780SDimitry Andric } else if (auto UO = dyn_cast<UnaryOperator>(E)) {
3476e3b55780SDimitry Andric switch (UO->getOpcode()) {
3477e3b55780SDimitry Andric case UO_Imag:
3478e3b55780SDimitry Andric return VisitImag(UO, PromotionType);
3479e3b55780SDimitry Andric case UO_Real:
3480e3b55780SDimitry Andric return VisitReal(UO, PromotionType);
3481e3b55780SDimitry Andric case UO_Minus:
3482e3b55780SDimitry Andric return VisitMinus(UO, PromotionType);
3483e3b55780SDimitry Andric case UO_Plus:
3484e3b55780SDimitry Andric return VisitPlus(UO, PromotionType);
3485e3b55780SDimitry Andric default:
3486e3b55780SDimitry Andric break;
3487e3b55780SDimitry Andric }
3488e3b55780SDimitry Andric }
3489e3b55780SDimitry Andric auto result = Visit(const_cast<Expr *>(E));
3490e3b55780SDimitry Andric if (result) {
3491e3b55780SDimitry Andric if (!PromotionType.isNull())
3492e3b55780SDimitry Andric return EmitPromotedValue(result, PromotionType);
3493e3b55780SDimitry Andric else
3494e3b55780SDimitry Andric return EmitUnPromotedValue(result, E->getType());
3495e3b55780SDimitry Andric }
3496e3b55780SDimitry Andric return result;
3497e3b55780SDimitry Andric }
3498e3b55780SDimitry Andric
EmitBinOps(const BinaryOperator * E,QualType PromotionType)3499e3b55780SDimitry Andric BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E,
3500e3b55780SDimitry Andric QualType PromotionType) {
3501ec2b103cSEd Schouten TestAndClearIgnoreResultAssign();
3502ec2b103cSEd Schouten BinOpInfo Result;
3503e3b55780SDimitry Andric Result.LHS = CGF.EmitPromotedScalarExpr(E->getLHS(), PromotionType);
3504e3b55780SDimitry Andric Result.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionType);
3505e3b55780SDimitry Andric if (!PromotionType.isNull())
3506e3b55780SDimitry Andric Result.Ty = PromotionType;
3507e3b55780SDimitry Andric else
3508ec2b103cSEd Schouten Result.Ty = E->getType();
35094ba67500SRoman Divacky Result.Opcode = E->getOpcode();
3510cfca06d7SDimitry Andric Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
3511ec2b103cSEd Schouten Result.E = E;
3512ec2b103cSEd Schouten return Result;
3513ec2b103cSEd Schouten }
3514ec2b103cSEd Schouten
EmitCompoundAssignLValue(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &),Value * & Result)35150883ccd9SRoman Divacky LValue ScalarExprEmitter::EmitCompoundAssignLValue(
35160883ccd9SRoman Divacky const CompoundAssignOperator *E,
35170883ccd9SRoman Divacky Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
35184ba67500SRoman Divacky Value *&Result) {
3519abe15e55SRoman Divacky QualType LHSTy = E->getLHS()->getType();
3520ec2b103cSEd Schouten BinOpInfo OpInfo;
3521ec2b103cSEd Schouten
3522bfef3995SDimitry Andric if (E->getComputationResultType()->isAnyComplexType())
35235e20cdd8SDimitry Andric return CGF.EmitScalarCompoundAssignWithComplex(E, Result);
3524ec2b103cSEd Schouten
3525ec2b103cSEd Schouten // Emit the RHS first. __block variables need to have the rhs evaluated
3526ec2b103cSEd Schouten // first, plus this should improve codegen a little.
3527e3b55780SDimitry Andric
3528e3b55780SDimitry Andric QualType PromotionTypeCR;
3529e3b55780SDimitry Andric PromotionTypeCR = getPromotionType(E->getComputationResultType());
3530e3b55780SDimitry Andric if (PromotionTypeCR.isNull())
3531e3b55780SDimitry Andric PromotionTypeCR = E->getComputationResultType();
3532e3b55780SDimitry Andric QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType());
3533e3b55780SDimitry Andric QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType());
3534e3b55780SDimitry Andric if (!PromotionTypeRHS.isNull())
3535e3b55780SDimitry Andric OpInfo.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS);
3536e3b55780SDimitry Andric else
3537ec2b103cSEd Schouten OpInfo.RHS = Visit(E->getRHS());
3538e3b55780SDimitry Andric OpInfo.Ty = PromotionTypeCR;
35394ba67500SRoman Divacky OpInfo.Opcode = E->getOpcode();
3540cfca06d7SDimitry Andric OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
3541ec2b103cSEd Schouten OpInfo.E = E;
3542ec2b103cSEd Schouten // Load/convert the LHS.
354313cc256eSDimitry Andric LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
3544ec2b103cSEd Schouten
35459f4dbff6SDimitry Andric llvm::PHINode *atomicPHI = nullptr;
3546809500fcSDimitry Andric if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
3547809500fcSDimitry Andric QualType type = atomicTy->getValueType();
3548809500fcSDimitry Andric if (!type->isBooleanType() && type->isIntegerType() &&
3549809500fcSDimitry Andric !(type->isUnsignedIntegerType() &&
355006d4ba38SDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
3551809500fcSDimitry Andric CGF.getLangOpts().getSignedOverflowBehavior() !=
3552809500fcSDimitry Andric LangOptions::SOB_Trapping) {
3553706b4fc4SDimitry Andric llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3554706b4fc4SDimitry Andric llvm::Instruction::BinaryOps Op;
3555809500fcSDimitry Andric switch (OpInfo.Opcode) {
3556809500fcSDimitry Andric // We don't have atomicrmw operands for *, %, /, <<, >>
3557809500fcSDimitry Andric case BO_MulAssign: case BO_DivAssign:
3558809500fcSDimitry Andric case BO_RemAssign:
3559809500fcSDimitry Andric case BO_ShlAssign:
3560809500fcSDimitry Andric case BO_ShrAssign:
3561809500fcSDimitry Andric break;
3562809500fcSDimitry Andric case BO_AddAssign:
3563706b4fc4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Add;
3564706b4fc4SDimitry Andric Op = llvm::Instruction::Add;
3565809500fcSDimitry Andric break;
3566809500fcSDimitry Andric case BO_SubAssign:
3567706b4fc4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Sub;
3568706b4fc4SDimitry Andric Op = llvm::Instruction::Sub;
3569809500fcSDimitry Andric break;
3570809500fcSDimitry Andric case BO_AndAssign:
3571706b4fc4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::And;
3572706b4fc4SDimitry Andric Op = llvm::Instruction::And;
3573809500fcSDimitry Andric break;
3574809500fcSDimitry Andric case BO_XorAssign:
3575706b4fc4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Xor;
3576706b4fc4SDimitry Andric Op = llvm::Instruction::Xor;
3577809500fcSDimitry Andric break;
3578809500fcSDimitry Andric case BO_OrAssign:
3579706b4fc4SDimitry Andric AtomicOp = llvm::AtomicRMWInst::Or;
3580706b4fc4SDimitry Andric Op = llvm::Instruction::Or;
3581809500fcSDimitry Andric break;
3582809500fcSDimitry Andric default:
3583809500fcSDimitry Andric llvm_unreachable("Invalid compound assignment type");
3584809500fcSDimitry Andric }
3585706b4fc4SDimitry Andric if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3586706b4fc4SDimitry Andric llvm::Value *Amt = CGF.EmitToMemory(
358745b53394SDimitry Andric EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
358845b53394SDimitry Andric E->getExprLoc()),
358945b53394SDimitry Andric LHSTy);
3590706b4fc4SDimitry Andric Value *OldVal = Builder.CreateAtomicRMW(
3591ac9a064cSDimitry Andric AtomicOp, LHSLV.getAddress(), Amt,
35922b6b257fSDimitry Andric llvm::AtomicOrdering::SequentiallyConsistent);
3593706b4fc4SDimitry Andric
3594706b4fc4SDimitry Andric // Since operation is atomic, the result type is guaranteed to be the
3595706b4fc4SDimitry Andric // same as the input in LLVM terms.
3596706b4fc4SDimitry Andric Result = Builder.CreateBinOp(Op, OldVal, Amt);
3597809500fcSDimitry Andric return LHSLV;
3598809500fcSDimitry Andric }
3599809500fcSDimitry Andric }
3600dbe13110SDimitry Andric // FIXME: For floating point types, we should be saving and restoring the
3601dbe13110SDimitry Andric // floating point environment in the loop.
3602dbe13110SDimitry Andric llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3603dbe13110SDimitry Andric llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
3604bfef3995SDimitry Andric OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
3605809500fcSDimitry Andric OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type);
3606dbe13110SDimitry Andric Builder.CreateBr(opBB);
3607dbe13110SDimitry Andric Builder.SetInsertPoint(opBB);
3608dbe13110SDimitry Andric atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
3609dbe13110SDimitry Andric atomicPHI->addIncoming(OpInfo.LHS, startBB);
3610dbe13110SDimitry Andric OpInfo.LHS = atomicPHI;
3611dbe13110SDimitry Andric }
3612809500fcSDimitry Andric else
3613bfef3995SDimitry Andric OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
3614dbe13110SDimitry Andric
3615b60736ecSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
361645b53394SDimitry Andric SourceLocation Loc = E->getExprLoc();
3617e3b55780SDimitry Andric if (!PromotionTypeLHS.isNull())
3618e3b55780SDimitry Andric OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3619e3b55780SDimitry Andric E->getExprLoc());
3620e3b55780SDimitry Andric else
3621e3b55780SDimitry Andric OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3622e3b55780SDimitry Andric E->getComputationLHSType(), Loc);
362356d91b49SDimitry Andric
3624ec2b103cSEd Schouten // Expand the binary operator.
36254ba67500SRoman Divacky Result = (this->*Func)(OpInfo);
3626ec2b103cSEd Schouten
3627676fbe81SDimitry Andric // Convert the result back to the LHS type,
3628676fbe81SDimitry Andric // potentially with Implicit Conversion sanitizer check.
3629ac9a064cSDimitry Andric // If LHSLV is a bitfield, use default ScalarConversionOpts
3630ac9a064cSDimitry Andric // to avoid emit any implicit integer checks.
3631ac9a064cSDimitry Andric Value *Previous = nullptr;
3632ac9a064cSDimitry Andric if (LHSLV.isBitField()) {
3633ac9a064cSDimitry Andric Previous = Result;
3634ac9a064cSDimitry Andric Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc);
3635ac9a064cSDimitry Andric } else
3636e3b55780SDimitry Andric Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc,
3637e3b55780SDimitry Andric ScalarConversionOpts(CGF.SanOpts));
3638ec2b103cSEd Schouten
3639dbe13110SDimitry Andric if (atomicPHI) {
364022989816SDimitry Andric llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3641dbe13110SDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
364206d4ba38SDimitry Andric auto Pair = CGF.EmitAtomicCompareExchange(
36435e20cdd8SDimitry Andric LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc());
36445e20cdd8SDimitry Andric llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy);
36455e20cdd8SDimitry Andric llvm::Value *success = Pair.second;
364622989816SDimitry Andric atomicPHI->addIncoming(old, curBlock);
364722989816SDimitry Andric Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3648dbe13110SDimitry Andric Builder.SetInsertPoint(contBB);
3649dbe13110SDimitry Andric return LHSLV;
3650dbe13110SDimitry Andric }
3651dbe13110SDimitry Andric
36524c8b2481SRoman Divacky // Store the result value into the LHS lvalue. Bit-fields are handled
36534c8b2481SRoman Divacky // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
36544c8b2481SRoman Divacky // 'An assignment expression has the value of the left operand after the
36554c8b2481SRoman Divacky // assignment...'.
3656ac9a064cSDimitry Andric if (LHSLV.isBitField()) {
3657ac9a064cSDimitry Andric Value *Src = Previous ? Previous : Result;
3658ac9a064cSDimitry Andric QualType SrcType = E->getRHS()->getType();
3659ac9a064cSDimitry Andric QualType DstType = E->getLHS()->getType();
3660180abc3dSDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
3661ac9a064cSDimitry Andric CGF.EmitBitfieldConversionCheck(Src, SrcType, Result, DstType,
3662ac9a064cSDimitry Andric LHSLV.getBitFieldInfo(), E->getExprLoc());
3663ac9a064cSDimitry Andric } else
3664180abc3dSDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
36654ba67500SRoman Divacky
3666706b4fc4SDimitry Andric if (CGF.getLangOpts().OpenMP)
3667706b4fc4SDimitry Andric CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
3668706b4fc4SDimitry Andric E->getLHS());
36690883ccd9SRoman Divacky return LHSLV;
36700883ccd9SRoman Divacky }
36710883ccd9SRoman Divacky
EmitCompoundAssign(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &))36720883ccd9SRoman Divacky Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
36730883ccd9SRoman Divacky Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
36740883ccd9SRoman Divacky bool Ignore = TestAndClearIgnoreResultAssign();
367522989816SDimitry Andric Value *RHS = nullptr;
36764ba67500SRoman Divacky LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
36770883ccd9SRoman Divacky
36784ba67500SRoman Divacky // If the result is clearly ignored, return now.
3679ec2b103cSEd Schouten if (Ignore)
36809f4dbff6SDimitry Andric return nullptr;
36814ba67500SRoman Divacky
3682bca07a45SDimitry Andric // The result of an assignment in C is the assigned r-value.
368313cc256eSDimitry Andric if (!CGF.getLangOpts().CPlusPlus)
36844ba67500SRoman Divacky return RHS;
36854ba67500SRoman Divacky
36864ba67500SRoman Divacky // If the lvalue is non-volatile, return the computed value of the assignment.
36874ba67500SRoman Divacky if (!LHS.isVolatileQualified())
36884ba67500SRoman Divacky return RHS;
36894ba67500SRoman Divacky
36904ba67500SRoman Divacky // Otherwise, reload the value.
3691bfef3995SDimitry Andric return EmitLoadOfLValue(LHS, E->getExprLoc());
3692ec2b103cSEd Schouten }
3693ec2b103cSEd Schouten
EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo & Ops,llvm::Value * Zero,bool isDiv)3694bca07a45SDimitry Andric void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
369513cc256eSDimitry Andric const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
36965e20cdd8SDimitry Andric SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
3697bca07a45SDimitry Andric
369806d4ba38SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
369906d4ba38SDimitry Andric Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
370006d4ba38SDimitry Andric SanitizerKind::IntegerDivideByZero));
370106d4ba38SDimitry Andric }
370213cc256eSDimitry Andric
37037442d6faSDimitry Andric const auto *BO = cast<BinaryOperator>(Ops.E);
370406d4ba38SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
37057442d6faSDimitry Andric Ops.Ty->hasSignedIntegerRepresentation() &&
3706f0c0337bSDimitry Andric !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) &&
3707f0c0337bSDimitry Andric Ops.mayHaveIntegerOverflow()) {
370836981b17SDimitry Andric llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
3709bca07a45SDimitry Andric
3710bca07a45SDimitry Andric llvm::Value *IntMin =
371101af97d3SDimitry Andric Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3712344a3780SDimitry Andric llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
3713bca07a45SDimitry Andric
371413cc256eSDimitry Andric llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
371513cc256eSDimitry Andric llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
371606d4ba38SDimitry Andric llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
371706d4ba38SDimitry Andric Checks.push_back(
371806d4ba38SDimitry Andric std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
3719bca07a45SDimitry Andric }
372013cc256eSDimitry Andric
372106d4ba38SDimitry Andric if (Checks.size() > 0)
372206d4ba38SDimitry Andric EmitBinOpCheck(Checks, Ops);
3723bca07a45SDimitry Andric }
3724ec2b103cSEd Schouten
EmitDiv(const BinOpInfo & Ops)3725ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
37269f4dbff6SDimitry Andric {
37279f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
372806d4ba38SDimitry Andric if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
372906d4ba38SDimitry Andric CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
3730f0c0337bSDimitry Andric Ops.Ty->isIntegerType() &&
3731f0c0337bSDimitry Andric (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
3732bca07a45SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3733bca07a45SDimitry Andric EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
373406d4ba38SDimitry Andric } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
3735f0c0337bSDimitry Andric Ops.Ty->isRealFloatingType() &&
3736f0c0337bSDimitry Andric Ops.mayHaveFloatDivisionByZero()) {
3737809500fcSDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
373806d4ba38SDimitry Andric llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
373906d4ba38SDimitry Andric EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
374006d4ba38SDimitry Andric Ops);
3741bca07a45SDimitry Andric }
37429f4dbff6SDimitry Andric }
3743809500fcSDimitry Andric
3744344a3780SDimitry Andric if (Ops.Ty->isConstantMatrixType()) {
3745145449b1SDimitry Andric llvm::MatrixBuilder MB(Builder);
3746344a3780SDimitry Andric // We need to check the types of the operands of the operator to get the
3747344a3780SDimitry Andric // correct matrix dimensions.
3748344a3780SDimitry Andric auto *BO = cast<BinaryOperator>(Ops.E);
3749344a3780SDimitry Andric (void)BO;
3750344a3780SDimitry Andric assert(
3751344a3780SDimitry Andric isa<ConstantMatrixType>(BO->getLHS()->getType().getCanonicalType()) &&
3752344a3780SDimitry Andric "first operand must be a matrix");
3753344a3780SDimitry Andric assert(BO->getRHS()->getType().getCanonicalType()->isArithmeticType() &&
3754344a3780SDimitry Andric "second operand must be an arithmetic type");
3755344a3780SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3756344a3780SDimitry Andric return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3757344a3780SDimitry Andric Ops.Ty->hasUnsignedIntegerRepresentation());
3758344a3780SDimitry Andric }
3759344a3780SDimitry Andric
3760dbe13110SDimitry Andric if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
3761cfca06d7SDimitry Andric llvm::Value *Val;
3762cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3763cfca06d7SDimitry Andric Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
37647fa27ce4SDimitry Andric CGF.SetDivFPAccuracy(Val);
3765dbe13110SDimitry Andric return Val;
3766dbe13110SDimitry Andric }
3767cfca06d7SDimitry Andric else if (Ops.isFixedPointOp())
3768cfca06d7SDimitry Andric return EmitFixedPointBinOp(Ops);
37693d1dcd9bSDimitry Andric else if (Ops.Ty->hasUnsignedIntegerRepresentation())
3770ec2b103cSEd Schouten return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
3771ec2b103cSEd Schouten else
3772ec2b103cSEd Schouten return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
3773ec2b103cSEd Schouten }
3774ec2b103cSEd Schouten
EmitRem(const BinOpInfo & Ops)3775ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
3776ec2b103cSEd Schouten // Rem in C can't be a floating point type: C99 6.5.5p2.
37777442d6faSDimitry Andric if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
37787442d6faSDimitry Andric CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
3779f0c0337bSDimitry Andric Ops.Ty->isIntegerType() &&
3780f0c0337bSDimitry Andric (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
37819f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
3782bca07a45SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
3783bca07a45SDimitry Andric EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
3784bca07a45SDimitry Andric }
3785bca07a45SDimitry Andric
378601af97d3SDimitry Andric if (Ops.Ty->hasUnsignedIntegerRepresentation())
3787ec2b103cSEd Schouten return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
3788ec2b103cSEd Schouten else
3789ec2b103cSEd Schouten return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
3790ec2b103cSEd Schouten }
3791ec2b103cSEd Schouten
EmitOverflowCheckedBinOp(const BinOpInfo & Ops)3792ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
3793ec2b103cSEd Schouten unsigned IID;
3794ec2b103cSEd Schouten unsigned OpID = 0;
3795b60736ecSDimitry Andric SanitizerHandler OverflowKind;
3796ec2b103cSEd Schouten
3797809500fcSDimitry Andric bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
37984ba67500SRoman Divacky switch (Ops.Opcode) {
37993d1dcd9bSDimitry Andric case BO_Add:
38003d1dcd9bSDimitry Andric case BO_AddAssign:
3801ec2b103cSEd Schouten OpID = 1;
3802809500fcSDimitry Andric IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
3803809500fcSDimitry Andric llvm::Intrinsic::uadd_with_overflow;
3804b60736ecSDimitry Andric OverflowKind = SanitizerHandler::AddOverflow;
3805ec2b103cSEd Schouten break;
38063d1dcd9bSDimitry Andric case BO_Sub:
38073d1dcd9bSDimitry Andric case BO_SubAssign:
3808ec2b103cSEd Schouten OpID = 2;
3809809500fcSDimitry Andric IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
3810809500fcSDimitry Andric llvm::Intrinsic::usub_with_overflow;
3811b60736ecSDimitry Andric OverflowKind = SanitizerHandler::SubOverflow;
3812ec2b103cSEd Schouten break;
38133d1dcd9bSDimitry Andric case BO_Mul:
38143d1dcd9bSDimitry Andric case BO_MulAssign:
3815ec2b103cSEd Schouten OpID = 3;
3816809500fcSDimitry Andric IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
3817809500fcSDimitry Andric llvm::Intrinsic::umul_with_overflow;
3818b60736ecSDimitry Andric OverflowKind = SanitizerHandler::MulOverflow;
3819ec2b103cSEd Schouten break;
3820ec2b103cSEd Schouten default:
382136981b17SDimitry Andric llvm_unreachable("Unsupported operation for overflow detection");
3822ec2b103cSEd Schouten }
3823ec2b103cSEd Schouten OpID <<= 1;
3824809500fcSDimitry Andric if (isSigned)
3825ec2b103cSEd Schouten OpID |= 1;
3826ec2b103cSEd Schouten
38272410013dSDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
3828180abc3dSDimitry Andric llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
3829ec2b103cSEd Schouten
3830180abc3dSDimitry Andric llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
3831ec2b103cSEd Schouten
38325e20cdd8SDimitry Andric Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
3833ec2b103cSEd Schouten Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
3834ec2b103cSEd Schouten Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
3835ec2b103cSEd Schouten
383613cc256eSDimitry Andric // Handle overflow with llvm.trap if no custom handler has been specified.
383713cc256eSDimitry Andric const std::string *handlerName =
383813cc256eSDimitry Andric &CGF.getLangOpts().OverflowHandler;
383913cc256eSDimitry Andric if (handlerName->empty()) {
384013cc256eSDimitry Andric // If the signed-integer-overflow sanitizer is enabled, emit a call to its
384113cc256eSDimitry Andric // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
384206d4ba38SDimitry Andric if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
384306d4ba38SDimitry Andric llvm::Value *NotOverflow = Builder.CreateNot(overflow);
38445e20cdd8SDimitry Andric SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
384506d4ba38SDimitry Andric : SanitizerKind::UnsignedIntegerOverflow;
384606d4ba38SDimitry Andric EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
38479f4dbff6SDimitry Andric } else
3848b60736ecSDimitry Andric CGF.EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
384913cc256eSDimitry Andric return result;
385013cc256eSDimitry Andric }
385113cc256eSDimitry Andric
3852ec2b103cSEd Schouten // Branch in case of overflow.
3853bca07a45SDimitry Andric llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
3854bab175ecSDimitry Andric llvm::BasicBlock *continueBB =
3855bab175ecSDimitry Andric CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode());
38563d1dcd9bSDimitry Andric llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
3857ec2b103cSEd Schouten
3858ec2b103cSEd Schouten Builder.CreateCondBr(overflow, overflowBB, continueBB);
3859ec2b103cSEd Schouten
3860bca07a45SDimitry Andric // If an overflow handler is set, then we want to call it and then use its
3861bca07a45SDimitry Andric // result, if it returns.
3862bca07a45SDimitry Andric Builder.SetInsertPoint(overflowBB);
3863bca07a45SDimitry Andric
3864bca07a45SDimitry Andric // Get the overflow handler.
3865dbe13110SDimitry Andric llvm::Type *Int8Ty = CGF.Int8Ty;
3866180abc3dSDimitry Andric llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty };
3867bca07a45SDimitry Andric llvm::FunctionType *handlerTy =
3868bca07a45SDimitry Andric llvm::FunctionType::get(CGF.Int64Ty, argTypes, true);
386922989816SDimitry Andric llvm::FunctionCallee handler =
387022989816SDimitry Andric CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
3871bca07a45SDimitry Andric
3872bca07a45SDimitry Andric // Sign extend the args to 64-bit, so that we can use the same handler for
3873bca07a45SDimitry Andric // all types of overflow.
3874bca07a45SDimitry Andric llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty);
3875bca07a45SDimitry Andric llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty);
3876bca07a45SDimitry Andric
3877bca07a45SDimitry Andric // Call the handler with the two arguments, the operation, and the size of
3878bca07a45SDimitry Andric // the result.
3879809500fcSDimitry Andric llvm::Value *handlerArgs[] = {
3880809500fcSDimitry Andric lhs,
3881809500fcSDimitry Andric rhs,
3882bca07a45SDimitry Andric Builder.getInt8(OpID),
3883809500fcSDimitry Andric Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
3884809500fcSDimitry Andric };
3885809500fcSDimitry Andric llvm::Value *handlerResult =
3886809500fcSDimitry Andric CGF.EmitNounwindRuntimeCall(handler, handlerArgs);
3887bca07a45SDimitry Andric
3888bca07a45SDimitry Andric // Truncate the result back to the desired size.
3889bca07a45SDimitry Andric handlerResult = Builder.CreateTrunc(handlerResult, opTy);
3890bca07a45SDimitry Andric Builder.CreateBr(continueBB);
3891bca07a45SDimitry Andric
3892bca07a45SDimitry Andric Builder.SetInsertPoint(continueBB);
389301af97d3SDimitry Andric llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
3894bca07a45SDimitry Andric phi->addIncoming(result, initialBB);
3895bca07a45SDimitry Andric phi->addIncoming(handlerResult, overflowBB);
3896bca07a45SDimitry Andric
3897bca07a45SDimitry Andric return phi;
3898bca07a45SDimitry Andric }
3899bca07a45SDimitry Andric
3900180abc3dSDimitry Andric /// Emit pointer + index arithmetic.
emitPointerArithmetic(CodeGenFunction & CGF,const BinOpInfo & op,bool isSubtraction)3901180abc3dSDimitry Andric static Value *emitPointerArithmetic(CodeGenFunction &CGF,
3902180abc3dSDimitry Andric const BinOpInfo &op,
3903180abc3dSDimitry Andric bool isSubtraction) {
3904180abc3dSDimitry Andric // Must have binary (not unary) expr here. Unary pointer
3905180abc3dSDimitry Andric // increment/decrement doesn't use this path.
3906180abc3dSDimitry Andric const BinaryOperator *expr = cast<BinaryOperator>(op.E);
3907180abc3dSDimitry Andric
3908180abc3dSDimitry Andric Value *pointer = op.LHS;
3909180abc3dSDimitry Andric Expr *pointerOperand = expr->getLHS();
3910180abc3dSDimitry Andric Value *index = op.RHS;
3911180abc3dSDimitry Andric Expr *indexOperand = expr->getRHS();
3912180abc3dSDimitry Andric
3913180abc3dSDimitry Andric // In a subtraction, the LHS is always the pointer.
3914180abc3dSDimitry Andric if (!isSubtraction && !pointer->getType()->isPointerTy()) {
3915180abc3dSDimitry Andric std::swap(pointer, index);
3916180abc3dSDimitry Andric std::swap(pointerOperand, indexOperand);
39174ba67500SRoman Divacky }
3918b897c866SEd Schouten
3919325377b5SDimitry Andric bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
3920325377b5SDimitry Andric
3921180abc3dSDimitry Andric unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
3922bab175ecSDimitry Andric auto &DL = CGF.CGM.getDataLayout();
3923bab175ecSDimitry Andric auto PtrTy = cast<llvm::PointerType>(pointer->getType());
3924461a67faSDimitry Andric
3925461a67faSDimitry Andric // Some versions of glibc and gcc use idioms (particularly in their malloc
3926461a67faSDimitry Andric // routines) that add a pointer-sized integer (known to be a pointer value)
3927461a67faSDimitry Andric // to a null pointer in order to cast the value back to an integer or as
3928461a67faSDimitry Andric // part of a pointer alignment algorithm. This is undefined behavior, but
3929461a67faSDimitry Andric // we'd like to be able to compile programs that use it.
3930461a67faSDimitry Andric //
3931461a67faSDimitry Andric // Normally, we'd generate a GEP with a null-pointer base here in response
3932461a67faSDimitry Andric // to that code, but it's also UB to dereference a pointer created that
3933461a67faSDimitry Andric // way. Instead (as an acknowledged hack to tolerate the idiom) we will
3934461a67faSDimitry Andric // generate a direct cast of the integer value to a pointer.
3935461a67faSDimitry Andric //
3936461a67faSDimitry Andric // The idiom (p = nullptr + N) is not met if any of the following are true:
3937461a67faSDimitry Andric //
3938461a67faSDimitry Andric // The operation is subtraction.
3939461a67faSDimitry Andric // The index is not pointer-sized.
3940461a67faSDimitry Andric // The pointer type is not byte-sized.
3941461a67faSDimitry Andric //
3942461a67faSDimitry Andric if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(),
3943461a67faSDimitry Andric op.Opcode,
3944461a67faSDimitry Andric expr->getLHS(),
3945461a67faSDimitry Andric expr->getRHS()))
3946461a67faSDimitry Andric return CGF.Builder.CreateIntToPtr(index, pointer->getType());
3947461a67faSDimitry Andric
3948706b4fc4SDimitry Andric if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
3949180abc3dSDimitry Andric // Zero-extend or sign-extend the pointer value according to
3950180abc3dSDimitry Andric // whether the index is signed or not.
3951706b4fc4SDimitry Andric index = CGF.Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
3952180abc3dSDimitry Andric "idx.ext");
3953ec2b103cSEd Schouten }
3954ec2b103cSEd Schouten
3955180abc3dSDimitry Andric // If this is subtraction, negate the index.
3956180abc3dSDimitry Andric if (isSubtraction)
3957180abc3dSDimitry Andric index = CGF.Builder.CreateNeg(index, "idx.neg");
39584ba67500SRoman Divacky
395906d4ba38SDimitry Andric if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
3960809500fcSDimitry Andric CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
3961809500fcSDimitry Andric /*Accessed*/ false);
3962809500fcSDimitry Andric
3963180abc3dSDimitry Andric const PointerType *pointerType
3964180abc3dSDimitry Andric = pointerOperand->getType()->getAs<PointerType>();
3965180abc3dSDimitry Andric if (!pointerType) {
3966180abc3dSDimitry Andric QualType objectType = pointerOperand->getType()
3967180abc3dSDimitry Andric ->castAs<ObjCObjectPointerType>()
3968180abc3dSDimitry Andric ->getPointeeType();
3969180abc3dSDimitry Andric llvm::Value *objectSize
3970180abc3dSDimitry Andric = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType));
3971180abc3dSDimitry Andric
3972180abc3dSDimitry Andric index = CGF.Builder.CreateMul(index, objectSize);
3973180abc3dSDimitry Andric
3974b1c73532SDimitry Andric Value *result =
3975b1c73532SDimitry Andric CGF.Builder.CreateGEP(CGF.Int8Ty, pointer, index, "add.ptr");
3976180abc3dSDimitry Andric return CGF.Builder.CreateBitCast(result, pointer->getType());
3977ec2b103cSEd Schouten }
39784ba67500SRoman Divacky
3979180abc3dSDimitry Andric QualType elementType = pointerType->getPointeeType();
3980180abc3dSDimitry Andric if (const VariableArrayType *vla
3981180abc3dSDimitry Andric = CGF.getContext().getAsVariableArrayType(elementType)) {
3982180abc3dSDimitry Andric // The element count here is the total number of non-VLA elements.
398348675466SDimitry Andric llvm::Value *numElements = CGF.getVLASize(vla).NumElts;
3984ec2b103cSEd Schouten
3985180abc3dSDimitry Andric // Effectively, the multiply by the VLA size is part of the GEP.
3986180abc3dSDimitry Andric // GEP indexes are signed, and scaling an index isn't permitted to
3987180abc3dSDimitry Andric // signed-overflow, so we use the same semantics for our explicit
3988180abc3dSDimitry Andric // multiply. We suppress this if overflow is not undefined behavior.
3989145449b1SDimitry Andric llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
3990dbe13110SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined()) {
3991180abc3dSDimitry Andric index = CGF.Builder.CreateMul(index, numElements, "vla.index");
399277fc4c14SDimitry Andric pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
3993180abc3dSDimitry Andric } else {
3994180abc3dSDimitry Andric index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
399577fc4c14SDimitry Andric pointer = CGF.EmitCheckedInBoundsGEP(
399677fc4c14SDimitry Andric elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
399777fc4c14SDimitry Andric "add.ptr");
3998ec2b103cSEd Schouten }
3999180abc3dSDimitry Andric return pointer;
4000ec2b103cSEd Schouten }
4001ec2b103cSEd Schouten
40024c8b2481SRoman Divacky // Explicitly handle GNU void* and function pointer arithmetic extensions. The
40034c8b2481SRoman Divacky // GNU void* casts amount to no-ops since our void* type is i8*, but this is
40044c8b2481SRoman Divacky // future proof.
4005b1c73532SDimitry Andric llvm::Type *elemTy;
40067fa27ce4SDimitry Andric if (elementType->isVoidType() || elementType->isFunctionType())
4007b1c73532SDimitry Andric elemTy = CGF.Int8Ty;
4008b1c73532SDimitry Andric else
4009b1c73532SDimitry Andric elemTy = CGF.ConvertTypeForMem(elementType);
4010ec2b103cSEd Schouten
4011dbe13110SDimitry Andric if (CGF.getLangOpts().isSignedOverflowDefined())
401277fc4c14SDimitry Andric return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
4013180abc3dSDimitry Andric
401477fc4c14SDimitry Andric return CGF.EmitCheckedInBoundsGEP(
401577fc4c14SDimitry Andric elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
401677fc4c14SDimitry Andric "add.ptr");
4017ec2b103cSEd Schouten }
4018ec2b103cSEd Schouten
401913cc256eSDimitry Andric // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
402013cc256eSDimitry Andric // Addend. Use negMul and negAdd to negate the first operand of the Mul or
402113cc256eSDimitry Andric // the add operand respectively. This allows fmuladd to represent a*b-c, or
402213cc256eSDimitry Andric // c-a*b. Patterns in LLVM should catch the negated forms and translate them to
402313cc256eSDimitry Andric // efficient operations.
buildFMulAdd(llvm::Instruction * MulOp,Value * Addend,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool negMul,bool negAdd)4024cfca06d7SDimitry Andric static Value* buildFMulAdd(llvm::Instruction *MulOp, Value *Addend,
402513cc256eSDimitry Andric const CodeGenFunction &CGF, CGBuilderTy &Builder,
402613cc256eSDimitry Andric bool negMul, bool negAdd) {
402713cc256eSDimitry Andric Value *MulOp0 = MulOp->getOperand(0);
402813cc256eSDimitry Andric Value *MulOp1 = MulOp->getOperand(1);
4029706b4fc4SDimitry Andric if (negMul)
4030706b4fc4SDimitry Andric MulOp0 = Builder.CreateFNeg(MulOp0, "neg");
4031706b4fc4SDimitry Andric if (negAdd)
4032706b4fc4SDimitry Andric Addend = Builder.CreateFNeg(Addend, "neg");
403313cc256eSDimitry Andric
4034cfca06d7SDimitry Andric Value *FMulAdd = nullptr;
4035cfca06d7SDimitry Andric if (Builder.getIsFPConstrained()) {
4036cfca06d7SDimitry Andric assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
4037cfca06d7SDimitry Andric "Only constrained operation should be created when Builder is in FP "
4038cfca06d7SDimitry Andric "constrained mode");
4039cfca06d7SDimitry Andric FMulAdd = Builder.CreateConstrainedFPCall(
4040cfca06d7SDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4041cfca06d7SDimitry Andric Addend->getType()),
4042cfca06d7SDimitry Andric {MulOp0, MulOp1, Addend});
4043cfca06d7SDimitry Andric } else {
4044cfca06d7SDimitry Andric FMulAdd = Builder.CreateCall(
404513cc256eSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
40465e20cdd8SDimitry Andric {MulOp0, MulOp1, Addend});
4047cfca06d7SDimitry Andric }
404813cc256eSDimitry Andric MulOp->eraseFromParent();
404913cc256eSDimitry Andric
405013cc256eSDimitry Andric return FMulAdd;
405113cc256eSDimitry Andric }
405213cc256eSDimitry Andric
405313cc256eSDimitry Andric // Check whether it would be legal to emit an fmuladd intrinsic call to
405413cc256eSDimitry Andric // represent op and if so, build the fmuladd.
405513cc256eSDimitry Andric //
405613cc256eSDimitry Andric // Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
405713cc256eSDimitry Andric // Does NOT check the type of the operation - it's assumed that this function
405813cc256eSDimitry 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)405913cc256eSDimitry Andric static Value* tryEmitFMulAdd(const BinOpInfo &op,
406013cc256eSDimitry Andric const CodeGenFunction &CGF, CGBuilderTy &Builder,
406113cc256eSDimitry Andric bool isSub=false) {
406213cc256eSDimitry Andric
406313cc256eSDimitry Andric assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
406413cc256eSDimitry Andric op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
406513cc256eSDimitry Andric "Only fadd/fsub can be the root of an fmuladd.");
406613cc256eSDimitry Andric
406713cc256eSDimitry Andric // Check whether this op is marked as fusable.
40687442d6faSDimitry Andric if (!op.FPFeatures.allowFPContractWithinStatement())
40699f4dbff6SDimitry Andric return nullptr;
407013cc256eSDimitry Andric
40717fa27ce4SDimitry Andric Value *LHS = op.LHS;
40727fa27ce4SDimitry Andric Value *RHS = op.RHS;
40737fa27ce4SDimitry Andric
40747fa27ce4SDimitry Andric // Peek through fneg to look for fmul. Make sure fneg has no users, and that
40757fa27ce4SDimitry Andric // it is the only use of its operand.
40767fa27ce4SDimitry Andric bool NegLHS = false;
40777fa27ce4SDimitry Andric if (auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
40787fa27ce4SDimitry Andric if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
40797fa27ce4SDimitry Andric LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
40807fa27ce4SDimitry Andric LHS = LHSUnOp->getOperand(0);
40817fa27ce4SDimitry Andric NegLHS = true;
40827fa27ce4SDimitry Andric }
40837fa27ce4SDimitry Andric }
40847fa27ce4SDimitry Andric
40857fa27ce4SDimitry Andric bool NegRHS = false;
40867fa27ce4SDimitry Andric if (auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
40877fa27ce4SDimitry Andric if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
40887fa27ce4SDimitry Andric RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
40897fa27ce4SDimitry Andric RHS = RHSUnOp->getOperand(0);
40907fa27ce4SDimitry Andric NegRHS = true;
40917fa27ce4SDimitry Andric }
40927fa27ce4SDimitry Andric }
40937fa27ce4SDimitry Andric
409413cc256eSDimitry Andric // We have a potentially fusable op. Look for a mul on one of the operands.
409545b53394SDimitry Andric // Also, make sure that the mul result isn't used directly. In that case,
409645b53394SDimitry Andric // there's no point creating a muladd operation.
40977fa27ce4SDimitry Andric if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
409845b53394SDimitry Andric if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
40997fa27ce4SDimitry Andric (LHSBinOp->use_empty() || NegLHS)) {
41007fa27ce4SDimitry Andric // If we looked through fneg, erase it.
41017fa27ce4SDimitry Andric if (NegLHS)
41027fa27ce4SDimitry Andric cast<llvm::Instruction>(op.LHS)->eraseFromParent();
41037fa27ce4SDimitry Andric return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
410413cc256eSDimitry Andric }
41057fa27ce4SDimitry Andric }
41067fa27ce4SDimitry Andric if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
410745b53394SDimitry Andric if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
41087fa27ce4SDimitry Andric (RHSBinOp->use_empty() || NegRHS)) {
41097fa27ce4SDimitry Andric // If we looked through fneg, erase it.
41107fa27ce4SDimitry Andric if (NegRHS)
41117fa27ce4SDimitry Andric cast<llvm::Instruction>(op.RHS)->eraseFromParent();
41127fa27ce4SDimitry Andric return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS, false);
41137fa27ce4SDimitry Andric }
411413cc256eSDimitry Andric }
411513cc256eSDimitry Andric
41167fa27ce4SDimitry Andric if (auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4117cfca06d7SDimitry Andric if (LHSBinOp->getIntrinsicID() ==
4118cfca06d7SDimitry Andric llvm::Intrinsic::experimental_constrained_fmul &&
41197fa27ce4SDimitry Andric (LHSBinOp->use_empty() || NegLHS)) {
41207fa27ce4SDimitry Andric // If we looked through fneg, erase it.
41217fa27ce4SDimitry Andric if (NegLHS)
41227fa27ce4SDimitry Andric cast<llvm::Instruction>(op.LHS)->eraseFromParent();
41237fa27ce4SDimitry Andric return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4124cfca06d7SDimitry Andric }
41257fa27ce4SDimitry Andric }
41267fa27ce4SDimitry Andric if (auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4127cfca06d7SDimitry Andric if (RHSBinOp->getIntrinsicID() ==
4128cfca06d7SDimitry Andric llvm::Intrinsic::experimental_constrained_fmul &&
41297fa27ce4SDimitry Andric (RHSBinOp->use_empty() || NegRHS)) {
41307fa27ce4SDimitry Andric // If we looked through fneg, erase it.
41317fa27ce4SDimitry Andric if (NegRHS)
41327fa27ce4SDimitry Andric cast<llvm::Instruction>(op.RHS)->eraseFromParent();
41337fa27ce4SDimitry Andric return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS, false);
41347fa27ce4SDimitry Andric }
4135cfca06d7SDimitry Andric }
4136cfca06d7SDimitry Andric
41379f4dbff6SDimitry Andric return nullptr;
413813cc256eSDimitry Andric }
413913cc256eSDimitry Andric
EmitAdd(const BinOpInfo & op)4140180abc3dSDimitry Andric Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
4141180abc3dSDimitry Andric if (op.LHS->getType()->isPointerTy() ||
4142180abc3dSDimitry Andric op.RHS->getType()->isPointerTy())
4143de51d671SDimitry Andric return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction);
4144180abc3dSDimitry Andric
4145180abc3dSDimitry Andric if (op.Ty->isSignedIntegerOrEnumerationType()) {
414613cc256eSDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
41474ba67500SRoman Divacky case LangOptions::SOB_Defined:
4148ac9a064cSDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
4149180abc3dSDimitry Andric return Builder.CreateAdd(op.LHS, op.RHS, "add");
4150ac9a064cSDimitry Andric [[fallthrough]];
415113cc256eSDimitry Andric case LangOptions::SOB_Undefined:
415206d4ba38SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
415313cc256eSDimitry Andric return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
4154e3b55780SDimitry Andric [[fallthrough]];
41554ba67500SRoman Divacky case LangOptions::SOB_Trapping:
41567442d6faSDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), op))
41577442d6faSDimitry Andric return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
4158180abc3dSDimitry Andric return EmitOverflowCheckedBinOp(op);
41594ba67500SRoman Divacky }
41604ba67500SRoman Divacky }
4161b897c866SEd Schouten
4162b1c73532SDimitry Andric // For vector and matrix adds, try to fold into a fmuladd.
4163b1c73532SDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
4164b1c73532SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4165b1c73532SDimitry Andric // Try to form an fmuladd.
4166b1c73532SDimitry Andric if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
4167b1c73532SDimitry Andric return FMulAdd;
4168b1c73532SDimitry Andric }
4169b1c73532SDimitry Andric
4170cfca06d7SDimitry Andric if (op.Ty->isConstantMatrixType()) {
4171145449b1SDimitry Andric llvm::MatrixBuilder MB(Builder);
4172344a3780SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4173cfca06d7SDimitry Andric return MB.CreateAdd(op.LHS, op.RHS);
4174cfca06d7SDimitry Andric }
4175cfca06d7SDimitry Andric
417606d4ba38SDimitry Andric if (op.Ty->isUnsignedIntegerType() &&
41777442d6faSDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
41787442d6faSDimitry Andric !CanElideOverflowCheck(CGF.getContext(), op))
4179809500fcSDimitry Andric return EmitOverflowCheckedBinOp(op);
4180809500fcSDimitry Andric
418113cc256eSDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
4182cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4183cfca06d7SDimitry Andric return Builder.CreateFAdd(op.LHS, op.RHS, "add");
418413cc256eSDimitry Andric }
418511d2b2d2SRoman Divacky
4186cfca06d7SDimitry Andric if (op.isFixedPointOp())
418722989816SDimitry Andric return EmitFixedPointBinOp(op);
418822989816SDimitry Andric
4189180abc3dSDimitry Andric return Builder.CreateAdd(op.LHS, op.RHS, "add");
4190ec2b103cSEd Schouten }
4191ec2b103cSEd Schouten
419222989816SDimitry Andric /// The resulting value must be calculated with exact precision, so the operands
419322989816SDimitry Andric /// may not be the same type.
EmitFixedPointBinOp(const BinOpInfo & op)419422989816SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {
419522989816SDimitry Andric using llvm::APSInt;
419622989816SDimitry Andric using llvm::ConstantInt;
419722989816SDimitry Andric
4198cfca06d7SDimitry Andric // This is either a binary operation where at least one of the operands is
4199cfca06d7SDimitry Andric // a fixed-point type, or a unary operation where the operand is a fixed-point
4200cfca06d7SDimitry Andric // type. The result type of a binary operation is determined by
4201cfca06d7SDimitry Andric // Sema::handleFixedPointConversions().
420222989816SDimitry Andric QualType ResultTy = op.Ty;
4203cfca06d7SDimitry Andric QualType LHSTy, RHSTy;
4204cfca06d7SDimitry Andric if (const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4205cfca06d7SDimitry Andric RHSTy = BinOp->getRHS()->getType();
4206cfca06d7SDimitry Andric if (const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4207cfca06d7SDimitry Andric // For compound assignment, the effective type of the LHS at this point
4208cfca06d7SDimitry Andric // is the computation LHS type, not the actual LHS type, and the final
4209cfca06d7SDimitry Andric // result type is not the type of the expression but rather the
4210cfca06d7SDimitry Andric // computation result type.
4211cfca06d7SDimitry Andric LHSTy = CAO->getComputationLHSType();
4212cfca06d7SDimitry Andric ResultTy = CAO->getComputationResultType();
4213cfca06d7SDimitry Andric } else
4214cfca06d7SDimitry Andric LHSTy = BinOp->getLHS()->getType();
4215cfca06d7SDimitry Andric } else if (const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4216cfca06d7SDimitry Andric LHSTy = UnOp->getSubExpr()->getType();
4217cfca06d7SDimitry Andric RHSTy = UnOp->getSubExpr()->getType();
4218cfca06d7SDimitry Andric }
421922989816SDimitry Andric ASTContext &Ctx = CGF.getContext();
422022989816SDimitry Andric Value *LHS = op.LHS;
422122989816SDimitry Andric Value *RHS = op.RHS;
422222989816SDimitry Andric
422322989816SDimitry Andric auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy);
422422989816SDimitry Andric auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy);
422522989816SDimitry Andric auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy);
422622989816SDimitry Andric auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
422722989816SDimitry Andric
4228cfca06d7SDimitry Andric // Perform the actual operation.
422922989816SDimitry Andric Value *Result;
4230b60736ecSDimitry Andric llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4231cfca06d7SDimitry Andric switch (op.Opcode) {
4232cfca06d7SDimitry Andric case BO_AddAssign:
4233b60736ecSDimitry Andric case BO_Add:
4234b60736ecSDimitry Andric Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
423522989816SDimitry Andric break;
4236cfca06d7SDimitry Andric case BO_SubAssign:
4237b60736ecSDimitry Andric case BO_Sub:
4238b60736ecSDimitry Andric Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
423922989816SDimitry Andric break;
4240cfca06d7SDimitry Andric case BO_MulAssign:
4241b60736ecSDimitry Andric case BO_Mul:
4242b60736ecSDimitry Andric Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4243cfca06d7SDimitry Andric break;
4244cfca06d7SDimitry Andric case BO_DivAssign:
4245b60736ecSDimitry Andric case BO_Div:
4246b60736ecSDimitry Andric Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4247cfca06d7SDimitry Andric break;
4248b60736ecSDimitry Andric case BO_ShlAssign:
4249b60736ecSDimitry Andric case BO_Shl:
4250b60736ecSDimitry Andric Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4251b60736ecSDimitry Andric break;
4252b60736ecSDimitry Andric case BO_ShrAssign:
4253b60736ecSDimitry Andric case BO_Shr:
4254b60736ecSDimitry Andric Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4255b60736ecSDimitry Andric break;
425622989816SDimitry Andric case BO_LT:
4257b60736ecSDimitry Andric return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
425822989816SDimitry Andric case BO_GT:
4259b60736ecSDimitry Andric return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
426022989816SDimitry Andric case BO_LE:
4261b60736ecSDimitry Andric return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
426222989816SDimitry Andric case BO_GE:
4263b60736ecSDimitry Andric return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
426422989816SDimitry Andric case BO_EQ:
426522989816SDimitry Andric // For equality operations, we assume any padding bits on unsigned types are
426622989816SDimitry Andric // zero'd out. They could be overwritten through non-saturating operations
426722989816SDimitry Andric // that cause overflow, but this leads to undefined behavior.
4268b60736ecSDimitry Andric return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
426922989816SDimitry Andric case BO_NE:
4270b60736ecSDimitry Andric return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
427122989816SDimitry Andric case BO_Cmp:
427222989816SDimitry Andric case BO_LAnd:
427322989816SDimitry Andric case BO_LOr:
427422989816SDimitry Andric llvm_unreachable("Found unimplemented fixed point binary operation");
427522989816SDimitry Andric case BO_PtrMemD:
427622989816SDimitry Andric case BO_PtrMemI:
427722989816SDimitry Andric case BO_Rem:
427822989816SDimitry Andric case BO_Xor:
427922989816SDimitry Andric case BO_And:
428022989816SDimitry Andric case BO_Or:
428122989816SDimitry Andric case BO_Assign:
428222989816SDimitry Andric case BO_RemAssign:
428322989816SDimitry Andric case BO_AndAssign:
428422989816SDimitry Andric case BO_XorAssign:
428522989816SDimitry Andric case BO_OrAssign:
428622989816SDimitry Andric case BO_Comma:
428722989816SDimitry Andric llvm_unreachable("Found unsupported binary operation for fixed point types.");
428822989816SDimitry Andric }
428922989816SDimitry Andric
4290b60736ecSDimitry Andric bool IsShift = BinaryOperator::isShiftOp(op.Opcode) ||
4291b60736ecSDimitry Andric BinaryOperator::isShiftAssignOp(op.Opcode);
429222989816SDimitry Andric // Convert to the result type.
4293b60736ecSDimitry Andric return FPBuilder.CreateFixedToFixed(Result, IsShift ? LHSFixedSema
4294b60736ecSDimitry Andric : CommonFixedSema,
4295b60736ecSDimitry Andric ResultFixedSema);
429622989816SDimitry Andric }
429722989816SDimitry Andric
EmitSub(const BinOpInfo & op)4298180abc3dSDimitry Andric Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
4299180abc3dSDimitry Andric // The LHS is always a pointer if either side is.
4300180abc3dSDimitry Andric if (!op.LHS->getType()->isPointerTy()) {
4301180abc3dSDimitry Andric if (op.Ty->isSignedIntegerOrEnumerationType()) {
430213cc256eSDimitry Andric switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
4303180abc3dSDimitry Andric case LangOptions::SOB_Defined:
4304ac9a064cSDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
4305180abc3dSDimitry Andric return Builder.CreateSub(op.LHS, op.RHS, "sub");
4306ac9a064cSDimitry Andric [[fallthrough]];
430713cc256eSDimitry Andric case LangOptions::SOB_Undefined:
430806d4ba38SDimitry Andric if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
430913cc256eSDimitry Andric return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
4310e3b55780SDimitry Andric [[fallthrough]];
4311180abc3dSDimitry Andric case LangOptions::SOB_Trapping:
43127442d6faSDimitry Andric if (CanElideOverflowCheck(CGF.getContext(), op))
43137442d6faSDimitry Andric return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
4314180abc3dSDimitry Andric return EmitOverflowCheckedBinOp(op);
4315180abc3dSDimitry Andric }
4316ec2b103cSEd Schouten }
4317ec2b103cSEd Schouten
4318b1c73532SDimitry Andric // For vector and matrix subs, try to fold into a fmuladd.
4319b1c73532SDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
4320b1c73532SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4321b1c73532SDimitry Andric // Try to form an fmuladd.
4322b1c73532SDimitry Andric if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
4323b1c73532SDimitry Andric return FMulAdd;
4324b1c73532SDimitry Andric }
4325b1c73532SDimitry Andric
4326cfca06d7SDimitry Andric if (op.Ty->isConstantMatrixType()) {
4327145449b1SDimitry Andric llvm::MatrixBuilder MB(Builder);
4328344a3780SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4329cfca06d7SDimitry Andric return MB.CreateSub(op.LHS, op.RHS);
4330cfca06d7SDimitry Andric }
4331cfca06d7SDimitry Andric
433206d4ba38SDimitry Andric if (op.Ty->isUnsignedIntegerType() &&
43337442d6faSDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
43347442d6faSDimitry Andric !CanElideOverflowCheck(CGF.getContext(), op))
4335809500fcSDimitry Andric return EmitOverflowCheckedBinOp(op);
4336809500fcSDimitry Andric
433713cc256eSDimitry Andric if (op.LHS->getType()->isFPOrFPVectorTy()) {
4338cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4339cfca06d7SDimitry Andric return Builder.CreateFSub(op.LHS, op.RHS, "sub");
434013cc256eSDimitry Andric }
4341180abc3dSDimitry Andric
4342cfca06d7SDimitry Andric if (op.isFixedPointOp())
434322989816SDimitry Andric return EmitFixedPointBinOp(op);
434422989816SDimitry Andric
4345180abc3dSDimitry Andric return Builder.CreateSub(op.LHS, op.RHS, "sub");
4346180abc3dSDimitry Andric }
4347180abc3dSDimitry Andric
4348180abc3dSDimitry Andric // If the RHS is not a pointer, then we have normal pointer
4349180abc3dSDimitry Andric // arithmetic.
4350180abc3dSDimitry Andric if (!op.RHS->getType()->isPointerTy())
4351de51d671SDimitry Andric return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction);
4352180abc3dSDimitry Andric
4353180abc3dSDimitry Andric // Otherwise, this is a pointer subtraction.
4354180abc3dSDimitry Andric
4355180abc3dSDimitry Andric // Do the raw subtraction part.
4356180abc3dSDimitry Andric llvm::Value *LHS
4357180abc3dSDimitry Andric = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast");
4358180abc3dSDimitry Andric llvm::Value *RHS
4359180abc3dSDimitry Andric = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast");
4360180abc3dSDimitry Andric Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
4361180abc3dSDimitry Andric
4362180abc3dSDimitry Andric // Okay, figure out the element size.
4363180abc3dSDimitry Andric const BinaryOperator *expr = cast<BinaryOperator>(op.E);
4364180abc3dSDimitry Andric QualType elementType = expr->getLHS()->getType()->getPointeeType();
4365180abc3dSDimitry Andric
43669f4dbff6SDimitry Andric llvm::Value *divisor = nullptr;
4367180abc3dSDimitry Andric
4368180abc3dSDimitry Andric // For a variable-length array, this is going to be non-constant.
4369180abc3dSDimitry Andric if (const VariableArrayType *vla
4370180abc3dSDimitry Andric = CGF.getContext().getAsVariableArrayType(elementType)) {
437148675466SDimitry Andric auto VlaSize = CGF.getVLASize(vla);
437248675466SDimitry Andric elementType = VlaSize.Type;
437348675466SDimitry Andric divisor = VlaSize.NumElts;
4374180abc3dSDimitry Andric
4375180abc3dSDimitry Andric // Scale the number of non-VLA elements by the non-VLA element size.
4376180abc3dSDimitry Andric CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType);
4377180abc3dSDimitry Andric if (!eltSize.isOne())
4378180abc3dSDimitry Andric divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor);
4379180abc3dSDimitry Andric
4380180abc3dSDimitry Andric // For everything elese, we can just compute it, safe in the
4381180abc3dSDimitry Andric // assumption that Sema won't let anything through that we can't
4382180abc3dSDimitry Andric // safely compute the size of.
4383180abc3dSDimitry Andric } else {
4384180abc3dSDimitry Andric CharUnits elementSize;
4385180abc3dSDimitry Andric // Handle GCC extension for pointer arithmetic on void* and
4386180abc3dSDimitry Andric // function pointer types.
4387180abc3dSDimitry Andric if (elementType->isVoidType() || elementType->isFunctionType())
4388180abc3dSDimitry Andric elementSize = CharUnits::One();
4389ec2b103cSEd Schouten else
4390180abc3dSDimitry Andric elementSize = CGF.getContext().getTypeSizeInChars(elementType);
4391180abc3dSDimitry Andric
4392180abc3dSDimitry Andric // Don't even emit the divide for element size of 1.
4393180abc3dSDimitry Andric if (elementSize.isOne())
4394180abc3dSDimitry Andric return diffInChars;
4395180abc3dSDimitry Andric
4396180abc3dSDimitry Andric divisor = CGF.CGM.getSize(elementSize);
4397ec2b103cSEd Schouten }
4398ec2b103cSEd Schouten
43994c8b2481SRoman Divacky // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
44004c8b2481SRoman Divacky // pointer difference in C is only defined in the case where both operands
44014c8b2481SRoman Divacky // are pointing to elements of an array.
4402180abc3dSDimitry Andric return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div");
4403ec2b103cSEd Schouten }
4404ec2b103cSEd Schouten
GetMaximumShiftAmount(Value * LHS,Value * RHS,bool RHSIsSigned)4405ac9a064cSDimitry Andric Value *ScalarExprEmitter::GetMaximumShiftAmount(Value *LHS, Value *RHS,
4406ac9a064cSDimitry Andric bool RHSIsSigned) {
4407809500fcSDimitry Andric llvm::IntegerType *Ty;
4408809500fcSDimitry Andric if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
4409809500fcSDimitry Andric Ty = cast<llvm::IntegerType>(VT->getElementType());
4410809500fcSDimitry Andric else
4411809500fcSDimitry Andric Ty = cast<llvm::IntegerType>(LHS->getType());
4412ac9a064cSDimitry Andric // For a given type of LHS the maximum shift amount is width(LHS)-1, however
4413ac9a064cSDimitry Andric // it can occur that width(LHS)-1 > range(RHS). Since there is no check for
4414ac9a064cSDimitry Andric // this in ConstantInt::get, this results in the value getting truncated.
4415ac9a064cSDimitry Andric // Constrain the return value to be max(RHS) in this case.
4416ac9a064cSDimitry Andric llvm::Type *RHSTy = RHS->getType();
4417ac9a064cSDimitry Andric llvm::APInt RHSMax =
4418ac9a064cSDimitry Andric RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4419ac9a064cSDimitry Andric : llvm::APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4420ac9a064cSDimitry Andric if (RHSMax.ult(Ty->getBitWidth()))
4421ac9a064cSDimitry Andric return llvm::ConstantInt::get(RHSTy, RHSMax);
4422ac9a064cSDimitry Andric return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4423809500fcSDimitry Andric }
4424809500fcSDimitry Andric
ConstrainShiftValue(Value * LHS,Value * RHS,const Twine & Name)4425cfca06d7SDimitry Andric Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS,
4426cfca06d7SDimitry Andric const Twine &Name) {
4427cfca06d7SDimitry Andric llvm::IntegerType *Ty;
4428cfca06d7SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
4429cfca06d7SDimitry Andric Ty = cast<llvm::IntegerType>(VT->getElementType());
4430cfca06d7SDimitry Andric else
4431cfca06d7SDimitry Andric Ty = cast<llvm::IntegerType>(LHS->getType());
4432cfca06d7SDimitry Andric
4433cfca06d7SDimitry Andric if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4434ac9a064cSDimitry Andric return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS, false), Name);
4435cfca06d7SDimitry Andric
4436cfca06d7SDimitry Andric return Builder.CreateURem(
4437cfca06d7SDimitry Andric RHS, llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth()), Name);
4438cfca06d7SDimitry Andric }
4439cfca06d7SDimitry Andric
EmitShl(const BinOpInfo & Ops)4440ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
4441b60736ecSDimitry Andric // TODO: This misses out on the sanitizer check below.
4442b60736ecSDimitry Andric if (Ops.isFixedPointOp())
4443b60736ecSDimitry Andric return EmitFixedPointBinOp(Ops);
4444b60736ecSDimitry Andric
4445ec2b103cSEd Schouten // LLVM requires the LHS and RHS to be the same type: promote or truncate the
4446ec2b103cSEd Schouten // RHS to the same size as the LHS.
4447ec2b103cSEd Schouten Value *RHS = Ops.RHS;
4448ec2b103cSEd Schouten if (Ops.LHS->getType() != RHS->getType())
4449ec2b103cSEd Schouten RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
4450ec2b103cSEd Schouten
4451b60736ecSDimitry Andric bool SanitizeSignedBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
4452cb2d6caaSDimitry Andric Ops.Ty->hasSignedIntegerRepresentation() &&
445322989816SDimitry Andric !CGF.getLangOpts().isSignedOverflowDefined() &&
4454cfca06d7SDimitry Andric !CGF.getLangOpts().CPlusPlus20;
4455b60736ecSDimitry Andric bool SanitizeUnsignedBase =
4456b60736ecSDimitry Andric CGF.SanOpts.has(SanitizerKind::UnsignedShiftBase) &&
4457b60736ecSDimitry Andric Ops.Ty->hasUnsignedIntegerRepresentation();
4458b60736ecSDimitry Andric bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
44595e20cdd8SDimitry Andric bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
44605e20cdd8SDimitry Andric // OpenCL 6.3j: shift values are effectively % word size of LHS.
4461ac9a064cSDimitry Andric if (CGF.getLangOpts().OpenCL || CGF.getLangOpts().HLSL)
4462cfca06d7SDimitry Andric RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
44635e20cdd8SDimitry Andric else if ((SanitizeBase || SanitizeExponent) &&
446413cc256eSDimitry Andric isa<llvm::IntegerType>(Ops.LHS->getType())) {
44659f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
44665e20cdd8SDimitry Andric SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
4467ac9a064cSDimitry Andric bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4468ac9a064cSDimitry Andric llvm::Value *WidthMinusOne =
4469ac9a064cSDimitry Andric GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
44707442d6faSDimitry Andric llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
447113cc256eSDimitry Andric
44725e20cdd8SDimitry Andric if (SanitizeExponent) {
44735e20cdd8SDimitry Andric Checks.push_back(
44745e20cdd8SDimitry Andric std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
44755e20cdd8SDimitry Andric }
44765e20cdd8SDimitry Andric
44775e20cdd8SDimitry Andric if (SanitizeBase) {
44785e20cdd8SDimitry Andric // Check whether we are shifting any non-zero bits off the top of the
44795e20cdd8SDimitry Andric // integer. We only emit this check if exponent is valid - otherwise
44805e20cdd8SDimitry Andric // instructions below will have undefined behavior themselves.
4481809500fcSDimitry Andric llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4482809500fcSDimitry Andric llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
44835e20cdd8SDimitry Andric llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
44845e20cdd8SDimitry Andric Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
44857442d6faSDimitry Andric llvm::Value *PromotedWidthMinusOne =
44867442d6faSDimitry Andric (RHS == Ops.RHS) ? WidthMinusOne
4487ac9a064cSDimitry Andric : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
44885e20cdd8SDimitry Andric CGF.EmitBlock(CheckShiftBase);
44897442d6faSDimitry Andric llvm::Value *BitsShiftedOff = Builder.CreateLShr(
44907442d6faSDimitry Andric Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
449113cc256eSDimitry Andric /*NUW*/ true, /*NSW*/ true),
449213cc256eSDimitry Andric "shl.check");
4493b60736ecSDimitry Andric if (SanitizeUnsignedBase || CGF.getLangOpts().CPlusPlus) {
449413cc256eSDimitry Andric // In C99, we are not permitted to shift a 1 bit into the sign bit.
449513cc256eSDimitry Andric // Under C++11's rules, shifting a 1 bit into the sign bit is
449613cc256eSDimitry Andric // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't
449713cc256eSDimitry Andric // define signed left shifts, so we use the C99 and C++11 rules there).
4498b60736ecSDimitry Andric // Unsigned shifts can always shift into the top bit.
449913cc256eSDimitry Andric llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
450013cc256eSDimitry Andric BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
450113cc256eSDimitry Andric }
450213cc256eSDimitry Andric llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
45035e20cdd8SDimitry Andric llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
4504809500fcSDimitry Andric CGF.EmitBlock(Cont);
45055e20cdd8SDimitry Andric llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
45065e20cdd8SDimitry Andric BaseCheck->addIncoming(Builder.getTrue(), Orig);
45075e20cdd8SDimitry Andric BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4508b60736ecSDimitry Andric Checks.push_back(std::make_pair(
4509b60736ecSDimitry Andric BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4510b60736ecSDimitry Andric : SanitizerKind::UnsignedShiftBase));
451113cc256eSDimitry Andric }
4512809500fcSDimitry Andric
45135e20cdd8SDimitry Andric assert(!Checks.empty());
45145e20cdd8SDimitry Andric EmitBinOpCheck(Checks, Ops);
451534d02d0bSRoman Divacky }
451634d02d0bSRoman Divacky
4517ec2b103cSEd Schouten return Builder.CreateShl(Ops.LHS, RHS, "shl");
4518ec2b103cSEd Schouten }
4519ec2b103cSEd Schouten
EmitShr(const BinOpInfo & Ops)4520ec2b103cSEd Schouten Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
4521b60736ecSDimitry Andric // TODO: This misses out on the sanitizer check below.
4522b60736ecSDimitry Andric if (Ops.isFixedPointOp())
4523b60736ecSDimitry Andric return EmitFixedPointBinOp(Ops);
4524b60736ecSDimitry Andric
4525ec2b103cSEd Schouten // LLVM requires the LHS and RHS to be the same type: promote or truncate the
4526ec2b103cSEd Schouten // RHS to the same size as the LHS.
4527ec2b103cSEd Schouten Value *RHS = Ops.RHS;
4528ec2b103cSEd Schouten if (Ops.LHS->getType() != RHS->getType())
4529ec2b103cSEd Schouten RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
4530ec2b103cSEd Schouten
45315e20cdd8SDimitry Andric // OpenCL 6.3j: shift values are effectively % word size of LHS.
4532ac9a064cSDimitry Andric if (CGF.getLangOpts().OpenCL || CGF.getLangOpts().HLSL)
4533cfca06d7SDimitry Andric RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
45345e20cdd8SDimitry Andric else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
45359f4dbff6SDimitry Andric isa<llvm::IntegerType>(Ops.LHS->getType())) {
45369f4dbff6SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF);
4537ac9a064cSDimitry Andric bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4538ac9a064cSDimitry Andric llvm::Value *Valid = Builder.CreateICmpULE(
4539ac9a064cSDimitry Andric Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
45405e20cdd8SDimitry Andric EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
45419f4dbff6SDimitry Andric }
4542809500fcSDimitry Andric
45433d1dcd9bSDimitry Andric if (Ops.Ty->hasUnsignedIntegerRepresentation())
4544ec2b103cSEd Schouten return Builder.CreateLShr(Ops.LHS, RHS, "shr");
4545ec2b103cSEd Schouten return Builder.CreateAShr(Ops.LHS, RHS, "shr");
4546ec2b103cSEd Schouten }
4547ec2b103cSEd Schouten
4548bca07a45SDimitry Andric enum IntrinsicType { VCMPEQ, VCMPGT };
4549bca07a45SDimitry Andric // return corresponding comparison intrinsic for given vector type
GetIntrinsic(IntrinsicType IT,BuiltinType::Kind ElemKind)4550bca07a45SDimitry Andric static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
4551bca07a45SDimitry Andric BuiltinType::Kind ElemKind) {
4552bca07a45SDimitry Andric switch (ElemKind) {
455336981b17SDimitry Andric default: llvm_unreachable("unexpected element type");
4554bca07a45SDimitry Andric case BuiltinType::Char_U:
4555bca07a45SDimitry Andric case BuiltinType::UChar:
4556bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4557bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
4558bca07a45SDimitry Andric case BuiltinType::Char_S:
4559bca07a45SDimitry Andric case BuiltinType::SChar:
4560bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
4561bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
4562bca07a45SDimitry Andric case BuiltinType::UShort:
4563bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4564bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
4565bca07a45SDimitry Andric case BuiltinType::Short:
4566bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
4567bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
4568bca07a45SDimitry Andric case BuiltinType::UInt:
4569bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4570bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
4571bca07a45SDimitry Andric case BuiltinType::Int:
4572bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
4573bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
4574461a67faSDimitry Andric case BuiltinType::ULong:
4575461a67faSDimitry Andric case BuiltinType::ULongLong:
4576461a67faSDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4577461a67faSDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
4578461a67faSDimitry Andric case BuiltinType::Long:
4579461a67faSDimitry Andric case BuiltinType::LongLong:
4580461a67faSDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
4581461a67faSDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
4582bca07a45SDimitry Andric case BuiltinType::Float:
4583bca07a45SDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
4584bca07a45SDimitry Andric llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
4585461a67faSDimitry Andric case BuiltinType::Double:
4586461a67faSDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
4587461a67faSDimitry Andric llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4588b60736ecSDimitry Andric case BuiltinType::UInt128:
4589b60736ecSDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4590b60736ecSDimitry Andric : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4591b60736ecSDimitry Andric case BuiltinType::Int128:
4592b60736ecSDimitry Andric return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4593b60736ecSDimitry Andric : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
4594bca07a45SDimitry Andric }
4595bca07a45SDimitry Andric }
4596bca07a45SDimitry Andric
EmitCompare(const BinaryOperator * E,llvm::CmpInst::Predicate UICmpOpc,llvm::CmpInst::Predicate SICmpOpc,llvm::CmpInst::Predicate FCmpOpc,bool IsSignaling)459745b53394SDimitry Andric Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
459845b53394SDimitry Andric llvm::CmpInst::Predicate UICmpOpc,
459945b53394SDimitry Andric llvm::CmpInst::Predicate SICmpOpc,
4600706b4fc4SDimitry Andric llvm::CmpInst::Predicate FCmpOpc,
4601706b4fc4SDimitry Andric bool IsSignaling) {
4602ec2b103cSEd Schouten TestAndClearIgnoreResultAssign();
4603ec2b103cSEd Schouten Value *Result;
4604ec2b103cSEd Schouten QualType LHSTy = E->getLHS()->getType();
460506d4ba38SDimitry Andric QualType RHSTy = E->getRHS()->getType();
46063d1dcd9bSDimitry Andric if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) {
46073d1dcd9bSDimitry Andric assert(E->getOpcode() == BO_EQ ||
46083d1dcd9bSDimitry Andric E->getOpcode() == BO_NE);
46093d1dcd9bSDimitry Andric Value *LHS = CGF.EmitScalarExpr(E->getLHS());
46103d1dcd9bSDimitry Andric Value *RHS = CGF.EmitScalarExpr(E->getRHS());
46113d1dcd9bSDimitry Andric Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
46123d1dcd9bSDimitry Andric CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
461306d4ba38SDimitry Andric } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) {
461422989816SDimitry Andric BinOpInfo BOInfo = EmitBinOps(E);
461522989816SDimitry Andric Value *LHS = BOInfo.LHS;
461622989816SDimitry Andric Value *RHS = BOInfo.RHS;
4617ec2b103cSEd Schouten
4618bca07a45SDimitry Andric // If AltiVec, the comparison results in a numeric type, so we use
4619bca07a45SDimitry Andric // intrinsics comparing vectors and giving 0 or 1 as a result
462001af97d3SDimitry Andric if (LHSTy->isVectorType() && !E->getType()->isVectorType()) {
4621bca07a45SDimitry Andric // constants for mapping CR6 register bits to predicate result
4622bca07a45SDimitry Andric enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
4623bca07a45SDimitry Andric
4624bca07a45SDimitry Andric llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic;
4625bca07a45SDimitry Andric
4626bca07a45SDimitry Andric // in several cases vector arguments order will be reversed
4627bca07a45SDimitry Andric Value *FirstVecArg = LHS,
4628bca07a45SDimitry Andric *SecondVecArg = RHS;
4629bca07a45SDimitry Andric
4630519fc96cSDimitry Andric QualType ElTy = LHSTy->castAs<VectorType>()->getElementType();
4631706b4fc4SDimitry Andric BuiltinType::Kind ElementKind = ElTy->castAs<BuiltinType>()->getKind();
4632bca07a45SDimitry Andric
4633bca07a45SDimitry Andric switch(E->getOpcode()) {
463436981b17SDimitry Andric default: llvm_unreachable("is not a comparison operation");
4635bca07a45SDimitry Andric case BO_EQ:
4636bca07a45SDimitry Andric CR6 = CR6_LT;
4637bca07a45SDimitry Andric ID = GetIntrinsic(VCMPEQ, ElementKind);
4638bca07a45SDimitry Andric break;
4639bca07a45SDimitry Andric case BO_NE:
4640bca07a45SDimitry Andric CR6 = CR6_EQ;
4641bca07a45SDimitry Andric ID = GetIntrinsic(VCMPEQ, ElementKind);
4642bca07a45SDimitry Andric break;
4643bca07a45SDimitry Andric case BO_LT:
4644bca07a45SDimitry Andric CR6 = CR6_LT;
4645bca07a45SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
4646bca07a45SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
4647bca07a45SDimitry Andric break;
4648bca07a45SDimitry Andric case BO_GT:
4649bca07a45SDimitry Andric CR6 = CR6_LT;
4650bca07a45SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
4651bca07a45SDimitry Andric break;
4652bca07a45SDimitry Andric case BO_LE:
4653bca07a45SDimitry Andric if (ElementKind == BuiltinType::Float) {
4654bca07a45SDimitry Andric CR6 = CR6_LT;
4655bca07a45SDimitry Andric ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4656bca07a45SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
4657bca07a45SDimitry Andric }
4658bca07a45SDimitry Andric else {
4659bca07a45SDimitry Andric CR6 = CR6_EQ;
4660bca07a45SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
4661bca07a45SDimitry Andric }
4662bca07a45SDimitry Andric break;
4663bca07a45SDimitry Andric case BO_GE:
4664bca07a45SDimitry Andric if (ElementKind == BuiltinType::Float) {
4665bca07a45SDimitry Andric CR6 = CR6_LT;
4666bca07a45SDimitry Andric ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
4667bca07a45SDimitry Andric }
4668bca07a45SDimitry Andric else {
4669bca07a45SDimitry Andric CR6 = CR6_EQ;
4670bca07a45SDimitry Andric ID = GetIntrinsic(VCMPGT, ElementKind);
4671bca07a45SDimitry Andric std::swap(FirstVecArg, SecondVecArg);
4672bca07a45SDimitry Andric }
4673bca07a45SDimitry Andric break;
4674bca07a45SDimitry Andric }
4675bca07a45SDimitry Andric
467601af97d3SDimitry Andric Value *CR6Param = Builder.getInt32(CR6);
4677bca07a45SDimitry Andric llvm::Function *F = CGF.CGM.getIntrinsic(ID);
46785e20cdd8SDimitry Andric Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
4679461a67faSDimitry Andric
4680461a67faSDimitry Andric // The result type of intrinsic may not be same as E->getType().
4681461a67faSDimitry Andric // If E->getType() is not BoolTy, EmitScalarConversion will do the
4682461a67faSDimitry Andric // conversion work. If E->getType() is BoolTy, EmitScalarConversion will
4683461a67faSDimitry Andric // do nothing, if ResultTy is not i1 at the same time, it will cause
4684461a67faSDimitry Andric // crash later.
4685461a67faSDimitry Andric llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
4686461a67faSDimitry Andric if (ResultTy->getBitWidth() > 1 &&
4687461a67faSDimitry Andric E->getType() == CGF.getContext().BoolTy)
4688461a67faSDimitry Andric Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
468945b53394SDimitry Andric return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
469045b53394SDimitry Andric E->getExprLoc());
4691bca07a45SDimitry Andric }
4692bca07a45SDimitry Andric
4693cfca06d7SDimitry Andric if (BOInfo.isFixedPointOp()) {
469422989816SDimitry Andric Result = EmitFixedPointBinOp(BOInfo);
469522989816SDimitry Andric } else if (LHS->getType()->isFPOrFPVectorTy()) {
4696cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4697706b4fc4SDimitry Andric if (!IsSignaling)
469845b53394SDimitry Andric Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
4699706b4fc4SDimitry Andric else
4700706b4fc4SDimitry Andric Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS, "cmp");
47013d1dcd9bSDimitry Andric } else if (LHSTy->hasSignedIntegerRepresentation()) {
470245b53394SDimitry Andric Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
4703ec2b103cSEd Schouten } else {
4704ec2b103cSEd Schouten // Unsigned integers and pointers.
470548675466SDimitry Andric
470648675466SDimitry Andric if (CGF.CGM.getCodeGenOpts().StrictVTablePointers &&
470748675466SDimitry Andric !isa<llvm::ConstantPointerNull>(LHS) &&
470848675466SDimitry Andric !isa<llvm::ConstantPointerNull>(RHS)) {
470948675466SDimitry Andric
471048675466SDimitry Andric // Dynamic information is required to be stripped for comparisons,
471148675466SDimitry Andric // because it could leak the dynamic information. Based on comparisons
471248675466SDimitry Andric // of pointers to dynamic objects, the optimizer can replace one pointer
471348675466SDimitry Andric // with another, which might be incorrect in presence of invariant
471448675466SDimitry Andric // groups. Comparison with null is safe because null does not carry any
471548675466SDimitry Andric // dynamic information.
471648675466SDimitry Andric if (LHSTy.mayBeDynamicClass())
471748675466SDimitry Andric LHS = Builder.CreateStripInvariantGroup(LHS);
471848675466SDimitry Andric if (RHSTy.mayBeDynamicClass())
471948675466SDimitry Andric RHS = Builder.CreateStripInvariantGroup(RHS);
472048675466SDimitry Andric }
472148675466SDimitry Andric
472245b53394SDimitry Andric Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
4723ec2b103cSEd Schouten }
4724ec2b103cSEd Schouten
47254c8b2481SRoman Divacky // If this is a vector comparison, sign extend the result to the appropriate
47264c8b2481SRoman Divacky // vector integer type and return it (don't convert to bool).
47274c8b2481SRoman Divacky if (LHSTy->isVectorType())
47284c8b2481SRoman Divacky return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
47294c8b2481SRoman Divacky
4730ec2b103cSEd Schouten } else {
4731ec2b103cSEd Schouten // Complex Comparison: can only be an equality comparison.
473206d4ba38SDimitry Andric CodeGenFunction::ComplexPairTy LHS, RHS;
473306d4ba38SDimitry Andric QualType CETy;
473406d4ba38SDimitry Andric if (auto *CTy = LHSTy->getAs<ComplexType>()) {
473506d4ba38SDimitry Andric LHS = CGF.EmitComplexExpr(E->getLHS());
473606d4ba38SDimitry Andric CETy = CTy->getElementType();
473706d4ba38SDimitry Andric } else {
473806d4ba38SDimitry Andric LHS.first = Visit(E->getLHS());
473906d4ba38SDimitry Andric LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
474006d4ba38SDimitry Andric CETy = LHSTy;
474106d4ba38SDimitry Andric }
474206d4ba38SDimitry Andric if (auto *CTy = RHSTy->getAs<ComplexType>()) {
474306d4ba38SDimitry Andric RHS = CGF.EmitComplexExpr(E->getRHS());
474406d4ba38SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(CETy,
474506d4ba38SDimitry Andric CTy->getElementType()) &&
474606d4ba38SDimitry Andric "The element types must always match.");
474706d4ba38SDimitry Andric (void)CTy;
474806d4ba38SDimitry Andric } else {
474906d4ba38SDimitry Andric RHS.first = Visit(E->getRHS());
475006d4ba38SDimitry Andric RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
475106d4ba38SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) &&
475206d4ba38SDimitry Andric "The element types must always match.");
475306d4ba38SDimitry Andric }
4754ec2b103cSEd Schouten
4755ec2b103cSEd Schouten Value *ResultR, *ResultI;
4756ec2b103cSEd Schouten if (CETy->isRealFloatingType()) {
4757706b4fc4SDimitry Andric // As complex comparisons can only be equality comparisons, they
4758706b4fc4SDimitry Andric // are never signaling comparisons.
475945b53394SDimitry Andric ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r");
476045b53394SDimitry Andric ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i");
4761ec2b103cSEd Schouten } else {
4762ec2b103cSEd Schouten // Complex comparisons can only be equality comparisons. As such, signed
4763ec2b103cSEd Schouten // and unsigned opcodes are the same.
476445b53394SDimitry Andric ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r");
476545b53394SDimitry Andric ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i");
4766ec2b103cSEd Schouten }
4767ec2b103cSEd Schouten
47683d1dcd9bSDimitry Andric if (E->getOpcode() == BO_EQ) {
4769ec2b103cSEd Schouten Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
4770ec2b103cSEd Schouten } else {
47713d1dcd9bSDimitry Andric assert(E->getOpcode() == BO_NE &&
4772ec2b103cSEd Schouten "Complex comparison other than == or != ?");
4773ec2b103cSEd Schouten Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
4774ec2b103cSEd Schouten }
4775ec2b103cSEd Schouten }
4776ec2b103cSEd Schouten
477745b53394SDimitry Andric return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
477845b53394SDimitry Andric E->getExprLoc());
4779ec2b103cSEd Schouten }
4780ec2b103cSEd Schouten
EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator * E,Value ** Previous,QualType * SrcType)4781ac9a064cSDimitry Andric llvm::Value *CodeGenFunction::EmitWithOriginalRHSBitfieldAssignment(
4782ac9a064cSDimitry Andric const BinaryOperator *E, Value **Previous, QualType *SrcType) {
4783ac9a064cSDimitry Andric // In case we have the integer or bitfield sanitizer checks enabled
4784ac9a064cSDimitry Andric // we want to get the expression before scalar conversion.
4785ac9a064cSDimitry Andric if (auto *ICE = dyn_cast<ImplicitCastExpr>(E->getRHS())) {
4786ac9a064cSDimitry Andric CastKind Kind = ICE->getCastKind();
4787ac9a064cSDimitry Andric if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
4788ac9a064cSDimitry Andric *SrcType = ICE->getSubExpr()->getType();
4789ac9a064cSDimitry Andric *Previous = EmitScalarExpr(ICE->getSubExpr());
4790ac9a064cSDimitry Andric // Pass default ScalarConversionOpts to avoid emitting
4791ac9a064cSDimitry Andric // integer sanitizer checks as E refers to bitfield.
4792ac9a064cSDimitry Andric return EmitScalarConversion(*Previous, *SrcType, ICE->getType(),
4793ac9a064cSDimitry Andric ICE->getExprLoc());
4794ac9a064cSDimitry Andric }
4795ac9a064cSDimitry Andric }
4796ac9a064cSDimitry Andric return EmitScalarExpr(E->getRHS());
4797ac9a064cSDimitry Andric }
4798ac9a064cSDimitry Andric
VisitBinAssign(const BinaryOperator * E)4799ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
4800ec2b103cSEd Schouten bool Ignore = TestAndClearIgnoreResultAssign();
4801ec2b103cSEd Schouten
4802180abc3dSDimitry Andric Value *RHS;
4803180abc3dSDimitry Andric LValue LHS;
4804180abc3dSDimitry Andric
4805180abc3dSDimitry Andric switch (E->getLHS()->getType().getObjCLifetime()) {
4806180abc3dSDimitry Andric case Qualifiers::OCL_Strong:
48079f4dbff6SDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
4808180abc3dSDimitry Andric break;
4809180abc3dSDimitry Andric
4810180abc3dSDimitry Andric case Qualifiers::OCL_Autoreleasing:
48119f4dbff6SDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E);
4812180abc3dSDimitry Andric break;
4813180abc3dSDimitry Andric
48142b6b257fSDimitry Andric case Qualifiers::OCL_ExplicitNone:
48152b6b257fSDimitry Andric std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore);
48162b6b257fSDimitry Andric break;
48172b6b257fSDimitry Andric
4818180abc3dSDimitry Andric case Qualifiers::OCL_Weak:
4819180abc3dSDimitry Andric RHS = Visit(E->getRHS());
482013cc256eSDimitry Andric LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
4821ac9a064cSDimitry Andric RHS = CGF.EmitARCStoreWeak(LHS.getAddress(), RHS, Ignore);
4822180abc3dSDimitry Andric break;
4823180abc3dSDimitry Andric
4824180abc3dSDimitry Andric case Qualifiers::OCL_None:
4825180abc3dSDimitry Andric // __block variables need to have the rhs evaluated first, plus
4826180abc3dSDimitry Andric // this should improve codegen just a little.
4827ac9a064cSDimitry Andric Value *Previous = nullptr;
4828ac9a064cSDimitry Andric QualType SrcType = E->getRHS()->getType();
4829ac9a064cSDimitry Andric // Check if LHS is a bitfield, if RHS contains an implicit cast expression
4830ac9a064cSDimitry Andric // we want to extract that value and potentially (if the bitfield sanitizer
4831ac9a064cSDimitry Andric // is enabled) use it to check for an implicit conversion.
4832ac9a064cSDimitry Andric if (E->getLHS()->refersToBitField())
4833ac9a064cSDimitry Andric RHS = CGF.EmitWithOriginalRHSBitfieldAssignment(E, &Previous, &SrcType);
4834ac9a064cSDimitry Andric else
4835180abc3dSDimitry Andric RHS = Visit(E->getRHS());
4836ac9a064cSDimitry Andric
483713cc256eSDimitry Andric LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
4838ec2b103cSEd Schouten
4839ec2b103cSEd Schouten // Store the value into the LHS. Bit-fields are handled specially
4840ec2b103cSEd Schouten // because the result is altered by the store, i.e., [C99 6.5.16p1]
4841ec2b103cSEd Schouten // 'An assignment expression has the value of the left operand after
4842ec2b103cSEd Schouten // the assignment...'.
48437442d6faSDimitry Andric if (LHS.isBitField()) {
4844180abc3dSDimitry Andric CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
4845ac9a064cSDimitry Andric // If the expression contained an implicit conversion, make sure
4846ac9a064cSDimitry Andric // to use the value before the scalar conversion.
4847ac9a064cSDimitry Andric Value *Src = Previous ? Previous : RHS;
4848ac9a064cSDimitry Andric QualType DstType = E->getLHS()->getType();
4849ac9a064cSDimitry Andric CGF.EmitBitfieldConversionCheck(Src, SrcType, RHS, DstType,
4850ac9a064cSDimitry Andric LHS.getBitFieldInfo(), E->getExprLoc());
48517442d6faSDimitry Andric } else {
48527442d6faSDimitry Andric CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
4853180abc3dSDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
4854180abc3dSDimitry Andric }
48557442d6faSDimitry Andric }
48564ba67500SRoman Divacky
48574ba67500SRoman Divacky // If the result is clearly ignored, return now.
4858ec2b103cSEd Schouten if (Ignore)
48599f4dbff6SDimitry Andric return nullptr;
48604ba67500SRoman Divacky
4861bca07a45SDimitry Andric // The result of an assignment in C is the assigned r-value.
486213cc256eSDimitry Andric if (!CGF.getLangOpts().CPlusPlus)
48634ba67500SRoman Divacky return RHS;
48644ba67500SRoman Divacky
48654ba67500SRoman Divacky // If the lvalue is non-volatile, return the computed value of the assignment.
48664ba67500SRoman Divacky if (!LHS.isVolatileQualified())
48674ba67500SRoman Divacky return RHS;
48684ba67500SRoman Divacky
48694ba67500SRoman Divacky // Otherwise, reload the value.
4870bfef3995SDimitry Andric return EmitLoadOfLValue(LHS, E->getExprLoc());
4871ec2b103cSEd Schouten }
4872ec2b103cSEd Schouten
VisitBinLAnd(const BinaryOperator * E)4873ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
4874dbe13110SDimitry Andric // Perform vector logical and on comparisons with zero vectors.
4875dbe13110SDimitry Andric if (E->getType()->isVectorType()) {
48765e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
48779f4dbff6SDimitry Andric
4878dbe13110SDimitry Andric Value *LHS = Visit(E->getLHS());
4879dbe13110SDimitry Andric Value *RHS = Visit(E->getRHS());
4880dbe13110SDimitry Andric Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
4881809500fcSDimitry Andric if (LHS->getType()->isFPOrFPVectorTy()) {
4882cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
4883cfca06d7SDimitry Andric CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
4884809500fcSDimitry Andric LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
4885809500fcSDimitry Andric RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
4886809500fcSDimitry Andric } else {
4887dbe13110SDimitry Andric LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
4888dbe13110SDimitry Andric RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
4889809500fcSDimitry Andric }
4890dbe13110SDimitry Andric Value *And = Builder.CreateAnd(LHS, RHS);
4891809500fcSDimitry Andric return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");
4892dbe13110SDimitry Andric }
4893dbe13110SDimitry Andric
4894b60736ecSDimitry Andric bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
489536981b17SDimitry Andric llvm::Type *ResTy = ConvertType(E->getType());
489673490b89SRoman Divacky
4897ec2b103cSEd Schouten // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
4898ec2b103cSEd Schouten // If we have 1 && X, just emit X without inserting the control flow.
489901af97d3SDimitry Andric bool LHSCondVal;
490001af97d3SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
490101af97d3SDimitry Andric if (LHSCondVal) { // If we have 1 && X, just emit X.
49025e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
49039f4dbff6SDimitry Andric
4904aca2e42cSDimitry Andric // If the top of the logical operator nest, reset the MCDC temp to 0.
4905aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
4906aca2e42cSDimitry Andric CGF.maybeResetMCDCCondBitmap(E);
4907aca2e42cSDimitry Andric
4908aca2e42cSDimitry Andric CGF.MCDCLogOpStack.push_back(E);
4909aca2e42cSDimitry Andric
4910ec2b103cSEd Schouten Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4911b60736ecSDimitry Andric
4912b60736ecSDimitry Andric // If we're generating for profiling or coverage, generate a branch to a
4913b60736ecSDimitry Andric // block that increments the RHS counter needed to track branch condition
4914b60736ecSDimitry Andric // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
4915b60736ecSDimitry Andric // "FalseBlock" after the increment is done.
4916b60736ecSDimitry Andric if (InstrumentRegions &&
4917b60736ecSDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4918aca2e42cSDimitry Andric CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4919b60736ecSDimitry Andric llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end");
4920b60736ecSDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4921b60736ecSDimitry Andric Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4922b60736ecSDimitry Andric CGF.EmitBlock(RHSBlockCnt);
4923b60736ecSDimitry Andric CGF.incrementProfileCounter(E->getRHS());
4924b60736ecSDimitry Andric CGF.EmitBranch(FBlock);
4925b60736ecSDimitry Andric CGF.EmitBlock(FBlock);
4926b60736ecSDimitry Andric }
4927b60736ecSDimitry Andric
4928aca2e42cSDimitry Andric CGF.MCDCLogOpStack.pop_back();
4929aca2e42cSDimitry Andric // If the top of the logical operator nest, update the MCDC bitmap.
4930aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
4931aca2e42cSDimitry Andric CGF.maybeUpdateMCDCTestVectorBitmap(E);
4932aca2e42cSDimitry Andric
493373490b89SRoman Divacky // ZExt result to int or bool.
493473490b89SRoman Divacky return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
4935ec2b103cSEd Schouten }
4936ec2b103cSEd Schouten
493773490b89SRoman Divacky // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
4938ec2b103cSEd Schouten if (!CGF.ContainsLabel(E->getRHS()))
493973490b89SRoman Divacky return llvm::Constant::getNullValue(ResTy);
4940ec2b103cSEd Schouten }
4941ec2b103cSEd Schouten
4942aca2e42cSDimitry Andric // If the top of the logical operator nest, reset the MCDC temp to 0.
4943aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
4944aca2e42cSDimitry Andric CGF.maybeResetMCDCCondBitmap(E);
4945aca2e42cSDimitry Andric
4946aca2e42cSDimitry Andric CGF.MCDCLogOpStack.push_back(E);
4947aca2e42cSDimitry Andric
4948ec2b103cSEd Schouten llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
4949ec2b103cSEd Schouten llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs");
4950ec2b103cSEd Schouten
4951bca07a45SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
4952bca07a45SDimitry Andric
4953ec2b103cSEd Schouten // Branch on the LHS first. If it is false, go to the failure (cont) block.
49545e20cdd8SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
49555e20cdd8SDimitry Andric CGF.getProfileCount(E->getRHS()));
4956ec2b103cSEd Schouten
4957ec2b103cSEd Schouten // Any edges into the ContBlock are now from an (indeterminate number of)
4958ec2b103cSEd Schouten // edges from this first condition. All of these values will be false. Start
4959ec2b103cSEd Schouten // setting up the PHI node in the Cont Block for this.
496001af97d3SDimitry Andric llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
49614c8b2481SRoman Divacky "", ContBlock);
4962ec2b103cSEd Schouten for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
4963ec2b103cSEd Schouten PI != PE; ++PI)
49644c8b2481SRoman Divacky PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
4965ec2b103cSEd Schouten
4966bca07a45SDimitry Andric eval.begin(CGF);
4967ec2b103cSEd Schouten CGF.EmitBlock(RHSBlock);
49685e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
4969ec2b103cSEd Schouten Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4970bca07a45SDimitry Andric eval.end(CGF);
4971ec2b103cSEd Schouten
4972ec2b103cSEd Schouten // Reaquire the RHS block, as there may be subblocks inserted.
4973ec2b103cSEd Schouten RHSBlock = Builder.GetInsertBlock();
4974ec2b103cSEd Schouten
4975b60736ecSDimitry Andric // If we're generating for profiling or coverage, generate a branch on the
4976b60736ecSDimitry Andric // RHS to a block that increments the RHS true counter needed to track branch
4977b60736ecSDimitry Andric // condition coverage.
4978b60736ecSDimitry Andric if (InstrumentRegions &&
4979b60736ecSDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4980aca2e42cSDimitry Andric CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4981b60736ecSDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4982b60736ecSDimitry Andric Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4983b60736ecSDimitry Andric CGF.EmitBlock(RHSBlockCnt);
4984b60736ecSDimitry Andric CGF.incrementProfileCounter(E->getRHS());
4985b60736ecSDimitry Andric CGF.EmitBranch(ContBlock);
4986b60736ecSDimitry Andric PN->addIncoming(RHSCond, RHSBlockCnt);
4987b60736ecSDimitry Andric }
4988b60736ecSDimitry Andric
49899f4dbff6SDimitry Andric // Emit an unconditional branch from this block to ContBlock.
49909f4dbff6SDimitry Andric {
499101af97d3SDimitry Andric // There is no need to emit line number for unconditional branch.
49925e20cdd8SDimitry Andric auto NL = ApplyDebugLocation::CreateEmpty(CGF);
4993ec2b103cSEd Schouten CGF.EmitBlock(ContBlock);
49949f4dbff6SDimitry Andric }
49959f4dbff6SDimitry Andric // Insert an entry into the phi node for the edge with the value of RHSCond.
4996ec2b103cSEd Schouten PN->addIncoming(RHSCond, RHSBlock);
4997ec2b103cSEd Schouten
4998aca2e42cSDimitry Andric CGF.MCDCLogOpStack.pop_back();
4999aca2e42cSDimitry Andric // If the top of the logical operator nest, update the MCDC bitmap.
5000aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
5001aca2e42cSDimitry Andric CGF.maybeUpdateMCDCTestVectorBitmap(E);
5002aca2e42cSDimitry Andric
500348675466SDimitry Andric // Artificial location to preserve the scope information
500448675466SDimitry Andric {
500548675466SDimitry Andric auto NL = ApplyDebugLocation::CreateArtificial(CGF);
500648675466SDimitry Andric PN->setDebugLoc(Builder.getCurrentDebugLocation());
500748675466SDimitry Andric }
500848675466SDimitry Andric
5009ec2b103cSEd Schouten // ZExt result to int.
501073490b89SRoman Divacky return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");
5011ec2b103cSEd Schouten }
5012ec2b103cSEd Schouten
VisitBinLOr(const BinaryOperator * E)5013ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
5014dbe13110SDimitry Andric // Perform vector logical or on comparisons with zero vectors.
5015dbe13110SDimitry Andric if (E->getType()->isVectorType()) {
50165e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
50179f4dbff6SDimitry Andric
5018dbe13110SDimitry Andric Value *LHS = Visit(E->getLHS());
5019dbe13110SDimitry Andric Value *RHS = Visit(E->getRHS());
5020dbe13110SDimitry Andric Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
5021809500fcSDimitry Andric if (LHS->getType()->isFPOrFPVectorTy()) {
5022cfca06d7SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5023cfca06d7SDimitry Andric CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
5024809500fcSDimitry Andric LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
5025809500fcSDimitry Andric RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
5026809500fcSDimitry Andric } else {
5027dbe13110SDimitry Andric LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
5028dbe13110SDimitry Andric RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
5029809500fcSDimitry Andric }
5030dbe13110SDimitry Andric Value *Or = Builder.CreateOr(LHS, RHS);
5031809500fcSDimitry Andric return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");
5032dbe13110SDimitry Andric }
5033dbe13110SDimitry Andric
5034b60736ecSDimitry Andric bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
503536981b17SDimitry Andric llvm::Type *ResTy = ConvertType(E->getType());
503673490b89SRoman Divacky
5037ec2b103cSEd Schouten // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
5038ec2b103cSEd Schouten // If we have 0 || X, just emit X without inserting the control flow.
503901af97d3SDimitry Andric bool LHSCondVal;
504001af97d3SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
504101af97d3SDimitry Andric if (!LHSCondVal) { // If we have 0 || X, just emit X.
50425e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
50439f4dbff6SDimitry Andric
5044aca2e42cSDimitry Andric // If the top of the logical operator nest, reset the MCDC temp to 0.
5045aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
5046aca2e42cSDimitry Andric CGF.maybeResetMCDCCondBitmap(E);
5047aca2e42cSDimitry Andric
5048aca2e42cSDimitry Andric CGF.MCDCLogOpStack.push_back(E);
5049aca2e42cSDimitry Andric
5050ec2b103cSEd Schouten Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
5051b60736ecSDimitry Andric
5052b60736ecSDimitry Andric // If we're generating for profiling or coverage, generate a branch to a
5053b60736ecSDimitry Andric // block that increments the RHS counter need to track branch condition
5054b60736ecSDimitry Andric // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
5055b60736ecSDimitry Andric // "FalseBlock" after the increment is done.
5056b60736ecSDimitry Andric if (InstrumentRegions &&
5057b60736ecSDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
5058aca2e42cSDimitry Andric CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
5059b60736ecSDimitry Andric llvm::BasicBlock *FBlock = CGF.createBasicBlock("lor.end");
5060b60736ecSDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
5061b60736ecSDimitry Andric Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5062b60736ecSDimitry Andric CGF.EmitBlock(RHSBlockCnt);
5063b60736ecSDimitry Andric CGF.incrementProfileCounter(E->getRHS());
5064b60736ecSDimitry Andric CGF.EmitBranch(FBlock);
5065b60736ecSDimitry Andric CGF.EmitBlock(FBlock);
5066b60736ecSDimitry Andric }
5067b60736ecSDimitry Andric
5068aca2e42cSDimitry Andric CGF.MCDCLogOpStack.pop_back();
5069aca2e42cSDimitry Andric // If the top of the logical operator nest, update the MCDC bitmap.
5070aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
5071aca2e42cSDimitry Andric CGF.maybeUpdateMCDCTestVectorBitmap(E);
5072aca2e42cSDimitry Andric
507373490b89SRoman Divacky // ZExt result to int or bool.
507473490b89SRoman Divacky return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
5075ec2b103cSEd Schouten }
5076ec2b103cSEd Schouten
507773490b89SRoman Divacky // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.
5078ec2b103cSEd Schouten if (!CGF.ContainsLabel(E->getRHS()))
507973490b89SRoman Divacky return llvm::ConstantInt::get(ResTy, 1);
5080ec2b103cSEd Schouten }
5081ec2b103cSEd Schouten
5082aca2e42cSDimitry Andric // If the top of the logical operator nest, reset the MCDC temp to 0.
5083aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
5084aca2e42cSDimitry Andric CGF.maybeResetMCDCCondBitmap(E);
5085aca2e42cSDimitry Andric
5086aca2e42cSDimitry Andric CGF.MCDCLogOpStack.push_back(E);
5087aca2e42cSDimitry Andric
5088ec2b103cSEd Schouten llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
5089ec2b103cSEd Schouten llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
5090ec2b103cSEd Schouten
5091bca07a45SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
5092bca07a45SDimitry Andric
5093ec2b103cSEd Schouten // Branch on the LHS first. If it is true, go to the success (cont) block.
50949f4dbff6SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock,
50955e20cdd8SDimitry Andric CGF.getCurrentProfileCount() -
50965e20cdd8SDimitry Andric CGF.getProfileCount(E->getRHS()));
5097ec2b103cSEd Schouten
5098ec2b103cSEd Schouten // Any edges into the ContBlock are now from an (indeterminate number of)
5099ec2b103cSEd Schouten // edges from this first condition. All of these values will be true. Start
5100ec2b103cSEd Schouten // setting up the PHI node in the Cont Block for this.
510101af97d3SDimitry Andric llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
51024c8b2481SRoman Divacky "", ContBlock);
5103ec2b103cSEd Schouten for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5104ec2b103cSEd Schouten PI != PE; ++PI)
51054c8b2481SRoman Divacky PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5106ec2b103cSEd Schouten
5107bca07a45SDimitry Andric eval.begin(CGF);
510837f6c480SEd Schouten
5109ec2b103cSEd Schouten // Emit the RHS condition as a bool value.
5110ec2b103cSEd Schouten CGF.EmitBlock(RHSBlock);
51115e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
5112ec2b103cSEd Schouten Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
5113ec2b103cSEd Schouten
5114bca07a45SDimitry Andric eval.end(CGF);
511537f6c480SEd Schouten
5116ec2b103cSEd Schouten // Reaquire the RHS block, as there may be subblocks inserted.
5117ec2b103cSEd Schouten RHSBlock = Builder.GetInsertBlock();
5118ec2b103cSEd Schouten
5119b60736ecSDimitry Andric // If we're generating for profiling or coverage, generate a branch on the
5120b60736ecSDimitry Andric // RHS to a block that increments the RHS true counter needed to track branch
5121b60736ecSDimitry Andric // condition coverage.
5122b60736ecSDimitry Andric if (InstrumentRegions &&
5123b60736ecSDimitry Andric CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
5124aca2e42cSDimitry Andric CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
5125b60736ecSDimitry Andric llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
5126b60736ecSDimitry Andric Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5127b60736ecSDimitry Andric CGF.EmitBlock(RHSBlockCnt);
5128b60736ecSDimitry Andric CGF.incrementProfileCounter(E->getRHS());
5129b60736ecSDimitry Andric CGF.EmitBranch(ContBlock);
5130b60736ecSDimitry Andric PN->addIncoming(RHSCond, RHSBlockCnt);
5131b60736ecSDimitry Andric }
5132b60736ecSDimitry Andric
5133ec2b103cSEd Schouten // Emit an unconditional branch from this block to ContBlock. Insert an entry
5134ec2b103cSEd Schouten // into the phi node for the edge with the value of RHSCond.
5135ec2b103cSEd Schouten CGF.EmitBlock(ContBlock);
5136ec2b103cSEd Schouten PN->addIncoming(RHSCond, RHSBlock);
5137ec2b103cSEd Schouten
5138aca2e42cSDimitry Andric CGF.MCDCLogOpStack.pop_back();
5139aca2e42cSDimitry Andric // If the top of the logical operator nest, update the MCDC bitmap.
5140aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
5141aca2e42cSDimitry Andric CGF.maybeUpdateMCDCTestVectorBitmap(E);
5142aca2e42cSDimitry Andric
5143ec2b103cSEd Schouten // ZExt result to int.
514473490b89SRoman Divacky return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");
5145ec2b103cSEd Schouten }
5146ec2b103cSEd Schouten
VisitBinComma(const BinaryOperator * E)5147ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
5148bca07a45SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS());
5149ec2b103cSEd Schouten CGF.EnsureInsertPoint();
5150ec2b103cSEd Schouten return Visit(E->getRHS());
5151ec2b103cSEd Schouten }
5152ec2b103cSEd Schouten
5153ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
5154ec2b103cSEd Schouten // Other Operators
5155ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
5156ec2b103cSEd Schouten
5157ec2b103cSEd Schouten /// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
5158ec2b103cSEd Schouten /// expression is cheap enough and side-effect-free enough to evaluate
5159ec2b103cSEd Schouten /// unconditionally instead of conditionally. This is used to convert control
5160ec2b103cSEd Schouten /// flow into selects in some cases.
isCheapEnoughToEvaluateUnconditionally(const Expr * E,CodeGenFunction & CGF)516151fb8b01SRoman Divacky static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
516251fb8b01SRoman Divacky CodeGenFunction &CGF) {
516301af97d3SDimitry Andric // Anything that is an integer or floating point constant is fine.
5164bfef3995SDimitry Andric return E->IgnoreParens()->isEvaluatable(CGF.getContext());
5165ec2b103cSEd Schouten
5166bfef3995SDimitry Andric // Even non-volatile automatic variables can't be evaluated unconditionally.
5167bfef3995SDimitry Andric // Referencing a thread_local may cause non-trivial initialization work to
5168bfef3995SDimitry Andric // occur. If we're inside a lambda and one of the variables is from the scope
5169bfef3995SDimitry Andric // outside the lambda, that function may have returned already. Reading its
5170bfef3995SDimitry Andric // locals is a bad idea. Also, these reads may introduce races there didn't
5171bfef3995SDimitry Andric // exist in the source-level program.
5172ec2b103cSEd Schouten }
5173ec2b103cSEd Schouten
5174ec2b103cSEd Schouten
5175ec2b103cSEd Schouten Value *ScalarExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)5176bca07a45SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
5177ec2b103cSEd Schouten TestAndClearIgnoreResultAssign();
5178bca07a45SDimitry Andric
5179bca07a45SDimitry Andric // Bind the common expression if necessary.
5180bca07a45SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5181bca07a45SDimitry Andric
5182bca07a45SDimitry Andric Expr *condExpr = E->getCond();
5183bca07a45SDimitry Andric Expr *lhsExpr = E->getTrueExpr();
5184bca07a45SDimitry Andric Expr *rhsExpr = E->getFalseExpr();
5185bca07a45SDimitry Andric
5186ec2b103cSEd Schouten // If the condition constant folds and can be elided, try to avoid emitting
5187ec2b103cSEd Schouten // the condition and the dead arm.
518801af97d3SDimitry Andric bool CondExprBool;
518901af97d3SDimitry Andric if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
5190bca07a45SDimitry Andric Expr *live = lhsExpr, *dead = rhsExpr;
519101af97d3SDimitry Andric if (!CondExprBool) std::swap(live, dead);
5192ec2b103cSEd Schouten
5193dbe13110SDimitry Andric // If the dead side doesn't have labels we need, just emit the Live part.
5194dbe13110SDimitry Andric if (!CGF.ContainsLabel(dead)) {
5195ac9a064cSDimitry Andric if (CondExprBool) {
5196ac9a064cSDimitry Andric if (llvm::EnableSingleByteCoverage) {
5197ac9a064cSDimitry Andric CGF.incrementProfileCounter(lhsExpr);
5198ac9a064cSDimitry Andric CGF.incrementProfileCounter(rhsExpr);
5199ac9a064cSDimitry Andric }
52005e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
5201ac9a064cSDimitry Andric }
5202dbe13110SDimitry Andric Value *Result = Visit(live);
5203dbe13110SDimitry Andric
5204dbe13110SDimitry Andric // If the live part is a throw expression, it acts like it has a void
5205dbe13110SDimitry Andric // type, so evaluating it returns a null Value*. However, a conditional
5206dbe13110SDimitry Andric // with non-void type must return a non-null Value*.
5207dbe13110SDimitry Andric if (!Result && !E->getType()->isVoidType())
5208dbe13110SDimitry Andric Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
5209dbe13110SDimitry Andric
5210dbe13110SDimitry Andric return Result;
5211dbe13110SDimitry Andric }
5212ec2b103cSEd Schouten }
5213ec2b103cSEd Schouten
5214bca07a45SDimitry Andric // OpenCL: If the condition is a vector, we can treat this condition like
5215bca07a45SDimitry Andric // the select function.
5216cfca06d7SDimitry Andric if ((CGF.getLangOpts().OpenCL && condExpr->getType()->isVectorType()) ||
5217cfca06d7SDimitry Andric condExpr->getType()->isExtVectorType()) {
52185e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
52199f4dbff6SDimitry Andric
5220bca07a45SDimitry Andric llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
5221bca07a45SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
5222bca07a45SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
5223bca07a45SDimitry Andric
522436981b17SDimitry Andric llvm::Type *condType = ConvertType(condExpr->getType());
5225b60736ecSDimitry Andric auto *vecTy = cast<llvm::FixedVectorType>(condType);
5226bca07a45SDimitry Andric
5227bca07a45SDimitry Andric unsigned numElem = vecTy->getNumElements();
522836981b17SDimitry Andric llvm::Type *elemType = vecTy->getElementType();
5229bca07a45SDimitry Andric
5230dbe13110SDimitry Andric llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5231bca07a45SDimitry Andric llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5232cfca06d7SDimitry Andric llvm::Value *tmp = Builder.CreateSExt(
5233cfca06d7SDimitry Andric TestMSB, llvm::FixedVectorType::get(elemType, numElem), "sext");
5234bca07a45SDimitry Andric llvm::Value *tmp2 = Builder.CreateNot(tmp);
5235bca07a45SDimitry Andric
5236bca07a45SDimitry Andric // Cast float to int to perform ANDs if necessary.
5237bca07a45SDimitry Andric llvm::Value *RHSTmp = RHS;
5238bca07a45SDimitry Andric llvm::Value *LHSTmp = LHS;
5239bca07a45SDimitry Andric bool wasCast = false;
524036981b17SDimitry Andric llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
524156d91b49SDimitry Andric if (rhsVTy->getElementType()->isFloatingPointTy()) {
5242bca07a45SDimitry Andric RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5243bca07a45SDimitry Andric LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5244bca07a45SDimitry Andric wasCast = true;
5245bca07a45SDimitry Andric }
5246bca07a45SDimitry Andric
5247bca07a45SDimitry Andric llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5248bca07a45SDimitry Andric llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5249bca07a45SDimitry Andric llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond");
5250bca07a45SDimitry Andric if (wasCast)
5251bca07a45SDimitry Andric tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5252bca07a45SDimitry Andric
5253bca07a45SDimitry Andric return tmp5;
5254bca07a45SDimitry Andric }
5255ec2b103cSEd Schouten
5256145449b1SDimitry Andric if (condExpr->getType()->isVectorType() ||
5257b1c73532SDimitry Andric condExpr->getType()->isSveVLSBuiltinType()) {
5258706b4fc4SDimitry Andric CGF.incrementProfileCounter(E);
5259706b4fc4SDimitry Andric
5260706b4fc4SDimitry Andric llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
5261706b4fc4SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
5262706b4fc4SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
5263706b4fc4SDimitry Andric
5264706b4fc4SDimitry Andric llvm::Type *CondType = ConvertType(condExpr->getType());
5265706b4fc4SDimitry Andric auto *VecTy = cast<llvm::VectorType>(CondType);
5266706b4fc4SDimitry Andric llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5267706b4fc4SDimitry Andric
5268706b4fc4SDimitry Andric CondV = Builder.CreateICmpNE(CondV, ZeroVec, "vector_cond");
5269706b4fc4SDimitry Andric return Builder.CreateSelect(CondV, LHS, RHS, "vector_select");
5270706b4fc4SDimitry Andric }
5271706b4fc4SDimitry Andric
5272ec2b103cSEd Schouten // If this is a really simple expression (like x ? 4 : 5), emit this as a
5273ec2b103cSEd Schouten // select instead of as control flow. We can only do this if it is cheap and
5274ec2b103cSEd Schouten // safe to evaluate the LHS and RHS unconditionally.
5275bca07a45SDimitry Andric if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
5276bca07a45SDimitry Andric isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
5277bca07a45SDimitry Andric llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
52787442d6faSDimitry Andric llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
52797442d6faSDimitry Andric
5280ac9a064cSDimitry Andric if (llvm::EnableSingleByteCoverage) {
5281ac9a064cSDimitry Andric CGF.incrementProfileCounter(lhsExpr);
5282ac9a064cSDimitry Andric CGF.incrementProfileCounter(rhsExpr);
5283ac9a064cSDimitry Andric CGF.incrementProfileCounter(E);
5284ac9a064cSDimitry Andric } else
52857442d6faSDimitry Andric CGF.incrementProfileCounter(E, StepV);
52867442d6faSDimitry Andric
5287bca07a45SDimitry Andric llvm::Value *LHS = Visit(lhsExpr);
5288bca07a45SDimitry Andric llvm::Value *RHS = Visit(rhsExpr);
5289dbe13110SDimitry Andric if (!LHS) {
5290dbe13110SDimitry Andric // If the conditional has void type, make sure we return a null Value*.
5291dbe13110SDimitry Andric assert(!RHS && "LHS and RHS types must match");
52929f4dbff6SDimitry Andric return nullptr;
5293dbe13110SDimitry Andric }
5294ec2b103cSEd Schouten return Builder.CreateSelect(CondV, LHS, RHS, "cond");
5295ec2b103cSEd Schouten }
5296ec2b103cSEd Schouten
5297aca2e42cSDimitry Andric // If the top of the logical operator nest, reset the MCDC temp to 0.
5298aca2e42cSDimitry Andric if (CGF.MCDCLogOpStack.empty())
5299aca2e42cSDimitry Andric CGF.maybeResetMCDCCondBitmap(condExpr);
5300aca2e42cSDimitry Andric
5301ec2b103cSEd Schouten llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
5302ec2b103cSEd Schouten llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
5303ec2b103cSEd Schouten llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
5304ec2b103cSEd Schouten
5305bca07a45SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF);
53065e20cdd8SDimitry Andric CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock,
53075e20cdd8SDimitry Andric CGF.getProfileCount(lhsExpr));
5308ec2b103cSEd Schouten
5309ec2b103cSEd Schouten CGF.EmitBlock(LHSBlock);
53104df029ccSDimitry Andric
53114df029ccSDimitry Andric // If the top of the logical operator nest, update the MCDC bitmap for the
53124df029ccSDimitry Andric // ConditionalOperator prior to visiting its LHS and RHS blocks, since they
53134df029ccSDimitry Andric // may also contain a boolean expression.
53144df029ccSDimitry Andric if (CGF.MCDCLogOpStack.empty())
53154df029ccSDimitry Andric CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
53164df029ccSDimitry Andric
5317ac9a064cSDimitry Andric if (llvm::EnableSingleByteCoverage)
5318ac9a064cSDimitry Andric CGF.incrementProfileCounter(lhsExpr);
5319ac9a064cSDimitry Andric else
53205e20cdd8SDimitry Andric CGF.incrementProfileCounter(E);
5321ac9a064cSDimitry Andric
5322bca07a45SDimitry Andric eval.begin(CGF);
5323bca07a45SDimitry Andric Value *LHS = Visit(lhsExpr);
5324bca07a45SDimitry Andric eval.end(CGF);
5325ec2b103cSEd Schouten
5326ec2b103cSEd Schouten LHSBlock = Builder.GetInsertBlock();
5327bca07a45SDimitry Andric Builder.CreateBr(ContBlock);
5328ec2b103cSEd Schouten
5329ec2b103cSEd Schouten CGF.EmitBlock(RHSBlock);
53304df029ccSDimitry Andric
53314df029ccSDimitry Andric // If the top of the logical operator nest, update the MCDC bitmap for the
53324df029ccSDimitry Andric // ConditionalOperator prior to visiting its LHS and RHS blocks, since they
53334df029ccSDimitry Andric // may also contain a boolean expression.
53344df029ccSDimitry Andric if (CGF.MCDCLogOpStack.empty())
53354df029ccSDimitry Andric CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
53364df029ccSDimitry Andric
5337ac9a064cSDimitry Andric if (llvm::EnableSingleByteCoverage)
5338ac9a064cSDimitry Andric CGF.incrementProfileCounter(rhsExpr);
5339ac9a064cSDimitry Andric
5340bca07a45SDimitry Andric eval.begin(CGF);
5341bca07a45SDimitry Andric Value *RHS = Visit(rhsExpr);
5342bca07a45SDimitry Andric eval.end(CGF);
5343ec2b103cSEd Schouten
5344ec2b103cSEd Schouten RHSBlock = Builder.GetInsertBlock();
5345ec2b103cSEd Schouten CGF.EmitBlock(ContBlock);
5346ec2b103cSEd Schouten
534734d02d0bSRoman Divacky // If the LHS or RHS is a throw expression, it will be legitimately null.
534834d02d0bSRoman Divacky if (!LHS)
534934d02d0bSRoman Divacky return RHS;
535034d02d0bSRoman Divacky if (!RHS)
535134d02d0bSRoman Divacky return LHS;
5352ec2b103cSEd Schouten
5353ec2b103cSEd Schouten // Create a PHI node for the real part.
535401af97d3SDimitry Andric llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond");
5355ec2b103cSEd Schouten PN->addIncoming(LHS, LHSBlock);
5356ec2b103cSEd Schouten PN->addIncoming(RHS, RHSBlock);
5357aca2e42cSDimitry Andric
5358ac9a064cSDimitry Andric // When single byte coverage mode is enabled, add a counter to continuation
5359ac9a064cSDimitry Andric // block.
5360ac9a064cSDimitry Andric if (llvm::EnableSingleByteCoverage)
5361ac9a064cSDimitry Andric CGF.incrementProfileCounter(E);
5362ac9a064cSDimitry Andric
5363ec2b103cSEd Schouten return PN;
5364ec2b103cSEd Schouten }
5365ec2b103cSEd Schouten
VisitChooseExpr(ChooseExpr * E)5366ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5367bfef3995SDimitry Andric return Visit(E->getChosenSubExpr());
5368ec2b103cSEd Schouten }
5369ec2b103cSEd Schouten
VisitVAArgExpr(VAArgExpr * VE)5370ec2b103cSEd Schouten Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
53719f4dbff6SDimitry Andric QualType Ty = VE->getType();
537230d79127SDimitry Andric
53739f4dbff6SDimitry Andric if (Ty->isVariablyModifiedType())
53749f4dbff6SDimitry Andric CGF.EmitVariablyModifiedType(Ty);
53759f4dbff6SDimitry Andric
537645b53394SDimitry Andric Address ArgValue = Address::invalid();
5377ac9a064cSDimitry Andric RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);
537845b53394SDimitry Andric
5379ac9a064cSDimitry Andric return ArgPtr.getScalarVal();
5380ec2b103cSEd Schouten }
5381ec2b103cSEd Schouten
VisitBlockExpr(const BlockExpr * block)5382bca07a45SDimitry Andric Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
5383bca07a45SDimitry Andric return CGF.EmitBlockLiteral(block);
5384ec2b103cSEd Schouten }
5385ec2b103cSEd Schouten
53862b6b257fSDimitry Andric // Convert a vec3 to vec4, or vice versa.
ConvertVec3AndVec4(CGBuilderTy & Builder,CodeGenFunction & CGF,Value * Src,unsigned NumElementsDst)53872b6b257fSDimitry Andric static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF,
53882b6b257fSDimitry Andric Value *Src, unsigned NumElementsDst) {
5389cfca06d7SDimitry Andric static constexpr int Mask[] = {0, 1, 2, -1};
5390e3b55780SDimitry Andric return Builder.CreateShuffleVector(Src, llvm::ArrayRef(Mask, NumElementsDst));
53912b6b257fSDimitry Andric }
53922b6b257fSDimitry Andric
5393bab175ecSDimitry Andric // Create cast instructions for converting LLVM value \p Src to LLVM type \p
5394bab175ecSDimitry Andric // DstTy. \p Src has the same size as \p DstTy. Both are single value types
5395bab175ecSDimitry Andric // but could be scalar or vectors of different lengths, and either can be
5396bab175ecSDimitry Andric // pointer.
5397bab175ecSDimitry Andric // There are 4 cases:
5398bab175ecSDimitry Andric // 1. non-pointer -> non-pointer : needs 1 bitcast
5399bab175ecSDimitry Andric // 2. pointer -> pointer : needs 1 bitcast or addrspacecast
5400bab175ecSDimitry Andric // 3. pointer -> non-pointer
5401bab175ecSDimitry Andric // a) pointer -> intptr_t : needs 1 ptrtoint
5402bab175ecSDimitry Andric // b) pointer -> non-intptr_t : needs 1 ptrtoint then 1 bitcast
5403bab175ecSDimitry Andric // 4. non-pointer -> pointer
5404bab175ecSDimitry Andric // a) intptr_t -> pointer : needs 1 inttoptr
5405bab175ecSDimitry Andric // b) non-intptr_t -> pointer : needs 1 bitcast then 1 inttoptr
5406bab175ecSDimitry Andric // Note: for cases 3b and 4b two casts are required since LLVM casts do not
5407bab175ecSDimitry Andric // allow casting directly between pointer types and non-integer non-pointer
5408bab175ecSDimitry Andric // types.
createCastsForTypeOfSameSize(CGBuilderTy & Builder,const llvm::DataLayout & DL,Value * Src,llvm::Type * DstTy,StringRef Name="")5409bab175ecSDimitry Andric static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
5410bab175ecSDimitry Andric const llvm::DataLayout &DL,
5411bab175ecSDimitry Andric Value *Src, llvm::Type *DstTy,
5412bab175ecSDimitry Andric StringRef Name = "") {
5413bab175ecSDimitry Andric auto SrcTy = Src->getType();
5414bab175ecSDimitry Andric
5415bab175ecSDimitry Andric // Case 1.
5416bab175ecSDimitry Andric if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5417bab175ecSDimitry Andric return Builder.CreateBitCast(Src, DstTy, Name);
5418bab175ecSDimitry Andric
5419bab175ecSDimitry Andric // Case 2.
5420bab175ecSDimitry Andric if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5421bab175ecSDimitry Andric return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5422bab175ecSDimitry Andric
5423bab175ecSDimitry Andric // Case 3.
5424bab175ecSDimitry Andric if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5425bab175ecSDimitry Andric // Case 3b.
5426bab175ecSDimitry Andric if (!DstTy->isIntegerTy())
5427bab175ecSDimitry Andric Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5428bab175ecSDimitry Andric // Cases 3a and 3b.
5429bab175ecSDimitry Andric return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5430bab175ecSDimitry Andric }
5431bab175ecSDimitry Andric
5432bab175ecSDimitry Andric // Case 4b.
5433bab175ecSDimitry Andric if (!SrcTy->isIntegerTy())
5434bab175ecSDimitry Andric Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5435bab175ecSDimitry Andric // Cases 4a and 4b.
5436bab175ecSDimitry Andric return Builder.CreateIntToPtr(Src, DstTy, Name);
5437bab175ecSDimitry Andric }
5438bab175ecSDimitry Andric
VisitAsTypeExpr(AsTypeExpr * E)543929cafa66SDimitry Andric Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
544029cafa66SDimitry Andric Value *Src = CGF.EmitScalarExpr(E->getSrcExpr());
544136981b17SDimitry Andric llvm::Type *DstTy = ConvertType(E->getType());
544229cafa66SDimitry Andric
544336981b17SDimitry Andric llvm::Type *SrcTy = Src->getType();
5444b60736ecSDimitry Andric unsigned NumElementsSrc =
5445b60736ecSDimitry Andric isa<llvm::VectorType>(SrcTy)
5446b60736ecSDimitry Andric ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5447b60736ecSDimitry Andric : 0;
5448b60736ecSDimitry Andric unsigned NumElementsDst =
5449b60736ecSDimitry Andric isa<llvm::VectorType>(DstTy)
5450b60736ecSDimitry Andric ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5451b60736ecSDimitry Andric : 0;
545229cafa66SDimitry Andric
5453145449b1SDimitry Andric // Use bit vector expansion for ext_vector_type boolean vectors.
5454145449b1SDimitry Andric if (E->getType()->isExtVectorBoolType())
5455145449b1SDimitry Andric return CGF.emitBoolVecConversion(Src, NumElementsDst, "astype");
5456145449b1SDimitry Andric
54572b6b257fSDimitry Andric // Going from vec3 to non-vec3 is a special case and requires a shuffle
54582b6b257fSDimitry Andric // vector to get a vec4, then a bitcast if the target type is different.
54592b6b257fSDimitry Andric if (NumElementsSrc == 3 && NumElementsDst != 3) {
54602b6b257fSDimitry Andric Src = ConvertVec3AndVec4(Builder, CGF, Src, 4);
5461bab175ecSDimitry Andric Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
5462bab175ecSDimitry Andric DstTy);
54637442d6faSDimitry Andric
54642b6b257fSDimitry Andric Src->setName("astype");
54652b6b257fSDimitry Andric return Src;
546629cafa66SDimitry Andric }
546729cafa66SDimitry Andric
54682b6b257fSDimitry Andric // Going from non-vec3 to vec3 is a special case and requires a bitcast
54692b6b257fSDimitry Andric // to vec4 if the original type is not vec4, then a shuffle vector to
54702b6b257fSDimitry Andric // get a vec3.
54712b6b257fSDimitry Andric if (NumElementsSrc != 3 && NumElementsDst == 3) {
5472cfca06d7SDimitry Andric auto *Vec4Ty = llvm::FixedVectorType::get(
5473cfca06d7SDimitry Andric cast<llvm::VectorType>(DstTy)->getElementType(), 4);
5474bab175ecSDimitry Andric Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
5475bab175ecSDimitry Andric Vec4Ty);
54767442d6faSDimitry Andric
54772b6b257fSDimitry Andric Src = ConvertVec3AndVec4(Builder, CGF, Src, 3);
54782b6b257fSDimitry Andric Src->setName("astype");
54792b6b257fSDimitry Andric return Src;
548029cafa66SDimitry Andric }
548129cafa66SDimitry Andric
5482519fc96cSDimitry Andric return createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(),
5483bab175ecSDimitry Andric Src, DstTy, "astype");
548429cafa66SDimitry Andric }
548529cafa66SDimitry Andric
VisitAtomicExpr(AtomicExpr * E)548636981b17SDimitry Andric Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
548736981b17SDimitry Andric return CGF.EmitAtomicExpr(E).getScalarVal();
548836981b17SDimitry Andric }
548936981b17SDimitry Andric
5490ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
5491ec2b103cSEd Schouten // Entry Point into this File
5492ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
5493ec2b103cSEd Schouten
549445b53394SDimitry Andric /// Emit the computation of the specified expression of scalar type, ignoring
549545b53394SDimitry Andric /// the result.
EmitScalarExpr(const Expr * E,bool IgnoreResultAssign)5496ec2b103cSEd Schouten Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
5497809500fcSDimitry Andric assert(E && hasScalarEvaluationKind(E->getType()) &&
5498ec2b103cSEd Schouten "Invalid scalar expression to emit");
5499ec2b103cSEd Schouten
55005e20cdd8SDimitry Andric return ScalarExprEmitter(*this, IgnoreResultAssign)
5501ec2b103cSEd Schouten .Visit(const_cast<Expr *>(E));
5502ec2b103cSEd Schouten }
5503ec2b103cSEd Schouten
550445b53394SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
550545b53394SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)5506ec2b103cSEd Schouten Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
550745b53394SDimitry Andric QualType DstTy,
550845b53394SDimitry Andric SourceLocation Loc) {
5509809500fcSDimitry Andric assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
5510ec2b103cSEd Schouten "Invalid scalar expression to emit");
551145b53394SDimitry Andric return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
5512ec2b103cSEd Schouten }
5513ec2b103cSEd Schouten
551445b53394SDimitry Andric /// Emit a conversion from the specified complex type to the specified
551545b53394SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)5516ec2b103cSEd Schouten Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
5517ec2b103cSEd Schouten QualType SrcTy,
551845b53394SDimitry Andric QualType DstTy,
551945b53394SDimitry Andric SourceLocation Loc) {
5520809500fcSDimitry Andric assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) &&
5521ec2b103cSEd Schouten "Invalid complex -> scalar conversion");
552245b53394SDimitry Andric return ScalarExprEmitter(*this)
552345b53394SDimitry Andric .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
5524ec2b103cSEd Schouten }
5525ec2b103cSEd Schouten
55264ba67500SRoman Divacky
5527e3b55780SDimitry Andric Value *
EmitPromotedScalarExpr(const Expr * E,QualType PromotionType)5528e3b55780SDimitry Andric CodeGenFunction::EmitPromotedScalarExpr(const Expr *E,
5529e3b55780SDimitry Andric QualType PromotionType) {
5530e3b55780SDimitry Andric if (!PromotionType.isNull())
5531e3b55780SDimitry Andric return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5532e3b55780SDimitry Andric else
5533e3b55780SDimitry Andric return ScalarExprEmitter(*this).Visit(const_cast<Expr *>(E));
5534e3b55780SDimitry Andric }
5535e3b55780SDimitry Andric
5536e3b55780SDimitry Andric
55374ba67500SRoman Divacky llvm::Value *CodeGenFunction::
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)55384ba67500SRoman Divacky EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
55394ba67500SRoman Divacky bool isInc, bool isPre) {
55404ba67500SRoman Divacky return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
55414ba67500SRoman Divacky }
55424ba67500SRoman Divacky
EmitObjCIsaExpr(const ObjCIsaExpr * E)554334d02d0bSRoman Divacky LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
554434d02d0bSRoman Divacky // object->isa or (*object).isa
554534d02d0bSRoman Divacky // Generate code as for: *(Class*)object
5546ecb7e5c8SRoman Divacky
554734d02d0bSRoman Divacky Expr *BaseExpr = E->getBase();
554845b53394SDimitry Andric Address Addr = Address::invalid();
5549344a3780SDimitry Andric if (BaseExpr->isPRValue()) {
5550145449b1SDimitry Andric llvm::Type *BaseTy =
5551145449b1SDimitry Andric ConvertTypeForMem(BaseExpr->getType()->getPointeeType());
5552145449b1SDimitry Andric Addr = Address(EmitScalarExpr(BaseExpr), BaseTy, getPointerAlign());
55533d1dcd9bSDimitry Andric } else {
5554ac9a064cSDimitry Andric Addr = EmitLValue(BaseExpr).getAddress();
5555ecb7e5c8SRoman Divacky }
555634d02d0bSRoman Divacky
555745b53394SDimitry Andric // Cast the address to Class*.
55587fa27ce4SDimitry Andric Addr = Addr.withElementType(ConvertType(E->getType()));
555945b53394SDimitry Andric return MakeAddrLValue(Addr, E->getType());
556034d02d0bSRoman Divacky }
556134d02d0bSRoman Divacky
55620883ccd9SRoman Divacky
EmitCompoundAssignmentLValue(const CompoundAssignOperator * E)5563bca07a45SDimitry Andric LValue CodeGenFunction::EmitCompoundAssignmentLValue(
55640883ccd9SRoman Divacky const CompoundAssignOperator *E) {
55650883ccd9SRoman Divacky ScalarExprEmitter Scalar(*this);
55669f4dbff6SDimitry Andric Value *Result = nullptr;
55670883ccd9SRoman Divacky switch (E->getOpcode()) {
55680883ccd9SRoman Divacky #define COMPOUND_OP(Op) \
55693d1dcd9bSDimitry Andric case BO_##Op##Assign: \
55700883ccd9SRoman Divacky return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
55714ba67500SRoman Divacky Result)
55720883ccd9SRoman Divacky COMPOUND_OP(Mul);
55730883ccd9SRoman Divacky COMPOUND_OP(Div);
55740883ccd9SRoman Divacky COMPOUND_OP(Rem);
55750883ccd9SRoman Divacky COMPOUND_OP(Add);
55760883ccd9SRoman Divacky COMPOUND_OP(Sub);
55770883ccd9SRoman Divacky COMPOUND_OP(Shl);
55780883ccd9SRoman Divacky COMPOUND_OP(Shr);
55790883ccd9SRoman Divacky COMPOUND_OP(And);
55800883ccd9SRoman Divacky COMPOUND_OP(Xor);
55810883ccd9SRoman Divacky COMPOUND_OP(Or);
55820883ccd9SRoman Divacky #undef COMPOUND_OP
55830883ccd9SRoman Divacky
55843d1dcd9bSDimitry Andric case BO_PtrMemD:
55853d1dcd9bSDimitry Andric case BO_PtrMemI:
55863d1dcd9bSDimitry Andric case BO_Mul:
55873d1dcd9bSDimitry Andric case BO_Div:
55883d1dcd9bSDimitry Andric case BO_Rem:
55893d1dcd9bSDimitry Andric case BO_Add:
55903d1dcd9bSDimitry Andric case BO_Sub:
55913d1dcd9bSDimitry Andric case BO_Shl:
55923d1dcd9bSDimitry Andric case BO_Shr:
55933d1dcd9bSDimitry Andric case BO_LT:
55943d1dcd9bSDimitry Andric case BO_GT:
55953d1dcd9bSDimitry Andric case BO_LE:
55963d1dcd9bSDimitry Andric case BO_GE:
55973d1dcd9bSDimitry Andric case BO_EQ:
55983d1dcd9bSDimitry Andric case BO_NE:
5599461a67faSDimitry Andric case BO_Cmp:
56003d1dcd9bSDimitry Andric case BO_And:
56013d1dcd9bSDimitry Andric case BO_Xor:
56023d1dcd9bSDimitry Andric case BO_Or:
56033d1dcd9bSDimitry Andric case BO_LAnd:
56043d1dcd9bSDimitry Andric case BO_LOr:
56053d1dcd9bSDimitry Andric case BO_Assign:
56063d1dcd9bSDimitry Andric case BO_Comma:
560736981b17SDimitry Andric llvm_unreachable("Not valid compound assignment operators");
56080883ccd9SRoman Divacky }
56090883ccd9SRoman Divacky
56100883ccd9SRoman Divacky llvm_unreachable("Unhandled compound assignment operator");
56110883ccd9SRoman Divacky }
5612416ada0fSDimitry Andric
5613519fc96cSDimitry Andric struct GEPOffsetAndOverflow {
5614519fc96cSDimitry Andric // The total (signed) byte offset for the GEP.
5615519fc96cSDimitry Andric llvm::Value *TotalOffset;
5616519fc96cSDimitry Andric // The offset overflow flag - true if the total offset overflows.
5617519fc96cSDimitry Andric llvm::Value *OffsetOverflows;
5618519fc96cSDimitry Andric };
5619416ada0fSDimitry Andric
5620519fc96cSDimitry Andric /// Evaluate given GEPVal, which is either an inbounds GEP, or a constant,
5621519fc96cSDimitry Andric /// and compute the total offset it applies from it's base pointer BasePtr.
5622519fc96cSDimitry Andric /// Returns offset in bytes and a boolean flag whether an overflow happened
5623519fc96cSDimitry Andric /// during evaluation.
EmitGEPOffsetInBytes(Value * BasePtr,Value * GEPVal,llvm::LLVMContext & VMContext,CodeGenModule & CGM,CGBuilderTy & Builder)5624519fc96cSDimitry Andric static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal,
5625519fc96cSDimitry Andric llvm::LLVMContext &VMContext,
5626519fc96cSDimitry Andric CodeGenModule &CGM,
5627cfca06d7SDimitry Andric CGBuilderTy &Builder) {
5628519fc96cSDimitry Andric const auto &DL = CGM.getDataLayout();
5629416ada0fSDimitry Andric
5630519fc96cSDimitry Andric // The total (signed) byte offset for the GEP.
5631519fc96cSDimitry Andric llvm::Value *TotalOffset = nullptr;
5632416ada0fSDimitry Andric
5633519fc96cSDimitry Andric // Was the GEP already reduced to a constant?
5634519fc96cSDimitry Andric if (isa<llvm::Constant>(GEPVal)) {
5635519fc96cSDimitry Andric // Compute the offset by casting both pointers to integers and subtracting:
5636519fc96cSDimitry Andric // GEPVal = BasePtr + ptr(Offset) <--> Offset = int(GEPVal) - int(BasePtr)
5637519fc96cSDimitry Andric Value *BasePtr_int =
5638519fc96cSDimitry Andric Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType()));
5639519fc96cSDimitry Andric Value *GEPVal_int =
5640519fc96cSDimitry Andric Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType()));
5641519fc96cSDimitry Andric TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5642519fc96cSDimitry Andric return {TotalOffset, /*OffsetOverflows=*/Builder.getFalse()};
5643519fc96cSDimitry Andric }
5644416ada0fSDimitry Andric
5645416ada0fSDimitry Andric auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5646519fc96cSDimitry Andric assert(GEP->getPointerOperand() == BasePtr &&
5647c0981da4SDimitry Andric "BasePtr must be the base of the GEP.");
5648416ada0fSDimitry Andric assert(GEP->isInBounds() && "Expected inbounds GEP");
5649416ada0fSDimitry Andric
5650416ada0fSDimitry Andric auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
5651416ada0fSDimitry Andric
5652416ada0fSDimitry Andric // Grab references to the signed add/mul overflow intrinsics for intptr_t.
5653416ada0fSDimitry Andric auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5654416ada0fSDimitry Andric auto *SAddIntrinsic =
5655416ada0fSDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
5656416ada0fSDimitry Andric auto *SMulIntrinsic =
5657416ada0fSDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
5658416ada0fSDimitry Andric
5659416ada0fSDimitry Andric // The offset overflow flag - true if the total offset overflows.
5660416ada0fSDimitry Andric llvm::Value *OffsetOverflows = Builder.getFalse();
5661416ada0fSDimitry Andric
5662416ada0fSDimitry Andric /// Return the result of the given binary operation.
5663416ada0fSDimitry Andric auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
5664416ada0fSDimitry Andric llvm::Value *RHS) -> llvm::Value * {
5665551c6985SDimitry Andric assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop");
5666416ada0fSDimitry Andric
5667416ada0fSDimitry Andric // If the operands are constants, return a constant result.
5668416ada0fSDimitry Andric if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
5669416ada0fSDimitry Andric if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
5670416ada0fSDimitry Andric llvm::APInt N;
5671416ada0fSDimitry Andric bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
5672416ada0fSDimitry Andric /*Signed=*/true, N);
5673416ada0fSDimitry Andric if (HasOverflow)
5674416ada0fSDimitry Andric OffsetOverflows = Builder.getTrue();
5675416ada0fSDimitry Andric return llvm::ConstantInt::get(VMContext, N);
5676416ada0fSDimitry Andric }
5677416ada0fSDimitry Andric }
5678416ada0fSDimitry Andric
5679416ada0fSDimitry Andric // Otherwise, compute the result with checked arithmetic.
5680416ada0fSDimitry Andric auto *ResultAndOverflow = Builder.CreateCall(
5681416ada0fSDimitry Andric (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
5682416ada0fSDimitry Andric OffsetOverflows = Builder.CreateOr(
5683325377b5SDimitry Andric Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
5684416ada0fSDimitry Andric return Builder.CreateExtractValue(ResultAndOverflow, 0);
5685416ada0fSDimitry Andric };
5686416ada0fSDimitry Andric
5687416ada0fSDimitry Andric // Determine the total byte offset by looking at each GEP operand.
5688416ada0fSDimitry Andric for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
5689416ada0fSDimitry Andric GTI != GTE; ++GTI) {
5690416ada0fSDimitry Andric llvm::Value *LocalOffset;
5691416ada0fSDimitry Andric auto *Index = GTI.getOperand();
5692416ada0fSDimitry Andric // Compute the local offset contributed by this indexing step:
5693416ada0fSDimitry Andric if (auto *STy = GTI.getStructTypeOrNull()) {
5694416ada0fSDimitry Andric // For struct indexing, the local offset is the byte position of the
5695416ada0fSDimitry Andric // specified field.
5696416ada0fSDimitry Andric unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
5697416ada0fSDimitry Andric LocalOffset = llvm::ConstantInt::get(
5698416ada0fSDimitry Andric IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
5699416ada0fSDimitry Andric } else {
5700416ada0fSDimitry Andric // Otherwise this is array-like indexing. The local offset is the index
5701416ada0fSDimitry Andric // multiplied by the element size.
5702aca2e42cSDimitry Andric auto *ElementSize =
5703aca2e42cSDimitry Andric llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
5704416ada0fSDimitry Andric auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
5705416ada0fSDimitry Andric LocalOffset = eval(BO_Mul, ElementSize, IndexS);
5706416ada0fSDimitry Andric }
5707416ada0fSDimitry Andric
5708416ada0fSDimitry Andric // If this is the first offset, set it as the total offset. Otherwise, add
5709416ada0fSDimitry Andric // the local offset into the running total.
5710416ada0fSDimitry Andric if (!TotalOffset || TotalOffset == Zero)
5711416ada0fSDimitry Andric TotalOffset = LocalOffset;
5712416ada0fSDimitry Andric else
5713416ada0fSDimitry Andric TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
5714416ada0fSDimitry Andric }
5715416ada0fSDimitry Andric
5716519fc96cSDimitry Andric return {TotalOffset, OffsetOverflows};
5717519fc96cSDimitry Andric }
5718519fc96cSDimitry Andric
5719519fc96cSDimitry Andric Value *
EmitCheckedInBoundsGEP(llvm::Type * ElemTy,Value * Ptr,ArrayRef<Value * > IdxList,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,const Twine & Name)572077fc4c14SDimitry Andric CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
572177fc4c14SDimitry Andric ArrayRef<Value *> IdxList,
5722519fc96cSDimitry Andric bool SignedIndices, bool IsSubtraction,
5723519fc96cSDimitry Andric SourceLocation Loc, const Twine &Name) {
5724344a3780SDimitry Andric llvm::Type *PtrTy = Ptr->getType();
572577fc4c14SDimitry Andric Value *GEPVal = Builder.CreateInBoundsGEP(ElemTy, Ptr, IdxList, Name);
5726519fc96cSDimitry Andric
5727519fc96cSDimitry Andric // If the pointer overflow sanitizer isn't enabled, do nothing.
5728519fc96cSDimitry Andric if (!SanOpts.has(SanitizerKind::PointerOverflow))
5729519fc96cSDimitry Andric return GEPVal;
5730519fc96cSDimitry Andric
5731519fc96cSDimitry Andric // Perform nullptr-and-offset check unless the nullptr is defined.
5732519fc96cSDimitry Andric bool PerformNullCheck = !NullPointerIsDefined(
5733519fc96cSDimitry Andric Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5734519fc96cSDimitry Andric // Check for overflows unless the GEP got constant-folded,
5735519fc96cSDimitry Andric // and only in the default address space
5736519fc96cSDimitry Andric bool PerformOverflowCheck =
5737519fc96cSDimitry Andric !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5738519fc96cSDimitry Andric
5739519fc96cSDimitry Andric if (!(PerformNullCheck || PerformOverflowCheck))
5740519fc96cSDimitry Andric return GEPVal;
5741519fc96cSDimitry Andric
5742519fc96cSDimitry Andric const auto &DL = CGM.getDataLayout();
5743519fc96cSDimitry Andric
5744519fc96cSDimitry Andric SanitizerScope SanScope(this);
5745519fc96cSDimitry Andric llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
5746519fc96cSDimitry Andric
5747519fc96cSDimitry Andric GEPOffsetAndOverflow EvaluatedGEP =
5748519fc96cSDimitry Andric EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder);
5749519fc96cSDimitry Andric
5750519fc96cSDimitry Andric assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
5751519fc96cSDimitry Andric EvaluatedGEP.OffsetOverflows == Builder.getFalse()) &&
5752519fc96cSDimitry Andric "If the offset got constant-folded, we don't expect that there was an "
5753519fc96cSDimitry Andric "overflow.");
5754519fc96cSDimitry Andric
5755519fc96cSDimitry Andric auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5756519fc96cSDimitry Andric
5757519fc96cSDimitry Andric // Common case: if the total offset is zero, and we are using C++ semantics,
5758519fc96cSDimitry Andric // where nullptr+0 is defined, don't emit a check.
5759519fc96cSDimitry Andric if (EvaluatedGEP.TotalOffset == Zero && CGM.getLangOpts().CPlusPlus)
5760416ada0fSDimitry Andric return GEPVal;
5761416ada0fSDimitry Andric
5762416ada0fSDimitry Andric // Now that we've computed the total offset, add it to the base pointer (with
5763416ada0fSDimitry Andric // wrapping semantics).
5764519fc96cSDimitry Andric auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
5765519fc96cSDimitry Andric auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset);
5766416ada0fSDimitry Andric
5767519fc96cSDimitry Andric llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
5768519fc96cSDimitry Andric
5769519fc96cSDimitry Andric if (PerformNullCheck) {
5770519fc96cSDimitry Andric // In C++, if the base pointer evaluates to a null pointer value,
5771519fc96cSDimitry Andric // the only valid pointer this inbounds GEP can produce is also
5772519fc96cSDimitry Andric // a null pointer, so the offset must also evaluate to zero.
5773519fc96cSDimitry Andric // Likewise, if we have non-zero base pointer, we can not get null pointer
5774519fc96cSDimitry Andric // as a result, so the offset can not be -intptr_t(BasePtr).
5775519fc96cSDimitry Andric // In other words, both pointers are either null, or both are non-null,
5776519fc96cSDimitry Andric // or the behaviour is undefined.
5777519fc96cSDimitry Andric //
5778519fc96cSDimitry Andric // C, however, is more strict in this regard, and gives more
5779519fc96cSDimitry Andric // optimization opportunities: in C, additionally, nullptr+0 is undefined.
5780519fc96cSDimitry Andric // So both the input to the 'gep inbounds' AND the output must not be null.
5781519fc96cSDimitry Andric auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
5782519fc96cSDimitry Andric auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
5783519fc96cSDimitry Andric auto *Valid =
5784519fc96cSDimitry Andric CGM.getLangOpts().CPlusPlus
5785519fc96cSDimitry Andric ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5786519fc96cSDimitry Andric : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5787519fc96cSDimitry Andric Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5788519fc96cSDimitry Andric }
5789519fc96cSDimitry Andric
5790519fc96cSDimitry Andric if (PerformOverflowCheck) {
5791416ada0fSDimitry Andric // The GEP is valid if:
5792416ada0fSDimitry Andric // 1) The total offset doesn't overflow, and
5793416ada0fSDimitry Andric // 2) The sign of the difference between the computed address and the base
5794416ada0fSDimitry Andric // pointer matches the sign of the total offset.
5795325377b5SDimitry Andric llvm::Value *ValidGEP;
5796519fc96cSDimitry Andric auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.OffsetOverflows);
5797325377b5SDimitry Andric if (SignedIndices) {
5798519fc96cSDimitry Andric // GEP is computed as `unsigned base + signed offset`, therefore:
5799519fc96cSDimitry Andric // * If offset was positive, then the computed pointer can not be
5800519fc96cSDimitry Andric // [unsigned] less than the base pointer, unless it overflowed.
5801519fc96cSDimitry Andric // * If offset was negative, then the computed pointer can not be
5802519fc96cSDimitry Andric // [unsigned] greater than the bas pointere, unless it overflowed.
5803de51d671SDimitry Andric auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5804519fc96cSDimitry Andric auto *PosOrZeroOffset =
5805519fc96cSDimitry Andric Builder.CreateICmpSGE(EvaluatedGEP.TotalOffset, Zero);
5806325377b5SDimitry Andric llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
5807519fc96cSDimitry Andric ValidGEP =
5808519fc96cSDimitry Andric Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5809519fc96cSDimitry Andric } else if (!IsSubtraction) {
5810519fc96cSDimitry Andric // GEP is computed as `unsigned base + unsigned offset`, therefore the
5811519fc96cSDimitry Andric // computed pointer can not be [unsigned] less than base pointer,
5812519fc96cSDimitry Andric // unless there was an overflow.
5813519fc96cSDimitry Andric // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`.
5814519fc96cSDimitry Andric ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5815de51d671SDimitry Andric } else {
5816519fc96cSDimitry Andric // GEP is computed as `unsigned base - unsigned offset`, therefore the
5817519fc96cSDimitry Andric // computed pointer can not be [unsigned] greater than base pointer,
5818519fc96cSDimitry Andric // unless there was an overflow.
5819519fc96cSDimitry Andric // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`.
5820519fc96cSDimitry Andric ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
5821325377b5SDimitry Andric }
5822519fc96cSDimitry Andric ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5823519fc96cSDimitry Andric Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5824519fc96cSDimitry Andric }
5825519fc96cSDimitry Andric
5826519fc96cSDimitry Andric assert(!Checks.empty() && "Should have produced some checks.");
5827416ada0fSDimitry Andric
5828416ada0fSDimitry Andric llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
5829416ada0fSDimitry Andric // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
5830416ada0fSDimitry Andric llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5831519fc96cSDimitry Andric EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
5832416ada0fSDimitry Andric
5833416ada0fSDimitry Andric return GEPVal;
5834416ada0fSDimitry Andric }
5835ac9a064cSDimitry Andric
EmitCheckedInBoundsGEP(Address Addr,ArrayRef<Value * > IdxList,llvm::Type * elementType,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,CharUnits Align,const Twine & Name)5836ac9a064cSDimitry Andric Address CodeGenFunction::EmitCheckedInBoundsGEP(
5837ac9a064cSDimitry Andric Address Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
5838ac9a064cSDimitry Andric bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align,
5839ac9a064cSDimitry Andric const Twine &Name) {
5840ac9a064cSDimitry Andric if (!SanOpts.has(SanitizerKind::PointerOverflow))
5841ac9a064cSDimitry Andric return Builder.CreateInBoundsGEP(Addr, IdxList, elementType, Align, Name);
5842ac9a064cSDimitry Andric
5843ac9a064cSDimitry Andric return RawAddress(
5844ac9a064cSDimitry Andric EmitCheckedInBoundsGEP(Addr.getElementType(), Addr.emitRawPointer(*this),
5845ac9a064cSDimitry Andric IdxList, SignedIndices, IsSubtraction, Loc, Name),
5846ac9a064cSDimitry Andric elementType, Align);
5847ac9a064cSDimitry Andric }
5848