xref: /src/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp (revision 6e516c87b6d779911edde7481d8aef165b837a03)
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