10b57cec5SDimitry Andric //===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CGCXXABI.h"
140b57cec5SDimitry Andric #include "CGCleanup.h"
150b57cec5SDimitry Andric #include "CGDebugInfo.h"
160b57cec5SDimitry Andric #include "CGObjCRuntime.h"
17480093f4SDimitry Andric #include "CGOpenMPRuntime.h"
180b57cec5SDimitry Andric #include "CodeGenFunction.h"
190b57cec5SDimitry Andric #include "CodeGenModule.h"
200b57cec5SDimitry Andric #include "ConstantEmitter.h"
210b57cec5SDimitry Andric #include "TargetInfo.h"
220b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
23480093f4SDimitry Andric #include "clang/AST/Attr.h"
240b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
250b57cec5SDimitry Andric #include "clang/AST/Expr.h"
260b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
270b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
280b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
290b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
30e8d8bef9SDimitry Andric #include "llvm/ADT/APFixedPoint.h"
310b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
320b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
330b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
3481ad6265SDimitry Andric #include "llvm/IR/DerivedTypes.h"
35e8d8bef9SDimitry Andric #include "llvm/IR/FixedPointBuilder.h"
360b57cec5SDimitry Andric #include "llvm/IR/Function.h"
370b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
380b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
390b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
40480093f4SDimitry Andric #include "llvm/IR/IntrinsicsPowerPC.h"
415ffd83dbSDimitry Andric #include "llvm/IR/MatrixBuilder.h"
420b57cec5SDimitry Andric #include "llvm/IR/Module.h"
4381ad6265SDimitry Andric #include "llvm/Support/TypeSize.h"
440b57cec5SDimitry Andric #include <cstdarg>
45bdd1243dSDimitry Andric #include <optional>
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric using namespace clang;
480b57cec5SDimitry Andric using namespace CodeGen;
490b57cec5SDimitry Andric using llvm::Value;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
520b57cec5SDimitry Andric //                         Scalar Expression Emitter
530b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric namespace {
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric /// Determine whether the given binary operation may overflow.
580b57cec5SDimitry Andric /// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
590b57cec5SDimitry Andric /// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
600b57cec5SDimitry Andric /// the returned overflow check is precise. The returned value is 'true' for
610b57cec5SDimitry Andric /// all other opcodes, to be conservative.
mayHaveIntegerOverflow(llvm::ConstantInt * LHS,llvm::ConstantInt * RHS,BinaryOperator::Opcode Opcode,bool Signed,llvm::APInt & Result)620b57cec5SDimitry Andric bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
630b57cec5SDimitry Andric                              BinaryOperator::Opcode Opcode, bool Signed,
640b57cec5SDimitry Andric                              llvm::APInt &Result) {
650b57cec5SDimitry Andric   // Assume overflow is possible, unless we can prove otherwise.
660b57cec5SDimitry Andric   bool Overflow = true;
670b57cec5SDimitry Andric   const auto &LHSAP = LHS->getValue();
680b57cec5SDimitry Andric   const auto &RHSAP = RHS->getValue();
690b57cec5SDimitry Andric   if (Opcode == BO_Add) {
7081ad6265SDimitry Andric     Result = Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
7181ad6265SDimitry Andric                     : LHSAP.uadd_ov(RHSAP, Overflow);
720b57cec5SDimitry Andric   } else if (Opcode == BO_Sub) {
7381ad6265SDimitry Andric     Result = Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
7481ad6265SDimitry Andric                     : LHSAP.usub_ov(RHSAP, Overflow);
750b57cec5SDimitry Andric   } else if (Opcode == BO_Mul) {
7681ad6265SDimitry Andric     Result = Signed ? LHSAP.smul_ov(RHSAP, Overflow)
7781ad6265SDimitry Andric                     : LHSAP.umul_ov(RHSAP, Overflow);
780b57cec5SDimitry Andric   } else if (Opcode == BO_Div || Opcode == BO_Rem) {
790b57cec5SDimitry Andric     if (Signed && !RHS->isZero())
800b57cec5SDimitry Andric       Result = LHSAP.sdiv_ov(RHSAP, Overflow);
810b57cec5SDimitry Andric     else
820b57cec5SDimitry Andric       return false;
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric   return Overflow;
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric struct BinOpInfo {
880b57cec5SDimitry Andric   Value *LHS;
890b57cec5SDimitry Andric   Value *RHS;
900b57cec5SDimitry Andric   QualType Ty;  // Computation Type.
910b57cec5SDimitry Andric   BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
920b57cec5SDimitry Andric   FPOptions FPFeatures;
930b57cec5SDimitry Andric   const Expr *E;      // Entire expr, for error unsupported.  May not be binop.
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   /// Check if the binop can result in integer overflow.
mayHaveIntegerOverflow__anondf337c330111::BinOpInfo960b57cec5SDimitry Andric   bool mayHaveIntegerOverflow() const {
970b57cec5SDimitry Andric     // Without constant input, we can't rule out overflow.
980b57cec5SDimitry Andric     auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
990b57cec5SDimitry Andric     auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
1000b57cec5SDimitry Andric     if (!LHSCI || !RHSCI)
1010b57cec5SDimitry Andric       return true;
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric     llvm::APInt Result;
1040b57cec5SDimitry Andric     return ::mayHaveIntegerOverflow(
1050b57cec5SDimitry Andric         LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result);
1060b57cec5SDimitry Andric   }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   /// Check if the binop computes a division or a remainder.
isDivremOp__anondf337c330111::BinOpInfo1090b57cec5SDimitry Andric   bool isDivremOp() const {
1100b57cec5SDimitry Andric     return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
1110b57cec5SDimitry Andric            Opcode == BO_RemAssign;
1120b57cec5SDimitry Andric   }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   /// Check if the binop can result in an integer division by zero.
mayHaveIntegerDivisionByZero__anondf337c330111::BinOpInfo1150b57cec5SDimitry Andric   bool mayHaveIntegerDivisionByZero() const {
1160b57cec5SDimitry Andric     if (isDivremOp())
1170b57cec5SDimitry Andric       if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
1180b57cec5SDimitry Andric         return CI->isZero();
1190b57cec5SDimitry Andric     return true;
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   /// Check if the binop can result in a float division by zero.
mayHaveFloatDivisionByZero__anondf337c330111::BinOpInfo1230b57cec5SDimitry Andric   bool mayHaveFloatDivisionByZero() const {
1240b57cec5SDimitry Andric     if (isDivremOp())
1250b57cec5SDimitry Andric       if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
1260b57cec5SDimitry Andric         return CFP->isZero();
1270b57cec5SDimitry Andric     return true;
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric 
1305ffd83dbSDimitry Andric   /// Check if at least one operand is a fixed point type. In such cases, this
1315ffd83dbSDimitry Andric   /// operation did not follow usual arithmetic conversion and both operands
1325ffd83dbSDimitry Andric   /// might not be of the same type.
isFixedPointOp__anondf337c330111::BinOpInfo1335ffd83dbSDimitry Andric   bool isFixedPointOp() const {
1340b57cec5SDimitry Andric     // We cannot simply check the result type since comparison operations return
1350b57cec5SDimitry Andric     // an int.
1360b57cec5SDimitry Andric     if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
1370b57cec5SDimitry Andric       QualType LHSType = BinOp->getLHS()->getType();
1380b57cec5SDimitry Andric       QualType RHSType = BinOp->getRHS()->getType();
1390b57cec5SDimitry Andric       return LHSType->isFixedPointType() || RHSType->isFixedPointType();
1400b57cec5SDimitry Andric     }
1415ffd83dbSDimitry Andric     if (const auto *UnOp = dyn_cast<UnaryOperator>(E))
1425ffd83dbSDimitry Andric       return UnOp->getSubExpr()->getType()->isFixedPointType();
1430b57cec5SDimitry Andric     return false;
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric };
1460b57cec5SDimitry Andric 
MustVisitNullValue(const Expr * E)1470b57cec5SDimitry Andric static bool MustVisitNullValue(const Expr *E) {
1480b57cec5SDimitry Andric   // If a null pointer expression's type is the C++0x nullptr_t, then
1490b57cec5SDimitry Andric   // it's not necessarily a simple constant and it must be evaluated
1500b57cec5SDimitry Andric   // for its potential side effects.
1510b57cec5SDimitry Andric   return E->getType()->isNullPtrType();
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric /// If \p E is a widened promoted integer, get its base (unpromoted) type.
getUnwidenedIntegerType(const ASTContext & Ctx,const Expr * E)155bdd1243dSDimitry Andric static std::optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
1560b57cec5SDimitry Andric                                                        const Expr *E) {
1570b57cec5SDimitry Andric   const Expr *Base = E->IgnoreImpCasts();
1580b57cec5SDimitry Andric   if (E == Base)
159bdd1243dSDimitry Andric     return std::nullopt;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   QualType BaseTy = Base->getType();
162bdd1243dSDimitry Andric   if (!Ctx.isPromotableIntegerType(BaseTy) ||
1630b57cec5SDimitry Andric       Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
164bdd1243dSDimitry Andric     return std::nullopt;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   return BaseTy;
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric /// Check if \p E is a widened promoted integer.
IsWidenedIntegerOp(const ASTContext & Ctx,const Expr * E)1700b57cec5SDimitry Andric static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
17181ad6265SDimitry Andric   return getUnwidenedIntegerType(Ctx, E).has_value();
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric /// Check if we can skip the overflow check for \p Op.
CanElideOverflowCheck(const ASTContext & Ctx,const BinOpInfo & Op)1750b57cec5SDimitry Andric static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
1760b57cec5SDimitry Andric   assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
1770b57cec5SDimitry Andric          "Expected a unary or binary operator");
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   // If the binop has constant inputs and we can prove there is no overflow,
1800b57cec5SDimitry Andric   // we can elide the overflow check.
1810b57cec5SDimitry Andric   if (!Op.mayHaveIntegerOverflow())
1820b57cec5SDimitry Andric     return true;
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   // If a unary op has a widened operand, the op cannot overflow.
1850b57cec5SDimitry Andric   if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
1860b57cec5SDimitry Andric     return !UO->canOverflow();
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   // We usually don't need overflow checks for binops with widened operands.
1890b57cec5SDimitry Andric   // Multiplication with promoted unsigned operands is a special case.
1900b57cec5SDimitry Andric   const auto *BO = cast<BinaryOperator>(Op.E);
1910b57cec5SDimitry Andric   auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
1920b57cec5SDimitry Andric   if (!OptionalLHSTy)
1930b57cec5SDimitry Andric     return false;
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
1960b57cec5SDimitry Andric   if (!OptionalRHSTy)
1970b57cec5SDimitry Andric     return false;
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   QualType LHSTy = *OptionalLHSTy;
2000b57cec5SDimitry Andric   QualType RHSTy = *OptionalRHSTy;
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   // This is the simple case: binops without unsigned multiplication, and with
2030b57cec5SDimitry Andric   // widened operands. No overflow check is needed here.
2040b57cec5SDimitry Andric   if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
2050b57cec5SDimitry Andric       !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
2060b57cec5SDimitry Andric     return true;
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   // For unsigned multiplication the overflow check can be elided if either one
2090b57cec5SDimitry Andric   // of the unpromoted types are less than half the size of the promoted type.
2100b57cec5SDimitry Andric   unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
2110b57cec5SDimitry Andric   return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
2120b57cec5SDimitry Andric          (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric class ScalarExprEmitter
2160b57cec5SDimitry Andric   : public StmtVisitor<ScalarExprEmitter, Value*> {
2170b57cec5SDimitry Andric   CodeGenFunction &CGF;
2180b57cec5SDimitry Andric   CGBuilderTy &Builder;
2190b57cec5SDimitry Andric   bool IgnoreResultAssign;
2200b57cec5SDimitry Andric   llvm::LLVMContext &VMContext;
2210b57cec5SDimitry Andric public:
2220b57cec5SDimitry Andric 
ScalarExprEmitter(CodeGenFunction & cgf,bool ira=false)2230b57cec5SDimitry Andric   ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false)
2240b57cec5SDimitry Andric     : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
2250b57cec5SDimitry Andric       VMContext(cgf.getLLVMContext()) {
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
2290b57cec5SDimitry Andric   //                               Utilities
2300b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
2310b57cec5SDimitry Andric 
TestAndClearIgnoreResultAssign()2320b57cec5SDimitry Andric   bool TestAndClearIgnoreResultAssign() {
2330b57cec5SDimitry Andric     bool I = IgnoreResultAssign;
2340b57cec5SDimitry Andric     IgnoreResultAssign = false;
2350b57cec5SDimitry Andric     return I;
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric 
ConvertType(QualType T)2380b57cec5SDimitry Andric   llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
EmitLValue(const Expr * E)2390b57cec5SDimitry Andric   LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
EmitCheckedLValue(const Expr * E,CodeGenFunction::TypeCheckKind TCK)2400b57cec5SDimitry Andric   LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
2410b57cec5SDimitry Andric     return CGF.EmitCheckedLValue(E, TCK);
2420b57cec5SDimitry Andric   }
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
2450b57cec5SDimitry Andric                       const BinOpInfo &Info);
2460b57cec5SDimitry Andric 
EmitLoadOfLValue(LValue LV,SourceLocation Loc)2470b57cec5SDimitry Andric   Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
2480b57cec5SDimitry Andric     return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
2490b57cec5SDimitry Andric   }
2500b57cec5SDimitry Andric 
EmitLValueAlignmentAssumption(const Expr * E,Value * V)2510b57cec5SDimitry Andric   void EmitLValueAlignmentAssumption(const Expr *E, Value *V) {
2520b57cec5SDimitry Andric     const AlignValueAttr *AVAttr = nullptr;
2530b57cec5SDimitry Andric     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
2540b57cec5SDimitry Andric       const ValueDecl *VD = DRE->getDecl();
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric       if (VD->getType()->isReferenceType()) {
2570b57cec5SDimitry Andric         if (const auto *TTy =
258bdd1243dSDimitry Andric                 VD->getType().getNonReferenceType()->getAs<TypedefType>())
2590b57cec5SDimitry Andric           AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
2600b57cec5SDimitry Andric       } else {
2610b57cec5SDimitry Andric         // Assumptions for function parameters are emitted at the start of the
2620b57cec5SDimitry Andric         // function, so there is no need to repeat that here,
2630b57cec5SDimitry Andric         // unless the alignment-assumption sanitizer is enabled,
2640b57cec5SDimitry Andric         // then we prefer the assumption over alignment attribute
2650b57cec5SDimitry Andric         // on IR function param.
2660b57cec5SDimitry Andric         if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment))
2670b57cec5SDimitry Andric           return;
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric         AVAttr = VD->getAttr<AlignValueAttr>();
2700b57cec5SDimitry Andric       }
2710b57cec5SDimitry Andric     }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric     if (!AVAttr)
274bdd1243dSDimitry Andric       if (const auto *TTy = E->getType()->getAs<TypedefType>())
2750b57cec5SDimitry Andric         AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric     if (!AVAttr)
2780b57cec5SDimitry Andric       return;
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric     Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
2810b57cec5SDimitry Andric     llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
2825ffd83dbSDimitry Andric     CGF.emitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI);
2830b57cec5SDimitry Andric   }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   /// EmitLoadOfLValue - Given an expression with complex type that represents a
2860b57cec5SDimitry Andric   /// value l-value, this method emits the address of the l-value, then loads
2870b57cec5SDimitry Andric   /// and returns the result.
EmitLoadOfLValue(const Expr * E)2880b57cec5SDimitry Andric   Value *EmitLoadOfLValue(const Expr *E) {
2890b57cec5SDimitry Andric     Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
2900b57cec5SDimitry Andric                                 E->getExprLoc());
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric     EmitLValueAlignmentAssumption(E, V);
2930b57cec5SDimitry Andric     return V;
2940b57cec5SDimitry Andric   }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   /// EmitConversionToBool - Convert the specified expression value to a
2970b57cec5SDimitry Andric   /// boolean (i1) truth value.  This is equivalent to "Val != 0".
2980b57cec5SDimitry Andric   Value *EmitConversionToBool(Value *Src, QualType DstTy);
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   /// Emit a check that a conversion from a floating-point type does not
3010b57cec5SDimitry Andric   /// overflow.
3020b57cec5SDimitry Andric   void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
3030b57cec5SDimitry Andric                                 Value *Src, QualType SrcType, QualType DstType,
3040b57cec5SDimitry Andric                                 llvm::Type *DstTy, SourceLocation Loc);
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   /// Known implicit conversion check kinds.
3070b57cec5SDimitry Andric   /// Keep in sync with the enum of the same name in ubsan_handlers.h
3080b57cec5SDimitry Andric   enum ImplicitConversionCheckKind : unsigned char {
3090b57cec5SDimitry Andric     ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
3100b57cec5SDimitry Andric     ICCK_UnsignedIntegerTruncation = 1,
3110b57cec5SDimitry Andric     ICCK_SignedIntegerTruncation = 2,
3120b57cec5SDimitry Andric     ICCK_IntegerSignChange = 3,
3130b57cec5SDimitry Andric     ICCK_SignedIntegerTruncationOrSignChange = 4,
3140b57cec5SDimitry Andric   };
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   /// Emit a check that an [implicit] truncation of an integer  does not
3170b57cec5SDimitry Andric   /// discard any bits. It is not UB, so we use the value after truncation.
3180b57cec5SDimitry Andric   void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst,
3190b57cec5SDimitry Andric                                   QualType DstType, SourceLocation Loc);
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   /// Emit a check that an [implicit] conversion of an integer does not change
3220b57cec5SDimitry Andric   /// the sign of the value. It is not UB, so we use the value after conversion.
3230b57cec5SDimitry Andric   /// NOTE: Src and Dst may be the exact same value! (point to the same thing)
3240b57cec5SDimitry Andric   void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
3250b57cec5SDimitry Andric                                   QualType DstType, SourceLocation Loc);
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   /// Emit a conversion from the specified type to the specified destination
3280b57cec5SDimitry Andric   /// type, both of which are LLVM scalar types.
3290b57cec5SDimitry Andric   struct ScalarConversionOpts {
3300b57cec5SDimitry Andric     bool TreatBooleanAsSigned;
3310b57cec5SDimitry Andric     bool EmitImplicitIntegerTruncationChecks;
3320b57cec5SDimitry Andric     bool EmitImplicitIntegerSignChangeChecks;
3330b57cec5SDimitry Andric 
ScalarConversionOpts__anondf337c330111::ScalarExprEmitter::ScalarConversionOpts3340b57cec5SDimitry Andric     ScalarConversionOpts()
3350b57cec5SDimitry Andric         : TreatBooleanAsSigned(false),
3360b57cec5SDimitry Andric           EmitImplicitIntegerTruncationChecks(false),
3370b57cec5SDimitry Andric           EmitImplicitIntegerSignChangeChecks(false) {}
3380b57cec5SDimitry Andric 
ScalarConversionOpts__anondf337c330111::ScalarExprEmitter::ScalarConversionOpts3390b57cec5SDimitry Andric     ScalarConversionOpts(clang::SanitizerSet SanOpts)
3400b57cec5SDimitry Andric         : TreatBooleanAsSigned(false),
3410b57cec5SDimitry Andric           EmitImplicitIntegerTruncationChecks(
3420b57cec5SDimitry Andric               SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
3430b57cec5SDimitry Andric           EmitImplicitIntegerSignChangeChecks(
3440b57cec5SDimitry Andric               SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {}
3450b57cec5SDimitry Andric   };
346fe6060f1SDimitry Andric   Value *EmitScalarCast(Value *Src, QualType SrcType, QualType DstType,
347fe6060f1SDimitry Andric                         llvm::Type *SrcTy, llvm::Type *DstTy,
348fe6060f1SDimitry Andric                         ScalarConversionOpts Opts);
3490b57cec5SDimitry Andric   Value *
3500b57cec5SDimitry Andric   EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
3510b57cec5SDimitry Andric                        SourceLocation Loc,
3520b57cec5SDimitry Andric                        ScalarConversionOpts Opts = ScalarConversionOpts());
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   /// Convert between either a fixed point and other fixed point or fixed point
3550b57cec5SDimitry Andric   /// and an integer.
3560b57cec5SDimitry Andric   Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy,
3570b57cec5SDimitry Andric                                   SourceLocation Loc);
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   /// Emit a conversion from the specified complex type to the specified
3600b57cec5SDimitry Andric   /// destination type, where the destination type is an LLVM scalar type.
3610b57cec5SDimitry Andric   Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
3620b57cec5SDimitry Andric                                        QualType SrcTy, QualType DstTy,
3630b57cec5SDimitry Andric                                        SourceLocation Loc);
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric   /// EmitNullValue - Emit a value that corresponds to null for the given type.
3660b57cec5SDimitry Andric   Value *EmitNullValue(QualType Ty);
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric   /// EmitFloatToBoolConversion - Perform an FP to boolean conversion.
EmitFloatToBoolConversion(Value * V)3690b57cec5SDimitry Andric   Value *EmitFloatToBoolConversion(Value *V) {
3700b57cec5SDimitry Andric     // Compare against 0.0 for fp scalars.
3710b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
3720b57cec5SDimitry Andric     return Builder.CreateFCmpUNE(V, Zero, "tobool");
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion.
EmitPointerToBoolConversion(Value * V,QualType QT)3760b57cec5SDimitry Andric   Value *EmitPointerToBoolConversion(Value *V, QualType QT) {
3770b57cec5SDimitry Andric     Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT);
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric     return Builder.CreateICmpNE(V, Zero, "tobool");
3800b57cec5SDimitry Andric   }
3810b57cec5SDimitry Andric 
EmitIntToBoolConversion(Value * V)3820b57cec5SDimitry Andric   Value *EmitIntToBoolConversion(Value *V) {
3830b57cec5SDimitry Andric     // Because of the type rules of C, we often end up computing a
3840b57cec5SDimitry Andric     // logical value, then zero extending it to int, then wanting it
3850b57cec5SDimitry Andric     // as a logical value again.  Optimize this common case.
3860b57cec5SDimitry Andric     if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
3870b57cec5SDimitry Andric       if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
3880b57cec5SDimitry Andric         Value *Result = ZI->getOperand(0);
3890b57cec5SDimitry Andric         // If there aren't any more uses, zap the instruction to save space.
3900b57cec5SDimitry Andric         // Note that there can be more uses, for example if this
3910b57cec5SDimitry Andric         // is the result of an assignment.
3920b57cec5SDimitry Andric         if (ZI->use_empty())
3930b57cec5SDimitry Andric           ZI->eraseFromParent();
3940b57cec5SDimitry Andric         return Result;
3950b57cec5SDimitry Andric       }
3960b57cec5SDimitry Andric     }
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric     return Builder.CreateIsNotNull(V, "tobool");
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
4020b57cec5SDimitry Andric   //                            Visitor Methods
4030b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
4040b57cec5SDimitry Andric 
Visit(Expr * E)4050b57cec5SDimitry Andric   Value *Visit(Expr *E) {
4060b57cec5SDimitry Andric     ApplyDebugLocation DL(CGF, E);
4070b57cec5SDimitry Andric     return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric 
VisitStmt(Stmt * S)4100b57cec5SDimitry Andric   Value *VisitStmt(Stmt *S) {
4115ffd83dbSDimitry Andric     S->dump(llvm::errs(), CGF.getContext());
4120b57cec5SDimitry Andric     llvm_unreachable("Stmt can't have complex result type!");
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric   Value *VisitExpr(Expr *S);
4150b57cec5SDimitry Andric 
VisitConstantExpr(ConstantExpr * E)4160b57cec5SDimitry Andric   Value *VisitConstantExpr(ConstantExpr *E) {
417349cc55cSDimitry Andric     // A constant expression of type 'void' generates no code and produces no
418349cc55cSDimitry Andric     // value.
419349cc55cSDimitry Andric     if (E->getType()->isVoidType())
420349cc55cSDimitry Andric       return nullptr;
421349cc55cSDimitry Andric 
4225ffd83dbSDimitry Andric     if (Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
4235ffd83dbSDimitry Andric       if (E->isGLValue())
4245ffd83dbSDimitry Andric         return CGF.Builder.CreateLoad(Address(
42581ad6265SDimitry Andric             Result, CGF.ConvertTypeForMem(E->getType()),
42681ad6265SDimitry Andric             CGF.getContext().getTypeAlignInChars(E->getType())));
4275ffd83dbSDimitry Andric       return Result;
4285ffd83dbSDimitry Andric     }
4290b57cec5SDimitry Andric     return Visit(E->getSubExpr());
4300b57cec5SDimitry Andric   }
VisitParenExpr(ParenExpr * PE)4310b57cec5SDimitry Andric   Value *VisitParenExpr(ParenExpr *PE) {
4320b57cec5SDimitry Andric     return Visit(PE->getSubExpr());
4330b57cec5SDimitry Andric   }
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)4340b57cec5SDimitry Andric   Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
4350b57cec5SDimitry Andric     return Visit(E->getReplacement());
4360b57cec5SDimitry Andric   }
VisitGenericSelectionExpr(GenericSelectionExpr * GE)4370b57cec5SDimitry Andric   Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
4380b57cec5SDimitry Andric     return Visit(GE->getResultExpr());
4390b57cec5SDimitry Andric   }
VisitCoawaitExpr(CoawaitExpr * S)4400b57cec5SDimitry Andric   Value *VisitCoawaitExpr(CoawaitExpr *S) {
4410b57cec5SDimitry Andric     return CGF.EmitCoawaitExpr(*S).getScalarVal();
4420b57cec5SDimitry Andric   }
VisitCoyieldExpr(CoyieldExpr * S)4430b57cec5SDimitry Andric   Value *VisitCoyieldExpr(CoyieldExpr *S) {
4440b57cec5SDimitry Andric     return CGF.EmitCoyieldExpr(*S).getScalarVal();
4450b57cec5SDimitry Andric   }
VisitUnaryCoawait(const UnaryOperator * E)4460b57cec5SDimitry Andric   Value *VisitUnaryCoawait(const UnaryOperator *E) {
4470b57cec5SDimitry Andric     return Visit(E->getSubExpr());
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   // Leaves.
VisitIntegerLiteral(const IntegerLiteral * E)4510b57cec5SDimitry Andric   Value *VisitIntegerLiteral(const IntegerLiteral *E) {
4520b57cec5SDimitry Andric     return Builder.getInt(E->getValue());
4530b57cec5SDimitry Andric   }
VisitFixedPointLiteral(const FixedPointLiteral * E)4540b57cec5SDimitry Andric   Value *VisitFixedPointLiteral(const FixedPointLiteral *E) {
4550b57cec5SDimitry Andric     return Builder.getInt(E->getValue());
4560b57cec5SDimitry Andric   }
VisitFloatingLiteral(const FloatingLiteral * E)4570b57cec5SDimitry Andric   Value *VisitFloatingLiteral(const FloatingLiteral *E) {
4580b57cec5SDimitry Andric     return llvm::ConstantFP::get(VMContext, E->getValue());
4590b57cec5SDimitry Andric   }
VisitCharacterLiteral(const CharacterLiteral * E)4600b57cec5SDimitry Andric   Value *VisitCharacterLiteral(const CharacterLiteral *E) {
4610b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4620b57cec5SDimitry Andric   }
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * E)4630b57cec5SDimitry Andric   Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
4640b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4650b57cec5SDimitry Andric   }
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * E)4660b57cec5SDimitry Andric   Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
4670b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4680b57cec5SDimitry Andric   }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)4690b57cec5SDimitry Andric   Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
470bdd1243dSDimitry Andric     if (E->getType()->isVoidType())
471bdd1243dSDimitry Andric       return nullptr;
472bdd1243dSDimitry Andric 
4730b57cec5SDimitry Andric     return EmitNullValue(E->getType());
4740b57cec5SDimitry Andric   }
VisitGNUNullExpr(const GNUNullExpr * E)4750b57cec5SDimitry Andric   Value *VisitGNUNullExpr(const GNUNullExpr *E) {
4760b57cec5SDimitry Andric     return EmitNullValue(E->getType());
4770b57cec5SDimitry Andric   }
4780b57cec5SDimitry Andric   Value *VisitOffsetOfExpr(OffsetOfExpr *E);
4790b57cec5SDimitry Andric   Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
VisitAddrLabelExpr(const AddrLabelExpr * E)4800b57cec5SDimitry Andric   Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
4810b57cec5SDimitry Andric     llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
4820b57cec5SDimitry Andric     return Builder.CreateBitCast(V, ConvertType(E->getType()));
4830b57cec5SDimitry Andric   }
4840b57cec5SDimitry Andric 
VisitSizeOfPackExpr(SizeOfPackExpr * E)4850b57cec5SDimitry Andric   Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
4860b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength());
4870b57cec5SDimitry Andric   }
4880b57cec5SDimitry Andric 
VisitPseudoObjectExpr(PseudoObjectExpr * E)4890b57cec5SDimitry Andric   Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
4900b57cec5SDimitry Andric     return CGF.EmitPseudoObjectRValue(E).getScalarVal();
4910b57cec5SDimitry Andric   }
4920b57cec5SDimitry Andric 
493fe6060f1SDimitry Andric   Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
494fe6060f1SDimitry Andric 
VisitOpaqueValueExpr(OpaqueValueExpr * E)4950b57cec5SDimitry Andric   Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
4960b57cec5SDimitry Andric     if (E->isGLValue())
4970b57cec5SDimitry Andric       return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E),
4980b57cec5SDimitry Andric                               E->getExprLoc());
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric     // Otherwise, assume the mapping is the scalar directly.
5010b57cec5SDimitry Andric     return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal();
5020b57cec5SDimitry Andric   }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric   // l-values.
VisitDeclRefExpr(DeclRefExpr * E)5050b57cec5SDimitry Andric   Value *VisitDeclRefExpr(DeclRefExpr *E) {
5060b57cec5SDimitry Andric     if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
5070b57cec5SDimitry Andric       return CGF.emitScalarConstant(Constant, E);
5080b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
5090b57cec5SDimitry Andric   }
5100b57cec5SDimitry Andric 
VisitObjCSelectorExpr(ObjCSelectorExpr * E)5110b57cec5SDimitry Andric   Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
5120b57cec5SDimitry Andric     return CGF.EmitObjCSelectorExpr(E);
5130b57cec5SDimitry Andric   }
VisitObjCProtocolExpr(ObjCProtocolExpr * E)5140b57cec5SDimitry Andric   Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
5150b57cec5SDimitry Andric     return CGF.EmitObjCProtocolExpr(E);
5160b57cec5SDimitry Andric   }
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)5170b57cec5SDimitry Andric   Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
5180b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
5190b57cec5SDimitry Andric   }
VisitObjCMessageExpr(ObjCMessageExpr * E)5200b57cec5SDimitry Andric   Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
5210b57cec5SDimitry Andric     if (E->getMethodDecl() &&
5220b57cec5SDimitry Andric         E->getMethodDecl()->getReturnType()->isReferenceType())
5230b57cec5SDimitry Andric       return EmitLoadOfLValue(E);
5240b57cec5SDimitry Andric     return CGF.EmitObjCMessageExpr(E).getScalarVal();
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric 
VisitObjCIsaExpr(ObjCIsaExpr * E)5270b57cec5SDimitry Andric   Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
5280b57cec5SDimitry Andric     LValue LV = CGF.EmitObjCIsaExpr(E);
5290b57cec5SDimitry Andric     Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal();
5300b57cec5SDimitry Andric     return V;
5310b57cec5SDimitry Andric   }
5320b57cec5SDimitry Andric 
VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * E)5330b57cec5SDimitry Andric   Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
5340b57cec5SDimitry Andric     VersionTuple Version = E->getVersion();
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric     // If we're checking for a platform older than our minimum deployment
5370b57cec5SDimitry Andric     // target, we can fold the check away.
5380b57cec5SDimitry Andric     if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
5390b57cec5SDimitry Andric       return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
5400b57cec5SDimitry Andric 
541e8d8bef9SDimitry Andric     return CGF.EmitBuiltinAvailable(Version);
5420b57cec5SDimitry Andric   }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
5455ffd83dbSDimitry Andric   Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
5460b57cec5SDimitry Andric   Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
5470b57cec5SDimitry Andric   Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
5480b57cec5SDimitry Andric   Value *VisitMemberExpr(MemberExpr *E);
VisitExtVectorElementExpr(Expr * E)5490b57cec5SDimitry Andric   Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)5500b57cec5SDimitry Andric   Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
5515ffd83dbSDimitry Andric     // Strictly speaking, we shouldn't be calling EmitLoadOfLValue, which
5525ffd83dbSDimitry Andric     // transitively calls EmitCompoundLiteralLValue, here in C++ since compound
5535ffd83dbSDimitry Andric     // literals aren't l-values in C++. We do so simply because that's the
5545ffd83dbSDimitry Andric     // cleanest way to handle compound literals in C++.
5555ffd83dbSDimitry Andric     // See the discussion here: https://reviews.llvm.org/D64464
5560b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
5570b57cec5SDimitry Andric   }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   Value *VisitInitListExpr(InitListExpr *E);
5600b57cec5SDimitry Andric 
VisitArrayInitIndexExpr(ArrayInitIndexExpr * E)5610b57cec5SDimitry Andric   Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
5620b57cec5SDimitry Andric     assert(CGF.getArrayInitIndex() &&
5630b57cec5SDimitry Andric            "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
5640b57cec5SDimitry Andric     return CGF.getArrayInitIndex();
5650b57cec5SDimitry Andric   }
5660b57cec5SDimitry Andric 
VisitImplicitValueInitExpr(const ImplicitValueInitExpr * E)5670b57cec5SDimitry Andric   Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
5680b57cec5SDimitry Andric     return EmitNullValue(E->getType());
5690b57cec5SDimitry Andric   }
VisitExplicitCastExpr(ExplicitCastExpr * E)5700b57cec5SDimitry Andric   Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
5710b57cec5SDimitry Andric     CGF.CGM.EmitExplicitCastExprType(E, &CGF);
5720b57cec5SDimitry Andric     return VisitCastExpr(E);
5730b57cec5SDimitry Andric   }
5740b57cec5SDimitry Andric   Value *VisitCastExpr(CastExpr *E);
5750b57cec5SDimitry Andric 
VisitCallExpr(const CallExpr * E)5760b57cec5SDimitry Andric   Value *VisitCallExpr(const CallExpr *E) {
5770b57cec5SDimitry Andric     if (E->getCallReturnType(CGF.getContext())->isReferenceType())
5780b57cec5SDimitry Andric       return EmitLoadOfLValue(E);
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric     Value *V = CGF.EmitCallExpr(E).getScalarVal();
5810b57cec5SDimitry Andric 
5820b57cec5SDimitry Andric     EmitLValueAlignmentAssumption(E, V);
5830b57cec5SDimitry Andric     return V;
5840b57cec5SDimitry Andric   }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric   Value *VisitStmtExpr(const StmtExpr *E);
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   // Unary Operators.
VisitUnaryPostDec(const UnaryOperator * E)5890b57cec5SDimitry Andric   Value *VisitUnaryPostDec(const UnaryOperator *E) {
5900b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
5910b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, false, false);
5920b57cec5SDimitry Andric   }
VisitUnaryPostInc(const UnaryOperator * E)5930b57cec5SDimitry Andric   Value *VisitUnaryPostInc(const UnaryOperator *E) {
5940b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
5950b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, true, false);
5960b57cec5SDimitry Andric   }
VisitUnaryPreDec(const UnaryOperator * E)5970b57cec5SDimitry Andric   Value *VisitUnaryPreDec(const UnaryOperator *E) {
5980b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
5990b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, false, true);
6000b57cec5SDimitry Andric   }
VisitUnaryPreInc(const UnaryOperator * E)6010b57cec5SDimitry Andric   Value *VisitUnaryPreInc(const UnaryOperator *E) {
6020b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
6030b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, true, true);
6040b57cec5SDimitry Andric   }
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric   llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E,
6070b57cec5SDimitry Andric                                                   llvm::Value *InVal,
6080b57cec5SDimitry Andric                                                   bool IsInc);
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
6110b57cec5SDimitry Andric                                        bool isInc, bool isPre);
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric 
VisitUnaryAddrOf(const UnaryOperator * E)6140b57cec5SDimitry Andric   Value *VisitUnaryAddrOf(const UnaryOperator *E) {
6150b57cec5SDimitry Andric     if (isa<MemberPointerType>(E->getType())) // never sugared
6160b57cec5SDimitry Andric       return CGF.CGM.getMemberPointerConstant(E);
6170b57cec5SDimitry Andric 
618480093f4SDimitry Andric     return EmitLValue(E->getSubExpr()).getPointer(CGF);
6190b57cec5SDimitry Andric   }
VisitUnaryDeref(const UnaryOperator * E)6200b57cec5SDimitry Andric   Value *VisitUnaryDeref(const UnaryOperator *E) {
6210b57cec5SDimitry Andric     if (E->getType()->isVoidType())
6220b57cec5SDimitry Andric       return Visit(E->getSubExpr()); // the actual value should be unused
6230b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
6240b57cec5SDimitry Andric   }
625bdd1243dSDimitry Andric 
626bdd1243dSDimitry Andric   Value *VisitUnaryPlus(const UnaryOperator *E,
627bdd1243dSDimitry Andric                         QualType PromotionType = QualType());
628bdd1243dSDimitry Andric   Value *VisitPlus(const UnaryOperator *E, QualType PromotionType);
629bdd1243dSDimitry Andric   Value *VisitUnaryMinus(const UnaryOperator *E,
630bdd1243dSDimitry Andric                          QualType PromotionType = QualType());
631bdd1243dSDimitry Andric   Value *VisitMinus(const UnaryOperator *E, QualType PromotionType);
632bdd1243dSDimitry Andric 
6330b57cec5SDimitry Andric   Value *VisitUnaryNot      (const UnaryOperator *E);
6340b57cec5SDimitry Andric   Value *VisitUnaryLNot     (const UnaryOperator *E);
635bdd1243dSDimitry Andric   Value *VisitUnaryReal(const UnaryOperator *E,
636bdd1243dSDimitry Andric                         QualType PromotionType = QualType());
637bdd1243dSDimitry Andric   Value *VisitReal(const UnaryOperator *E, QualType PromotionType);
638bdd1243dSDimitry Andric   Value *VisitUnaryImag(const UnaryOperator *E,
639bdd1243dSDimitry Andric                         QualType PromotionType = QualType());
640bdd1243dSDimitry Andric   Value *VisitImag(const UnaryOperator *E, QualType PromotionType);
VisitUnaryExtension(const UnaryOperator * E)6410b57cec5SDimitry Andric   Value *VisitUnaryExtension(const UnaryOperator *E) {
6420b57cec5SDimitry Andric     return Visit(E->getSubExpr());
6430b57cec5SDimitry Andric   }
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric   // C++
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * E)6460b57cec5SDimitry Andric   Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {
6470b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
6480b57cec5SDimitry Andric   }
VisitSourceLocExpr(SourceLocExpr * SLE)6490b57cec5SDimitry Andric   Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
6500b57cec5SDimitry Andric     auto &Ctx = CGF.getContext();
6510b57cec5SDimitry Andric     APValue Evaluated =
6520b57cec5SDimitry Andric         SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr());
653480093f4SDimitry Andric     return ConstantEmitter(CGF).emitAbstract(SLE->getLocation(), Evaluated,
654480093f4SDimitry Andric                                              SLE->getType());
6550b57cec5SDimitry Andric   }
6560b57cec5SDimitry Andric 
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)6570b57cec5SDimitry Andric   Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
6580b57cec5SDimitry Andric     CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
6590b57cec5SDimitry Andric     return Visit(DAE->getExpr());
6600b57cec5SDimitry Andric   }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)6610b57cec5SDimitry Andric   Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
6620b57cec5SDimitry Andric     CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
6630b57cec5SDimitry Andric     return Visit(DIE->getExpr());
6640b57cec5SDimitry Andric   }
VisitCXXThisExpr(CXXThisExpr * TE)6650b57cec5SDimitry Andric   Value *VisitCXXThisExpr(CXXThisExpr *TE) {
6660b57cec5SDimitry Andric     return CGF.LoadCXXThis();
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   Value *VisitExprWithCleanups(ExprWithCleanups *E);
VisitCXXNewExpr(const CXXNewExpr * E)6700b57cec5SDimitry Andric   Value *VisitCXXNewExpr(const CXXNewExpr *E) {
6710b57cec5SDimitry Andric     return CGF.EmitCXXNewExpr(E);
6720b57cec5SDimitry Andric   }
VisitCXXDeleteExpr(const CXXDeleteExpr * E)6730b57cec5SDimitry Andric   Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
6740b57cec5SDimitry Andric     CGF.EmitCXXDeleteExpr(E);
6750b57cec5SDimitry Andric     return nullptr;
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric 
VisitTypeTraitExpr(const TypeTraitExpr * E)6780b57cec5SDimitry Andric   Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
6790b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
6800b57cec5SDimitry Andric   }
6810b57cec5SDimitry Andric 
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * E)682a7dea167SDimitry Andric   Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
683a7dea167SDimitry Andric     return Builder.getInt1(E->isSatisfied());
684a7dea167SDimitry Andric   }
685a7dea167SDimitry Andric 
VisitRequiresExpr(const RequiresExpr * E)68655e4f9d5SDimitry Andric   Value *VisitRequiresExpr(const RequiresExpr *E) {
68755e4f9d5SDimitry Andric     return Builder.getInt1(E->isSatisfied());
68855e4f9d5SDimitry Andric   }
68955e4f9d5SDimitry Andric 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)6900b57cec5SDimitry Andric   Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
6910b57cec5SDimitry Andric     return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
6920b57cec5SDimitry Andric   }
6930b57cec5SDimitry Andric 
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)6940b57cec5SDimitry Andric   Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
6950b57cec5SDimitry Andric     return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
6960b57cec5SDimitry Andric   }
6970b57cec5SDimitry Andric 
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)6980b57cec5SDimitry Andric   Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) {
6990b57cec5SDimitry Andric     // C++ [expr.pseudo]p1:
7000b57cec5SDimitry Andric     //   The result shall only be used as the operand for the function call
7010b57cec5SDimitry Andric     //   operator (), and the result of such a call has type void. The only
7020b57cec5SDimitry Andric     //   effect is the evaluation of the postfix-expression before the dot or
7030b57cec5SDimitry Andric     //   arrow.
7040b57cec5SDimitry Andric     CGF.EmitScalarExpr(E->getBase());
7050b57cec5SDimitry Andric     return nullptr;
7060b57cec5SDimitry Andric   }
7070b57cec5SDimitry Andric 
VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr * E)7080b57cec5SDimitry Andric   Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
7090b57cec5SDimitry Andric     return EmitNullValue(E->getType());
7100b57cec5SDimitry Andric   }
7110b57cec5SDimitry Andric 
VisitCXXThrowExpr(const CXXThrowExpr * E)7120b57cec5SDimitry Andric   Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
7130b57cec5SDimitry Andric     CGF.EmitCXXThrowExpr(E);
7140b57cec5SDimitry Andric     return nullptr;
7150b57cec5SDimitry Andric   }
7160b57cec5SDimitry Andric 
VisitCXXNoexceptExpr(const CXXNoexceptExpr * E)7170b57cec5SDimitry Andric   Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
7180b57cec5SDimitry Andric     return Builder.getInt1(E->getValue());
7190b57cec5SDimitry Andric   }
7200b57cec5SDimitry Andric 
7210b57cec5SDimitry Andric   // Binary Operators.
EmitMul(const BinOpInfo & Ops)7220b57cec5SDimitry Andric   Value *EmitMul(const BinOpInfo &Ops) {
7230b57cec5SDimitry Andric     if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
7240b57cec5SDimitry Andric       switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
7250b57cec5SDimitry Andric       case LangOptions::SOB_Defined:
7260b57cec5SDimitry Andric         return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
7270b57cec5SDimitry Andric       case LangOptions::SOB_Undefined:
7280b57cec5SDimitry Andric         if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
7290b57cec5SDimitry Andric           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
730bdd1243dSDimitry Andric         [[fallthrough]];
7310b57cec5SDimitry Andric       case LangOptions::SOB_Trapping:
7320b57cec5SDimitry Andric         if (CanElideOverflowCheck(CGF.getContext(), Ops))
7330b57cec5SDimitry Andric           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
7340b57cec5SDimitry Andric         return EmitOverflowCheckedBinOp(Ops);
7350b57cec5SDimitry Andric       }
7360b57cec5SDimitry Andric     }
7370b57cec5SDimitry Andric 
7385ffd83dbSDimitry Andric     if (Ops.Ty->isConstantMatrixType()) {
73981ad6265SDimitry Andric       llvm::MatrixBuilder MB(Builder);
7405ffd83dbSDimitry Andric       // We need to check the types of the operands of the operator to get the
7415ffd83dbSDimitry Andric       // correct matrix dimensions.
7425ffd83dbSDimitry Andric       auto *BO = cast<BinaryOperator>(Ops.E);
7435ffd83dbSDimitry Andric       auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
7445ffd83dbSDimitry Andric           BO->getLHS()->getType().getCanonicalType());
7455ffd83dbSDimitry Andric       auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
7465ffd83dbSDimitry Andric           BO->getRHS()->getType().getCanonicalType());
747fe6060f1SDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
7485ffd83dbSDimitry Andric       if (LHSMatTy && RHSMatTy)
7495ffd83dbSDimitry Andric         return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
7505ffd83dbSDimitry Andric                                        LHSMatTy->getNumColumns(),
7515ffd83dbSDimitry Andric                                        RHSMatTy->getNumColumns());
7525ffd83dbSDimitry Andric       return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
7535ffd83dbSDimitry Andric     }
7545ffd83dbSDimitry Andric 
7550b57cec5SDimitry Andric     if (Ops.Ty->isUnsignedIntegerType() &&
7560b57cec5SDimitry Andric         CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
7570b57cec5SDimitry Andric         !CanElideOverflowCheck(CGF.getContext(), Ops))
7580b57cec5SDimitry Andric       return EmitOverflowCheckedBinOp(Ops);
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric     if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
7615ffd83dbSDimitry Andric       //  Preserve the old values
7625ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
7635ffd83dbSDimitry Andric       return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
7640b57cec5SDimitry Andric     }
7655ffd83dbSDimitry Andric     if (Ops.isFixedPointOp())
7665ffd83dbSDimitry Andric       return EmitFixedPointBinOp(Ops);
7670b57cec5SDimitry Andric     return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
7680b57cec5SDimitry Andric   }
7690b57cec5SDimitry Andric   /// Create a binary op that checks for overflow.
7700b57cec5SDimitry Andric   /// Currently only supports +, - and *.
7710b57cec5SDimitry Andric   Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric   // Check for undefined division and modulus behaviors.
7740b57cec5SDimitry Andric   void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,
7750b57cec5SDimitry Andric                                                   llvm::Value *Zero,bool isDiv);
7760b57cec5SDimitry Andric   // Common helper for getting how wide LHS of shift is.
7770b57cec5SDimitry Andric   static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS);
7785ffd83dbSDimitry Andric 
7795ffd83dbSDimitry Andric   // Used for shifting constraints for OpenCL, do mask for powers of 2, URem for
7805ffd83dbSDimitry Andric   // non powers of two.
7815ffd83dbSDimitry Andric   Value *ConstrainShiftValue(Value *LHS, Value *RHS, const Twine &Name);
7825ffd83dbSDimitry Andric 
7830b57cec5SDimitry Andric   Value *EmitDiv(const BinOpInfo &Ops);
7840b57cec5SDimitry Andric   Value *EmitRem(const BinOpInfo &Ops);
7850b57cec5SDimitry Andric   Value *EmitAdd(const BinOpInfo &Ops);
7860b57cec5SDimitry Andric   Value *EmitSub(const BinOpInfo &Ops);
7870b57cec5SDimitry Andric   Value *EmitShl(const BinOpInfo &Ops);
7880b57cec5SDimitry Andric   Value *EmitShr(const BinOpInfo &Ops);
EmitAnd(const BinOpInfo & Ops)7890b57cec5SDimitry Andric   Value *EmitAnd(const BinOpInfo &Ops) {
7900b57cec5SDimitry Andric     return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
7910b57cec5SDimitry Andric   }
EmitXor(const BinOpInfo & Ops)7920b57cec5SDimitry Andric   Value *EmitXor(const BinOpInfo &Ops) {
7930b57cec5SDimitry Andric     return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
7940b57cec5SDimitry Andric   }
EmitOr(const BinOpInfo & Ops)7950b57cec5SDimitry Andric   Value *EmitOr (const BinOpInfo &Ops) {
7960b57cec5SDimitry Andric     return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
7970b57cec5SDimitry Andric   }
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric   // Helper functions for fixed point binary operations.
8000b57cec5SDimitry Andric   Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
8010b57cec5SDimitry Andric 
802bdd1243dSDimitry Andric   BinOpInfo EmitBinOps(const BinaryOperator *E,
803bdd1243dSDimitry Andric                        QualType PromotionTy = QualType());
804bdd1243dSDimitry Andric 
805bdd1243dSDimitry Andric   Value *EmitPromotedValue(Value *result, QualType PromotionType);
806bdd1243dSDimitry Andric   Value *EmitUnPromotedValue(Value *result, QualType ExprType);
807bdd1243dSDimitry Andric   Value *EmitPromoted(const Expr *E, QualType PromotionType);
808bdd1243dSDimitry Andric 
8090b57cec5SDimitry Andric   LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
8100b57cec5SDimitry Andric                             Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
8110b57cec5SDimitry Andric                                   Value *&Result);
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric   Value *EmitCompoundAssign(const CompoundAssignOperator *E,
8140b57cec5SDimitry Andric                             Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
8150b57cec5SDimitry Andric 
getPromotionType(QualType Ty)816bdd1243dSDimitry Andric   QualType getPromotionType(QualType Ty) {
817fe013be4SDimitry Andric     const auto &Ctx = CGF.getContext();
818bdd1243dSDimitry Andric     if (auto *CT = Ty->getAs<ComplexType>()) {
819bdd1243dSDimitry Andric       QualType ElementType = CT->getElementType();
820fe013be4SDimitry Andric       if (ElementType.UseExcessPrecision(Ctx))
821fe013be4SDimitry Andric         return Ctx.getComplexType(Ctx.FloatTy);
822bdd1243dSDimitry Andric     }
823fe013be4SDimitry Andric 
824fe013be4SDimitry Andric     if (Ty.UseExcessPrecision(Ctx)) {
825fe013be4SDimitry Andric       if (auto *VT = Ty->getAs<VectorType>()) {
826fe013be4SDimitry Andric         unsigned NumElements = VT->getNumElements();
827fe013be4SDimitry Andric         return Ctx.getVectorType(Ctx.FloatTy, NumElements, VT->getVectorKind());
828fe013be4SDimitry Andric       }
829fe013be4SDimitry Andric       return Ctx.FloatTy;
830fe013be4SDimitry Andric     }
831fe013be4SDimitry Andric 
832bdd1243dSDimitry Andric     return QualType();
833bdd1243dSDimitry Andric   }
834bdd1243dSDimitry Andric 
8350b57cec5SDimitry Andric   // Binary operators and binary compound assignment operators.
8360b57cec5SDimitry Andric #define HANDLEBINOP(OP)                                                        \
8370b57cec5SDimitry Andric   Value *VisitBin##OP(const BinaryOperator *E) {                               \
838bdd1243dSDimitry Andric     QualType promotionTy = getPromotionType(E->getType());                     \
839bdd1243dSDimitry Andric     auto result = Emit##OP(EmitBinOps(E, promotionTy));                        \
840bdd1243dSDimitry Andric     if (result && !promotionTy.isNull())                                       \
841bdd1243dSDimitry Andric       result = EmitUnPromotedValue(result, E->getType());                      \
842bdd1243dSDimitry Andric     return result;                                                             \
8430b57cec5SDimitry Andric   }                                                                            \
8440b57cec5SDimitry Andric   Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) {               \
8450b57cec5SDimitry Andric     return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP);                \
8460b57cec5SDimitry Andric   }
8470b57cec5SDimitry Andric   HANDLEBINOP(Mul)
8480b57cec5SDimitry Andric   HANDLEBINOP(Div)
8490b57cec5SDimitry Andric   HANDLEBINOP(Rem)
8500b57cec5SDimitry Andric   HANDLEBINOP(Add)
8510b57cec5SDimitry Andric   HANDLEBINOP(Sub)
8520b57cec5SDimitry Andric   HANDLEBINOP(Shl)
8530b57cec5SDimitry Andric   HANDLEBINOP(Shr)
8540b57cec5SDimitry Andric   HANDLEBINOP(And)
8550b57cec5SDimitry Andric   HANDLEBINOP(Xor)
8560b57cec5SDimitry Andric   HANDLEBINOP(Or)
8570b57cec5SDimitry Andric #undef HANDLEBINOP
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric   // Comparisons.
8600b57cec5SDimitry Andric   Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc,
8610b57cec5SDimitry Andric                      llvm::CmpInst::Predicate SICmpOpc,
862480093f4SDimitry Andric                      llvm::CmpInst::Predicate FCmpOpc, bool IsSignaling);
863480093f4SDimitry Andric #define VISITCOMP(CODE, UI, SI, FP, SIG) \
8640b57cec5SDimitry Andric     Value *VisitBin##CODE(const BinaryOperator *E) { \
8650b57cec5SDimitry Andric       return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
866480093f4SDimitry Andric                          llvm::FCmpInst::FP, SIG); }
867480093f4SDimitry Andric   VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT, true)
868480093f4SDimitry Andric   VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT, true)
869480093f4SDimitry Andric   VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE, true)
870480093f4SDimitry Andric   VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE, true)
871480093f4SDimitry Andric   VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ, false)
872480093f4SDimitry Andric   VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE, false)
8730b57cec5SDimitry Andric #undef VISITCOMP
8740b57cec5SDimitry Andric 
8750b57cec5SDimitry Andric   Value *VisitBinAssign     (const BinaryOperator *E);
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric   Value *VisitBinLAnd       (const BinaryOperator *E);
8780b57cec5SDimitry Andric   Value *VisitBinLOr        (const BinaryOperator *E);
8790b57cec5SDimitry Andric   Value *VisitBinComma      (const BinaryOperator *E);
8800b57cec5SDimitry Andric 
VisitBinPtrMemD(const Expr * E)8810b57cec5SDimitry Andric   Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
VisitBinPtrMemI(const Expr * E)8820b57cec5SDimitry Andric   Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
8830b57cec5SDimitry Andric 
VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator * E)884a7dea167SDimitry Andric   Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
885a7dea167SDimitry Andric     return Visit(E->getSemanticForm());
886a7dea167SDimitry Andric   }
887a7dea167SDimitry Andric 
8880b57cec5SDimitry Andric   // Other Operators.
8890b57cec5SDimitry Andric   Value *VisitBlockExpr(const BlockExpr *BE);
8900b57cec5SDimitry Andric   Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *);
8910b57cec5SDimitry Andric   Value *VisitChooseExpr(ChooseExpr *CE);
8920b57cec5SDimitry Andric   Value *VisitVAArgExpr(VAArgExpr *VE);
VisitObjCStringLiteral(const ObjCStringLiteral * E)8930b57cec5SDimitry Andric   Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
8940b57cec5SDimitry Andric     return CGF.EmitObjCStringLiteral(E);
8950b57cec5SDimitry Andric   }
VisitObjCBoxedExpr(ObjCBoxedExpr * E)8960b57cec5SDimitry Andric   Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
8970b57cec5SDimitry Andric     return CGF.EmitObjCBoxedExpr(E);
8980b57cec5SDimitry Andric   }
VisitObjCArrayLiteral(ObjCArrayLiteral * E)8990b57cec5SDimitry Andric   Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
9000b57cec5SDimitry Andric     return CGF.EmitObjCArrayLiteral(E);
9010b57cec5SDimitry Andric   }
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)9020b57cec5SDimitry Andric   Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
9030b57cec5SDimitry Andric     return CGF.EmitObjCDictionaryLiteral(E);
9040b57cec5SDimitry Andric   }
9050b57cec5SDimitry Andric   Value *VisitAsTypeExpr(AsTypeExpr *CE);
9060b57cec5SDimitry Andric   Value *VisitAtomicExpr(AtomicExpr *AE);
9070b57cec5SDimitry Andric };
9080b57cec5SDimitry Andric }  // end anonymous namespace.
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9110b57cec5SDimitry Andric //                                Utilities
9120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric /// EmitConversionToBool - Convert the specified expression value to a
9150b57cec5SDimitry Andric /// boolean (i1) truth value.  This is equivalent to "Val != 0".
EmitConversionToBool(Value * Src,QualType SrcType)9160b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
9170b57cec5SDimitry Andric   assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   if (SrcType->isRealFloatingType())
9200b57cec5SDimitry Andric     return EmitFloatToBoolConversion(Src);
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
9230b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT);
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric   assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
9260b57cec5SDimitry Andric          "Unknown scalar type to convert");
9270b57cec5SDimitry Andric 
9280b57cec5SDimitry Andric   if (isa<llvm::IntegerType>(Src->getType()))
9290b57cec5SDimitry Andric     return EmitIntToBoolConversion(Src);
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   assert(isa<llvm::PointerType>(Src->getType()));
9320b57cec5SDimitry Andric   return EmitPointerToBoolConversion(Src, SrcType);
9330b57cec5SDimitry Andric }
9340b57cec5SDimitry Andric 
EmitFloatConversionCheck(Value * OrigSrc,QualType OrigSrcType,Value * Src,QualType SrcType,QualType DstType,llvm::Type * DstTy,SourceLocation Loc)9350b57cec5SDimitry Andric void ScalarExprEmitter::EmitFloatConversionCheck(
9360b57cec5SDimitry Andric     Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
9370b57cec5SDimitry Andric     QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
9380b57cec5SDimitry Andric   assert(SrcType->isFloatingType() && "not a conversion from floating point");
9390b57cec5SDimitry Andric   if (!isa<llvm::IntegerType>(DstTy))
9400b57cec5SDimitry Andric     return;
9410b57cec5SDimitry Andric 
9420b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
9430b57cec5SDimitry Andric   using llvm::APFloat;
9440b57cec5SDimitry Andric   using llvm::APSInt;
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric   llvm::Value *Check = nullptr;
9470b57cec5SDimitry Andric   const llvm::fltSemantics &SrcSema =
9480b57cec5SDimitry Andric     CGF.getContext().getFloatTypeSemantics(OrigSrcType);
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   // Floating-point to integer. This has undefined behavior if the source is
9510b57cec5SDimitry Andric   // +-Inf, NaN, or doesn't fit into the destination type (after truncation
9520b57cec5SDimitry Andric   // to an integer).
9530b57cec5SDimitry Andric   unsigned Width = CGF.getContext().getIntWidth(DstType);
9540b57cec5SDimitry Andric   bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric   APSInt Min = APSInt::getMinValue(Width, Unsigned);
9570b57cec5SDimitry Andric   APFloat MinSrc(SrcSema, APFloat::uninitialized);
9580b57cec5SDimitry Andric   if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
9590b57cec5SDimitry Andric       APFloat::opOverflow)
9600b57cec5SDimitry Andric     // Don't need an overflow check for lower bound. Just check for
9610b57cec5SDimitry Andric     // -Inf/NaN.
9620b57cec5SDimitry Andric     MinSrc = APFloat::getInf(SrcSema, true);
9630b57cec5SDimitry Andric   else
9640b57cec5SDimitry Andric     // Find the largest value which is too small to represent (before
9650b57cec5SDimitry Andric     // truncation toward zero).
9660b57cec5SDimitry Andric     MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   APSInt Max = APSInt::getMaxValue(Width, Unsigned);
9690b57cec5SDimitry Andric   APFloat MaxSrc(SrcSema, APFloat::uninitialized);
9700b57cec5SDimitry Andric   if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
9710b57cec5SDimitry Andric       APFloat::opOverflow)
9720b57cec5SDimitry Andric     // Don't need an overflow check for upper bound. Just check for
9730b57cec5SDimitry Andric     // +Inf/NaN.
9740b57cec5SDimitry Andric     MaxSrc = APFloat::getInf(SrcSema, false);
9750b57cec5SDimitry Andric   else
9760b57cec5SDimitry Andric     // Find the smallest value which is too large to represent (before
9770b57cec5SDimitry Andric     // truncation toward zero).
9780b57cec5SDimitry Andric     MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric   // If we're converting from __half, convert the range to float to match
9810b57cec5SDimitry Andric   // the type of src.
9820b57cec5SDimitry Andric   if (OrigSrcType->isHalfType()) {
9830b57cec5SDimitry Andric     const llvm::fltSemantics &Sema =
9840b57cec5SDimitry Andric       CGF.getContext().getFloatTypeSemantics(SrcType);
9850b57cec5SDimitry Andric     bool IsInexact;
9860b57cec5SDimitry Andric     MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
9870b57cec5SDimitry Andric     MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
9880b57cec5SDimitry Andric   }
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric   llvm::Value *GE =
9910b57cec5SDimitry Andric     Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
9920b57cec5SDimitry Andric   llvm::Value *LE =
9930b57cec5SDimitry Andric     Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
9940b57cec5SDimitry Andric   Check = Builder.CreateAnd(GE, LE);
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
9970b57cec5SDimitry Andric                                   CGF.EmitCheckTypeDescriptor(OrigSrcType),
9980b57cec5SDimitry Andric                                   CGF.EmitCheckTypeDescriptor(DstType)};
9990b57cec5SDimitry Andric   CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
10000b57cec5SDimitry Andric                 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
10010b57cec5SDimitry Andric }
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
10040b57cec5SDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
10050b57cec5SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
10060b57cec5SDimitry Andric                  std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)10070b57cec5SDimitry Andric EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
10080b57cec5SDimitry Andric                                  QualType DstType, CGBuilderTy &Builder) {
10090b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
10100b57cec5SDimitry Andric   llvm::Type *DstTy = Dst->getType();
10110b57cec5SDimitry Andric   (void)DstTy; // Only used in assert()
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric   // This should be truncation of integral types.
10140b57cec5SDimitry Andric   assert(Src != Dst);
10150b57cec5SDimitry Andric   assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
10160b57cec5SDimitry Andric   assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
10170b57cec5SDimitry Andric          "non-integer llvm type");
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
10200b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
10210b57cec5SDimitry Andric 
10220b57cec5SDimitry Andric   // If both (src and dst) types are unsigned, then it's an unsigned truncation.
10230b57cec5SDimitry Andric   // Else, it is a signed truncation.
10240b57cec5SDimitry Andric   ScalarExprEmitter::ImplicitConversionCheckKind Kind;
10250b57cec5SDimitry Andric   SanitizerMask Mask;
10260b57cec5SDimitry Andric   if (!SrcSigned && !DstSigned) {
10270b57cec5SDimitry Andric     Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
10280b57cec5SDimitry Andric     Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
10290b57cec5SDimitry Andric   } else {
10300b57cec5SDimitry Andric     Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
10310b57cec5SDimitry Andric     Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
10320b57cec5SDimitry Andric   }
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric   llvm::Value *Check = nullptr;
10350b57cec5SDimitry Andric   // 1. Extend the truncated value back to the same width as the Src.
10360b57cec5SDimitry Andric   Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext");
10370b57cec5SDimitry Andric   // 2. Equality-compare with the original source value
10380b57cec5SDimitry Andric   Check = Builder.CreateICmpEQ(Check, Src, "truncheck");
10390b57cec5SDimitry Andric   // If the comparison result is 'i1 false', then the truncation was lossy.
10400b57cec5SDimitry Andric   return std::make_pair(Kind, std::make_pair(Check, Mask));
10410b57cec5SDimitry Andric }
10420b57cec5SDimitry Andric 
PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType,QualType DstType)1043480093f4SDimitry Andric static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
1044480093f4SDimitry Andric     QualType SrcType, QualType DstType) {
1045480093f4SDimitry Andric   return SrcType->isIntegerType() && DstType->isIntegerType();
1046480093f4SDimitry Andric }
1047480093f4SDimitry Andric 
EmitIntegerTruncationCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)10480b57cec5SDimitry Andric void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
10490b57cec5SDimitry Andric                                                    Value *Dst, QualType DstType,
10500b57cec5SDimitry Andric                                                    SourceLocation Loc) {
10510b57cec5SDimitry Andric   if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation))
10520b57cec5SDimitry Andric     return;
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   // We only care about int->int conversions here.
10550b57cec5SDimitry Andric   // We ignore conversions to/from pointer and/or bool.
1056480093f4SDimitry Andric   if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1057480093f4SDimitry Andric                                                                        DstType))
10580b57cec5SDimitry Andric     return;
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   unsigned SrcBits = Src->getType()->getScalarSizeInBits();
10610b57cec5SDimitry Andric   unsigned DstBits = Dst->getType()->getScalarSizeInBits();
10620b57cec5SDimitry Andric   // This must be truncation. Else we do not care.
10630b57cec5SDimitry Andric   if (SrcBits <= DstBits)
10640b57cec5SDimitry Andric     return;
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric   assert(!DstType->isBooleanType() && "we should not get here with booleans.");
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric   // If the integer sign change sanitizer is enabled,
10690b57cec5SDimitry Andric   // and we are truncating from larger unsigned type to smaller signed type,
10700b57cec5SDimitry Andric   // let that next sanitizer deal with it.
10710b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
10720b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
10730b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) &&
10740b57cec5SDimitry Andric       (!SrcSigned && DstSigned))
10750b57cec5SDimitry Andric     return;
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
10800b57cec5SDimitry Andric             std::pair<llvm::Value *, SanitizerMask>>
10810b57cec5SDimitry Andric       Check =
10820b57cec5SDimitry Andric           EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
10830b57cec5SDimitry Andric   // If the comparison result is 'i1 false', then the truncation was lossy.
10840b57cec5SDimitry Andric 
10850b57cec5SDimitry Andric   // Do we care about this type of truncation?
10860b57cec5SDimitry Andric   if (!CGF.SanOpts.has(Check.second.second))
10870b57cec5SDimitry Andric     return;
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {
10900b57cec5SDimitry Andric       CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
10910b57cec5SDimitry Andric       CGF.EmitCheckTypeDescriptor(DstType),
10920b57cec5SDimitry Andric       llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)};
10930b57cec5SDimitry Andric   CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
10940b57cec5SDimitry Andric                 {Src, Dst});
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
10980b57cec5SDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
10990b57cec5SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
11000b57cec5SDimitry Andric                  std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)11010b57cec5SDimitry Andric EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
11020b57cec5SDimitry Andric                                  QualType DstType, CGBuilderTy &Builder) {
11030b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
11040b57cec5SDimitry Andric   llvm::Type *DstTy = Dst->getType();
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric   assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
11070b57cec5SDimitry Andric          "non-integer llvm type");
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
11100b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
11110b57cec5SDimitry Andric   (void)SrcSigned; // Only used in assert()
11120b57cec5SDimitry Andric   (void)DstSigned; // Only used in assert()
11130b57cec5SDimitry Andric   unsigned SrcBits = SrcTy->getScalarSizeInBits();
11140b57cec5SDimitry Andric   unsigned DstBits = DstTy->getScalarSizeInBits();
11150b57cec5SDimitry Andric   (void)SrcBits; // Only used in assert()
11160b57cec5SDimitry Andric   (void)DstBits; // Only used in assert()
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric   assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
11190b57cec5SDimitry Andric          "either the widths should be different, or the signednesses.");
11200b57cec5SDimitry Andric 
11210b57cec5SDimitry Andric   // NOTE: zero value is considered to be non-negative.
11220b57cec5SDimitry Andric   auto EmitIsNegativeTest = [&Builder](Value *V, QualType VType,
11230b57cec5SDimitry Andric                                        const char *Name) -> Value * {
11240b57cec5SDimitry Andric     // Is this value a signed type?
11250b57cec5SDimitry Andric     bool VSigned = VType->isSignedIntegerOrEnumerationType();
11260b57cec5SDimitry Andric     llvm::Type *VTy = V->getType();
11270b57cec5SDimitry Andric     if (!VSigned) {
11280b57cec5SDimitry Andric       // If the value is unsigned, then it is never negative.
11290b57cec5SDimitry Andric       // FIXME: can we encounter non-scalar VTy here?
11300b57cec5SDimitry Andric       return llvm::ConstantInt::getFalse(VTy->getContext());
11310b57cec5SDimitry Andric     }
11320b57cec5SDimitry Andric     // Get the zero of the same type with which we will be comparing.
11330b57cec5SDimitry Andric     llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
11340b57cec5SDimitry Andric     // %V.isnegative = icmp slt %V, 0
11350b57cec5SDimitry Andric     // I.e is %V *strictly* less than zero, does it have negative value?
11360b57cec5SDimitry Andric     return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
11370b57cec5SDimitry Andric                               llvm::Twine(Name) + "." + V->getName() +
11380b57cec5SDimitry Andric                                   ".negativitycheck");
11390b57cec5SDimitry Andric   };
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric   // 1. Was the old Value negative?
11420b57cec5SDimitry Andric   llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType, "src");
11430b57cec5SDimitry Andric   // 2. Is the new Value negative?
11440b57cec5SDimitry Andric   llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst");
11450b57cec5SDimitry Andric   // 3. Now, was the 'negativity status' preserved during the conversion?
11460b57cec5SDimitry Andric   //    NOTE: conversion from negative to zero is considered to change the sign.
11470b57cec5SDimitry Andric   //    (We want to get 'false' when the conversion changed the sign)
11480b57cec5SDimitry Andric   //    So we should just equality-compare the negativity statuses.
11490b57cec5SDimitry Andric   llvm::Value *Check = nullptr;
11500b57cec5SDimitry Andric   Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck");
11510b57cec5SDimitry Andric   // If the comparison result is 'false', then the conversion changed the sign.
11520b57cec5SDimitry Andric   return std::make_pair(
11530b57cec5SDimitry Andric       ScalarExprEmitter::ICCK_IntegerSignChange,
11540b57cec5SDimitry Andric       std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
11550b57cec5SDimitry Andric }
11560b57cec5SDimitry Andric 
EmitIntegerSignChangeCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)11570b57cec5SDimitry Andric void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
11580b57cec5SDimitry Andric                                                    Value *Dst, QualType DstType,
11590b57cec5SDimitry Andric                                                    SourceLocation Loc) {
11600b57cec5SDimitry Andric   if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange))
11610b57cec5SDimitry Andric     return;
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
11640b57cec5SDimitry Andric   llvm::Type *DstTy = Dst->getType();
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   // We only care about int->int conversions here.
11670b57cec5SDimitry Andric   // We ignore conversions to/from pointer and/or bool.
1168480093f4SDimitry Andric   if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1169480093f4SDimitry Andric                                                                        DstType))
11700b57cec5SDimitry Andric     return;
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
11730b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
11740b57cec5SDimitry Andric   unsigned SrcBits = SrcTy->getScalarSizeInBits();
11750b57cec5SDimitry Andric   unsigned DstBits = DstTy->getScalarSizeInBits();
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   // Now, we do not need to emit the check in *all* of the cases.
11780b57cec5SDimitry Andric   // We can avoid emitting it in some obvious cases where it would have been
11790b57cec5SDimitry Andric   // dropped by the opt passes (instcombine) always anyways.
11800b57cec5SDimitry Andric   // If it's a cast between effectively the same type, no check.
11810b57cec5SDimitry Andric   // NOTE: this is *not* equivalent to checking the canonical types.
11820b57cec5SDimitry Andric   if (SrcSigned == DstSigned && SrcBits == DstBits)
11830b57cec5SDimitry Andric     return;
11840b57cec5SDimitry Andric   // At least one of the values needs to have signed type.
11850b57cec5SDimitry Andric   // If both are unsigned, then obviously, neither of them can be negative.
11860b57cec5SDimitry Andric   if (!SrcSigned && !DstSigned)
11870b57cec5SDimitry Andric     return;
11880b57cec5SDimitry Andric   // If the conversion is to *larger* *signed* type, then no check is needed.
11890b57cec5SDimitry Andric   // Because either sign-extension happens (so the sign will remain),
11900b57cec5SDimitry Andric   // or zero-extension will happen (the sign bit will be zero.)
11910b57cec5SDimitry Andric   if ((DstBits > SrcBits) && DstSigned)
11920b57cec5SDimitry Andric     return;
11930b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
11940b57cec5SDimitry Andric       (SrcBits > DstBits) && SrcSigned) {
11950b57cec5SDimitry Andric     // If the signed integer truncation sanitizer is enabled,
11960b57cec5SDimitry Andric     // and this is a truncation from signed type, then no check is needed.
11970b57cec5SDimitry Andric     // Because here sign change check is interchangeable with truncation check.
11980b57cec5SDimitry Andric     return;
11990b57cec5SDimitry Andric   }
12000b57cec5SDimitry Andric   // That's it. We can't rule out any more cases with the data we have.
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
12050b57cec5SDimitry Andric             std::pair<llvm::Value *, SanitizerMask>>
12060b57cec5SDimitry Andric       Check;
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric   // Each of these checks needs to return 'false' when an issue was detected.
12090b57cec5SDimitry Andric   ImplicitConversionCheckKind CheckKind;
12100b57cec5SDimitry Andric   llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
12110b57cec5SDimitry Andric   // So we can 'and' all the checks together, and still get 'false',
12120b57cec5SDimitry Andric   // if at least one of the checks detected an issue.
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric   Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
12150b57cec5SDimitry Andric   CheckKind = Check.first;
12160b57cec5SDimitry Andric   Checks.emplace_back(Check.second);
12170b57cec5SDimitry Andric 
12180b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
12190b57cec5SDimitry Andric       (SrcBits > DstBits) && !SrcSigned && DstSigned) {
12200b57cec5SDimitry Andric     // If the signed integer truncation sanitizer was enabled,
12210b57cec5SDimitry Andric     // and we are truncating from larger unsigned type to smaller signed type,
12220b57cec5SDimitry Andric     // let's handle the case we skipped in that check.
12230b57cec5SDimitry Andric     Check =
12240b57cec5SDimitry Andric         EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
12250b57cec5SDimitry Andric     CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
12260b57cec5SDimitry Andric     Checks.emplace_back(Check.second);
12270b57cec5SDimitry Andric     // If the comparison result is 'i1 false', then the truncation was lossy.
12280b57cec5SDimitry Andric   }
12290b57cec5SDimitry Andric 
12300b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {
12310b57cec5SDimitry Andric       CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
12320b57cec5SDimitry Andric       CGF.EmitCheckTypeDescriptor(DstType),
12330b57cec5SDimitry Andric       llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)};
12340b57cec5SDimitry Andric   // EmitCheck() will 'and' all the checks together.
12350b57cec5SDimitry Andric   CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
12360b57cec5SDimitry Andric                 {Src, Dst});
12370b57cec5SDimitry Andric }
12380b57cec5SDimitry Andric 
EmitScalarCast(Value * Src,QualType SrcType,QualType DstType,llvm::Type * SrcTy,llvm::Type * DstTy,ScalarConversionOpts Opts)1239fe6060f1SDimitry Andric Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
1240fe6060f1SDimitry Andric                                          QualType DstType, llvm::Type *SrcTy,
1241fe6060f1SDimitry Andric                                          llvm::Type *DstTy,
1242fe6060f1SDimitry Andric                                          ScalarConversionOpts Opts) {
1243fe6060f1SDimitry Andric   // The Element types determine the type of cast to perform.
1244fe6060f1SDimitry Andric   llvm::Type *SrcElementTy;
1245fe6060f1SDimitry Andric   llvm::Type *DstElementTy;
1246fe6060f1SDimitry Andric   QualType SrcElementType;
1247fe6060f1SDimitry Andric   QualType DstElementType;
1248fe6060f1SDimitry Andric   if (SrcType->isMatrixType() && DstType->isMatrixType()) {
1249fe6060f1SDimitry Andric     SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1250fe6060f1SDimitry Andric     DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1251fe6060f1SDimitry Andric     SrcElementType = SrcType->castAs<MatrixType>()->getElementType();
1252fe6060f1SDimitry Andric     DstElementType = DstType->castAs<MatrixType>()->getElementType();
1253fe6060f1SDimitry Andric   } else {
1254fe6060f1SDimitry Andric     assert(!SrcType->isMatrixType() && !DstType->isMatrixType() &&
1255fe6060f1SDimitry Andric            "cannot cast between matrix and non-matrix types");
1256fe6060f1SDimitry Andric     SrcElementTy = SrcTy;
1257fe6060f1SDimitry Andric     DstElementTy = DstTy;
1258fe6060f1SDimitry Andric     SrcElementType = SrcType;
1259fe6060f1SDimitry Andric     DstElementType = DstType;
1260fe6060f1SDimitry Andric   }
1261fe6060f1SDimitry Andric 
1262fe6060f1SDimitry Andric   if (isa<llvm::IntegerType>(SrcElementTy)) {
1263fe6060f1SDimitry Andric     bool InputSigned = SrcElementType->isSignedIntegerOrEnumerationType();
1264fe6060f1SDimitry Andric     if (SrcElementType->isBooleanType() && Opts.TreatBooleanAsSigned) {
1265fe6060f1SDimitry Andric       InputSigned = true;
1266fe6060f1SDimitry Andric     }
1267fe6060f1SDimitry Andric 
1268fe6060f1SDimitry Andric     if (isa<llvm::IntegerType>(DstElementTy))
1269fe6060f1SDimitry Andric       return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1270fe6060f1SDimitry Andric     if (InputSigned)
1271fe6060f1SDimitry Andric       return Builder.CreateSIToFP(Src, DstTy, "conv");
1272fe6060f1SDimitry Andric     return Builder.CreateUIToFP(Src, DstTy, "conv");
1273fe6060f1SDimitry Andric   }
1274fe6060f1SDimitry Andric 
1275fe6060f1SDimitry Andric   if (isa<llvm::IntegerType>(DstElementTy)) {
1276fe6060f1SDimitry Andric     assert(SrcElementTy->isFloatingPointTy() && "Unknown real conversion");
12770eae32dcSDimitry Andric     bool IsSigned = DstElementType->isSignedIntegerOrEnumerationType();
12780eae32dcSDimitry Andric 
12790eae32dcSDimitry Andric     // If we can't recognize overflow as undefined behavior, assume that
12800eae32dcSDimitry Andric     // overflow saturates. This protects against normal optimizations if we are
12810eae32dcSDimitry Andric     // compiling with non-standard FP semantics.
12820eae32dcSDimitry Andric     if (!CGF.CGM.getCodeGenOpts().StrictFloatCastOverflow) {
12830eae32dcSDimitry Andric       llvm::Intrinsic::ID IID =
12840eae32dcSDimitry Andric           IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
12850eae32dcSDimitry Andric       return Builder.CreateCall(CGF.CGM.getIntrinsic(IID, {DstTy, SrcTy}), Src);
12860eae32dcSDimitry Andric     }
12870eae32dcSDimitry Andric 
12880eae32dcSDimitry Andric     if (IsSigned)
1289fe6060f1SDimitry Andric       return Builder.CreateFPToSI(Src, DstTy, "conv");
1290fe6060f1SDimitry Andric     return Builder.CreateFPToUI(Src, DstTy, "conv");
1291fe6060f1SDimitry Andric   }
1292fe6060f1SDimitry Andric 
1293fe6060f1SDimitry Andric   if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1294fe6060f1SDimitry Andric     return Builder.CreateFPTrunc(Src, DstTy, "conv");
1295fe6060f1SDimitry Andric   return Builder.CreateFPExt(Src, DstTy, "conv");
1296fe6060f1SDimitry Andric }
1297fe6060f1SDimitry Andric 
12980b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
12990b57cec5SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcType,QualType DstType,SourceLocation Loc,ScalarConversionOpts Opts)13000b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
13010b57cec5SDimitry Andric                                                QualType DstType,
13020b57cec5SDimitry Andric                                                SourceLocation Loc,
13030b57cec5SDimitry Andric                                                ScalarConversionOpts Opts) {
13040b57cec5SDimitry Andric   // All conversions involving fixed point types should be handled by the
13050b57cec5SDimitry Andric   // EmitFixedPoint family functions. This is done to prevent bloating up this
13060b57cec5SDimitry Andric   // function more, and although fixed point numbers are represented by
13070b57cec5SDimitry Andric   // integers, we do not want to follow any logic that assumes they should be
13080b57cec5SDimitry Andric   // treated as integers.
13090b57cec5SDimitry Andric   // TODO(leonardchan): When necessary, add another if statement checking for
13100b57cec5SDimitry Andric   // conversions to fixed point types from other types.
13110b57cec5SDimitry Andric   if (SrcType->isFixedPointType()) {
13120b57cec5SDimitry Andric     if (DstType->isBooleanType())
13130b57cec5SDimitry Andric       // It is important that we check this before checking if the dest type is
13140b57cec5SDimitry Andric       // an integer because booleans are technically integer types.
13150b57cec5SDimitry Andric       // We do not need to check the padding bit on unsigned types if unsigned
13160b57cec5SDimitry Andric       // padding is enabled because overflow into this bit is undefined
13170b57cec5SDimitry Andric       // behavior.
13180b57cec5SDimitry Andric       return Builder.CreateIsNotNull(Src, "tobool");
1319e8d8bef9SDimitry Andric     if (DstType->isFixedPointType() || DstType->isIntegerType() ||
1320e8d8bef9SDimitry Andric         DstType->isRealFloatingType())
13210b57cec5SDimitry Andric       return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric     llvm_unreachable(
13240b57cec5SDimitry Andric         "Unhandled scalar conversion from a fixed point type to another type.");
13250b57cec5SDimitry Andric   } else if (DstType->isFixedPointType()) {
1326e8d8bef9SDimitry Andric     if (SrcType->isIntegerType() || SrcType->isRealFloatingType())
13270b57cec5SDimitry Andric       // This also includes converting booleans and enums to fixed point types.
13280b57cec5SDimitry Andric       return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
13290b57cec5SDimitry Andric 
13300b57cec5SDimitry Andric     llvm_unreachable(
13310b57cec5SDimitry Andric         "Unhandled scalar conversion to a fixed point type from another type.");
13320b57cec5SDimitry Andric   }
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric   QualType NoncanonicalSrcType = SrcType;
13350b57cec5SDimitry Andric   QualType NoncanonicalDstType = DstType;
13360b57cec5SDimitry Andric 
13370b57cec5SDimitry Andric   SrcType = CGF.getContext().getCanonicalType(SrcType);
13380b57cec5SDimitry Andric   DstType = CGF.getContext().getCanonicalType(DstType);
13390b57cec5SDimitry Andric   if (SrcType == DstType) return Src;
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric   if (DstType->isVoidType()) return nullptr;
13420b57cec5SDimitry Andric 
13430b57cec5SDimitry Andric   llvm::Value *OrigSrc = Src;
13440b57cec5SDimitry Andric   QualType OrigSrcType = SrcType;
13450b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric   // Handle conversions to bool first, they are special: comparisons against 0.
13480b57cec5SDimitry Andric   if (DstType->isBooleanType())
13490b57cec5SDimitry Andric     return EmitConversionToBool(Src, SrcType);
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   llvm::Type *DstTy = ConvertType(DstType);
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric   // Cast from half through float if half isn't a native type.
13540b57cec5SDimitry Andric   if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
13550b57cec5SDimitry Andric     // Cast to FP using the intrinsic if the half type itself isn't supported.
13560b57cec5SDimitry Andric     if (DstTy->isFloatingPointTy()) {
13570b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
13580b57cec5SDimitry Andric         return Builder.CreateCall(
13590b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy),
13600b57cec5SDimitry Andric             Src);
13610b57cec5SDimitry Andric     } else {
13620b57cec5SDimitry Andric       // Cast to other types through float, using either the intrinsic or FPExt,
13630b57cec5SDimitry Andric       // depending on whether the half type itself is supported
13640b57cec5SDimitry Andric       // (as opposed to operations on half, available with NativeHalfType).
13650b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
13660b57cec5SDimitry Andric         Src = Builder.CreateCall(
13670b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
13680b57cec5SDimitry Andric                                  CGF.CGM.FloatTy),
13690b57cec5SDimitry Andric             Src);
13700b57cec5SDimitry Andric       } else {
13710b57cec5SDimitry Andric         Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
13720b57cec5SDimitry Andric       }
13730b57cec5SDimitry Andric       SrcType = CGF.getContext().FloatTy;
13740b57cec5SDimitry Andric       SrcTy = CGF.FloatTy;
13750b57cec5SDimitry Andric     }
13760b57cec5SDimitry Andric   }
13770b57cec5SDimitry Andric 
13780b57cec5SDimitry Andric   // Ignore conversions like int -> uint.
13790b57cec5SDimitry Andric   if (SrcTy == DstTy) {
13800b57cec5SDimitry Andric     if (Opts.EmitImplicitIntegerSignChangeChecks)
13810b57cec5SDimitry Andric       EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
13820b57cec5SDimitry Andric                                  NoncanonicalDstType, Loc);
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric     return Src;
13850b57cec5SDimitry Andric   }
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric   // Handle pointer conversions next: pointers can only be converted to/from
13880b57cec5SDimitry Andric   // other pointers and integers. Check for pointer types in terms of LLVM, as
13890b57cec5SDimitry Andric   // some native types (like Obj-C id) may map to a pointer type.
13900b57cec5SDimitry Andric   if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
13910b57cec5SDimitry Andric     // The source value may be an integer, or a pointer.
13920b57cec5SDimitry Andric     if (isa<llvm::PointerType>(SrcTy))
13930b57cec5SDimitry Andric       return Builder.CreateBitCast(Src, DstTy, "conv");
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric     assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
13960b57cec5SDimitry Andric     // First, convert to the correct width so that we control the kind of
13970b57cec5SDimitry Andric     // extension.
13980b57cec5SDimitry Andric     llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT);
13990b57cec5SDimitry Andric     bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
14000b57cec5SDimitry Andric     llvm::Value* IntResult =
14010b57cec5SDimitry Andric         Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
14020b57cec5SDimitry Andric     // Then, cast to pointer.
14030b57cec5SDimitry Andric     return Builder.CreateIntToPtr(IntResult, DstTy, "conv");
14040b57cec5SDimitry Andric   }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric   if (isa<llvm::PointerType>(SrcTy)) {
14070b57cec5SDimitry Andric     // Must be an ptr to int cast.
14080b57cec5SDimitry Andric     assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
14090b57cec5SDimitry Andric     return Builder.CreatePtrToInt(Src, DstTy, "conv");
14100b57cec5SDimitry Andric   }
14110b57cec5SDimitry Andric 
14120b57cec5SDimitry Andric   // A scalar can be splatted to an extended vector of the same element type
14130b57cec5SDimitry Andric   if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
14140b57cec5SDimitry Andric     // Sema should add casts to make sure that the source expression's type is
14150b57cec5SDimitry Andric     // the same as the vector's element type (sans qualifiers)
14160b57cec5SDimitry Andric     assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
14170b57cec5SDimitry Andric                SrcType.getTypePtr() &&
14180b57cec5SDimitry Andric            "Splatted expr doesn't match with vector element type?");
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric     // Splat the element across to all elements
1421e8d8bef9SDimitry Andric     unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
14220b57cec5SDimitry Andric     return Builder.CreateVectorSplat(NumElements, Src, "splat");
14230b57cec5SDimitry Andric   }
14240b57cec5SDimitry Andric 
1425fe6060f1SDimitry Andric   if (SrcType->isMatrixType() && DstType->isMatrixType())
1426fe6060f1SDimitry Andric     return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1427fe6060f1SDimitry Andric 
14280b57cec5SDimitry Andric   if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
14290b57cec5SDimitry Andric     // Allow bitcast from vector to integer/fp of the same size.
143081ad6265SDimitry Andric     llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
143181ad6265SDimitry Andric     llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
14320b57cec5SDimitry Andric     if (SrcSize == DstSize)
14330b57cec5SDimitry Andric       return Builder.CreateBitCast(Src, DstTy, "conv");
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric     // Conversions between vectors of different sizes are not allowed except
14360b57cec5SDimitry Andric     // when vectors of half are involved. Operations on storage-only half
14370b57cec5SDimitry Andric     // vectors require promoting half vector operands to float vectors and
14380b57cec5SDimitry Andric     // truncating the result, which is either an int or float vector, to a
14390b57cec5SDimitry Andric     // short or half vector.
14400b57cec5SDimitry Andric 
14410b57cec5SDimitry Andric     // Source and destination are both expected to be vectors.
14425ffd83dbSDimitry Andric     llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
14435ffd83dbSDimitry Andric     llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
14440b57cec5SDimitry Andric     (void)DstElementTy;
14450b57cec5SDimitry Andric 
14460b57cec5SDimitry Andric     assert(((SrcElementTy->isIntegerTy() &&
14470b57cec5SDimitry Andric              DstElementTy->isIntegerTy()) ||
14480b57cec5SDimitry Andric             (SrcElementTy->isFloatingPointTy() &&
14490b57cec5SDimitry Andric              DstElementTy->isFloatingPointTy())) &&
14500b57cec5SDimitry Andric            "unexpected conversion between a floating-point vector and an "
14510b57cec5SDimitry Andric            "integer vector");
14520b57cec5SDimitry Andric 
14530b57cec5SDimitry Andric     // Truncate an i32 vector to an i16 vector.
14540b57cec5SDimitry Andric     if (SrcElementTy->isIntegerTy())
14550b57cec5SDimitry Andric       return Builder.CreateIntCast(Src, DstTy, false, "conv");
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric     // Truncate a float vector to a half vector.
14580b57cec5SDimitry Andric     if (SrcSize > DstSize)
14590b57cec5SDimitry Andric       return Builder.CreateFPTrunc(Src, DstTy, "conv");
14600b57cec5SDimitry Andric 
14610b57cec5SDimitry Andric     // Promote a half vector to a float vector.
14620b57cec5SDimitry Andric     return Builder.CreateFPExt(Src, DstTy, "conv");
14630b57cec5SDimitry Andric   }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric   // Finally, we have the arithmetic types: real int/float.
14660b57cec5SDimitry Andric   Value *Res = nullptr;
14670b57cec5SDimitry Andric   llvm::Type *ResTy = DstTy;
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric   // An overflowing conversion has undefined behavior if either the source type
14700b57cec5SDimitry Andric   // or the destination type is a floating-point type. However, we consider the
14710b57cec5SDimitry Andric   // range of representable values for all floating-point types to be
14720b57cec5SDimitry Andric   // [-inf,+inf], so no overflow can ever happen when the destination type is a
14730b57cec5SDimitry Andric   // floating-point type.
14740b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
14750b57cec5SDimitry Andric       OrigSrcType->isFloatingType())
14760b57cec5SDimitry Andric     EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
14770b57cec5SDimitry Andric                              Loc);
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   // Cast to half through float if half isn't a native type.
14800b57cec5SDimitry Andric   if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
14810b57cec5SDimitry Andric     // Make sure we cast in a single step if from another FP type.
14820b57cec5SDimitry Andric     if (SrcTy->isFloatingPointTy()) {
14830b57cec5SDimitry Andric       // Use the intrinsic if the half type itself isn't supported
14840b57cec5SDimitry Andric       // (as opposed to operations on half, available with NativeHalfType).
14850b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
14860b57cec5SDimitry Andric         return Builder.CreateCall(
14870b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src);
14880b57cec5SDimitry Andric       // If the half type is supported, just use an fptrunc.
14890b57cec5SDimitry Andric       return Builder.CreateFPTrunc(Src, DstTy);
14900b57cec5SDimitry Andric     }
14910b57cec5SDimitry Andric     DstTy = CGF.FloatTy;
14920b57cec5SDimitry Andric   }
14930b57cec5SDimitry Andric 
1494fe6060f1SDimitry Andric   Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
14950b57cec5SDimitry Andric 
14960b57cec5SDimitry Andric   if (DstTy != ResTy) {
14970b57cec5SDimitry Andric     if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
14980b57cec5SDimitry Andric       assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion");
14990b57cec5SDimitry Andric       Res = Builder.CreateCall(
15000b57cec5SDimitry Andric         CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy),
15010b57cec5SDimitry Andric         Res);
15020b57cec5SDimitry Andric     } else {
15030b57cec5SDimitry Andric       Res = Builder.CreateFPTrunc(Res, ResTy, "conv");
15040b57cec5SDimitry Andric     }
15050b57cec5SDimitry Andric   }
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric   if (Opts.EmitImplicitIntegerTruncationChecks)
15080b57cec5SDimitry Andric     EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
15090b57cec5SDimitry Andric                                NoncanonicalDstType, Loc);
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric   if (Opts.EmitImplicitIntegerSignChangeChecks)
15120b57cec5SDimitry Andric     EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
15130b57cec5SDimitry Andric                                NoncanonicalDstType, Loc);
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric   return Res;
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric 
EmitFixedPointConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)15180b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
15190b57cec5SDimitry Andric                                                    QualType DstTy,
15200b57cec5SDimitry Andric                                                    SourceLocation Loc) {
1521e8d8bef9SDimitry Andric   llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1522e8d8bef9SDimitry Andric   llvm::Value *Result;
1523e8d8bef9SDimitry Andric   if (SrcTy->isRealFloatingType())
1524e8d8bef9SDimitry Andric     Result = FPBuilder.CreateFloatingToFixed(Src,
1525e8d8bef9SDimitry Andric         CGF.getContext().getFixedPointSemantics(DstTy));
1526e8d8bef9SDimitry Andric   else if (DstTy->isRealFloatingType())
1527e8d8bef9SDimitry Andric     Result = FPBuilder.CreateFixedToFloating(Src,
1528e8d8bef9SDimitry Andric         CGF.getContext().getFixedPointSemantics(SrcTy),
1529e8d8bef9SDimitry Andric         ConvertType(DstTy));
1530e8d8bef9SDimitry Andric   else {
1531e8d8bef9SDimitry Andric     auto SrcFPSema = CGF.getContext().getFixedPointSemantics(SrcTy);
1532e8d8bef9SDimitry Andric     auto DstFPSema = CGF.getContext().getFixedPointSemantics(DstTy);
15330b57cec5SDimitry Andric 
1534e8d8bef9SDimitry Andric     if (DstTy->isIntegerType())
1535e8d8bef9SDimitry Andric       Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1536e8d8bef9SDimitry Andric                                               DstFPSema.getWidth(),
1537e8d8bef9SDimitry Andric                                               DstFPSema.isSigned());
1538e8d8bef9SDimitry Andric     else if (SrcTy->isIntegerType())
1539e8d8bef9SDimitry Andric       Result =  FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1540e8d8bef9SDimitry Andric                                                DstFPSema);
1541e8d8bef9SDimitry Andric     else
1542e8d8bef9SDimitry Andric       Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
15430b57cec5SDimitry Andric   }
15440b57cec5SDimitry Andric   return Result;
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
15480b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)15490b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitComplexToScalarConversion(
15500b57cec5SDimitry Andric     CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
15510b57cec5SDimitry Andric     SourceLocation Loc) {
15520b57cec5SDimitry Andric   // Get the source element type.
15530b57cec5SDimitry Andric   SrcTy = SrcTy->castAs<ComplexType>()->getElementType();
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric   // Handle conversions to bool first, they are special: comparisons against 0.
15560b57cec5SDimitry Andric   if (DstTy->isBooleanType()) {
15570b57cec5SDimitry Andric     //  Complex != 0  -> (Real != 0) | (Imag != 0)
15580b57cec5SDimitry Andric     Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
15590b57cec5SDimitry Andric     Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
15600b57cec5SDimitry Andric     return Builder.CreateOr(Src.first, Src.second, "tobool");
15610b57cec5SDimitry Andric   }
15620b57cec5SDimitry Andric 
15630b57cec5SDimitry Andric   // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
15640b57cec5SDimitry Andric   // the imaginary part of the complex value is discarded and the value of the
15650b57cec5SDimitry Andric   // real part is converted according to the conversion rules for the
15660b57cec5SDimitry Andric   // corresponding real type.
15670b57cec5SDimitry Andric   return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
15680b57cec5SDimitry Andric }
15690b57cec5SDimitry Andric 
EmitNullValue(QualType Ty)15700b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
15710b57cec5SDimitry Andric   return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty);
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric /// Emit a sanitization check for the given "binary" operation (which
15750b57cec5SDimitry Andric /// might actually be a unary increment which has been lowered to a binary
15760b57cec5SDimitry Andric /// operation). The check passes if all values in \p Checks (which are \c i1),
15770b57cec5SDimitry Andric /// are \c true.
EmitBinOpCheck(ArrayRef<std::pair<Value *,SanitizerMask>> Checks,const BinOpInfo & Info)15780b57cec5SDimitry Andric void ScalarExprEmitter::EmitBinOpCheck(
15790b57cec5SDimitry Andric     ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {
15800b57cec5SDimitry Andric   assert(CGF.IsSanitizerScope);
15810b57cec5SDimitry Andric   SanitizerHandler Check;
15820b57cec5SDimitry Andric   SmallVector<llvm::Constant *, 4> StaticData;
15830b57cec5SDimitry Andric   SmallVector<llvm::Value *, 2> DynamicData;
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric   BinaryOperatorKind Opcode = Info.Opcode;
15860b57cec5SDimitry Andric   if (BinaryOperator::isCompoundAssignmentOp(Opcode))
15870b57cec5SDimitry Andric     Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode);
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric   StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc()));
15900b57cec5SDimitry Andric   const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
15910b57cec5SDimitry Andric   if (UO && UO->getOpcode() == UO_Minus) {
15920b57cec5SDimitry Andric     Check = SanitizerHandler::NegateOverflow;
15930b57cec5SDimitry Andric     StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
15940b57cec5SDimitry Andric     DynamicData.push_back(Info.RHS);
15950b57cec5SDimitry Andric   } else {
15960b57cec5SDimitry Andric     if (BinaryOperator::isShiftOp(Opcode)) {
15970b57cec5SDimitry Andric       // Shift LHS negative or too large, or RHS out of bounds.
15980b57cec5SDimitry Andric       Check = SanitizerHandler::ShiftOutOfBounds;
15990b57cec5SDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(Info.E);
16000b57cec5SDimitry Andric       StaticData.push_back(
16010b57cec5SDimitry Andric         CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType()));
16020b57cec5SDimitry Andric       StaticData.push_back(
16030b57cec5SDimitry Andric         CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType()));
16040b57cec5SDimitry Andric     } else if (Opcode == BO_Div || Opcode == BO_Rem) {
16050b57cec5SDimitry Andric       // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1).
16060b57cec5SDimitry Andric       Check = SanitizerHandler::DivremOverflow;
16070b57cec5SDimitry Andric       StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
16080b57cec5SDimitry Andric     } else {
16090b57cec5SDimitry Andric       // Arithmetic overflow (+, -, *).
16100b57cec5SDimitry Andric       switch (Opcode) {
16110b57cec5SDimitry Andric       case BO_Add: Check = SanitizerHandler::AddOverflow; break;
16120b57cec5SDimitry Andric       case BO_Sub: Check = SanitizerHandler::SubOverflow; break;
16130b57cec5SDimitry Andric       case BO_Mul: Check = SanitizerHandler::MulOverflow; break;
16140b57cec5SDimitry Andric       default: llvm_unreachable("unexpected opcode for bin op check");
16150b57cec5SDimitry Andric       }
16160b57cec5SDimitry Andric       StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
16170b57cec5SDimitry Andric     }
16180b57cec5SDimitry Andric     DynamicData.push_back(Info.LHS);
16190b57cec5SDimitry Andric     DynamicData.push_back(Info.RHS);
16200b57cec5SDimitry Andric   }
16210b57cec5SDimitry Andric 
16220b57cec5SDimitry Andric   CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
16230b57cec5SDimitry Andric }
16240b57cec5SDimitry Andric 
16250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16260b57cec5SDimitry Andric //                            Visitor Methods
16270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16280b57cec5SDimitry Andric 
VisitExpr(Expr * E)16290b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitExpr(Expr *E) {
16300b57cec5SDimitry Andric   CGF.ErrorUnsupported(E, "scalar expression");
16310b57cec5SDimitry Andric   if (E->getType()->isVoidType())
16320b57cec5SDimitry Andric     return nullptr;
16330b57cec5SDimitry Andric   return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
16340b57cec5SDimitry Andric }
16350b57cec5SDimitry Andric 
1636fe6060f1SDimitry Andric Value *
VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr * E)1637fe6060f1SDimitry Andric ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1638fe6060f1SDimitry Andric   ASTContext &Context = CGF.getContext();
1639bdd1243dSDimitry Andric   unsigned AddrSpace =
1640bdd1243dSDimitry Andric       Context.getTargetAddressSpace(CGF.CGM.GetGlobalConstantAddressSpace());
1641fe6060f1SDimitry Andric   llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1642bdd1243dSDimitry Andric       E->ComputeName(Context), "__usn_str", AddrSpace);
1643fe6060f1SDimitry Andric 
1644bdd1243dSDimitry Andric   llvm::Type *ExprTy = ConvertType(E->getType());
1645bdd1243dSDimitry Andric   return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1646bdd1243dSDimitry Andric                                                      "usn_addr_cast");
1647fe6060f1SDimitry Andric }
1648fe6060f1SDimitry Andric 
VisitShuffleVectorExpr(ShuffleVectorExpr * E)16490b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
16500b57cec5SDimitry Andric   // Vector Mask Case
16510b57cec5SDimitry Andric   if (E->getNumSubExprs() == 2) {
16520b57cec5SDimitry Andric     Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));
16530b57cec5SDimitry Andric     Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));
16540b57cec5SDimitry Andric     Value *Mask;
16550b57cec5SDimitry Andric 
1656e8d8bef9SDimitry Andric     auto *LTy = cast<llvm::FixedVectorType>(LHS->getType());
16570b57cec5SDimitry Andric     unsigned LHSElts = LTy->getNumElements();
16580b57cec5SDimitry Andric 
16590b57cec5SDimitry Andric     Mask = RHS;
16600b57cec5SDimitry Andric 
1661e8d8bef9SDimitry Andric     auto *MTy = cast<llvm::FixedVectorType>(Mask->getType());
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric     // Mask off the high bits of each shuffle index.
16640b57cec5SDimitry Andric     Value *MaskBits =
16650b57cec5SDimitry Andric         llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
16660b57cec5SDimitry Andric     Mask = Builder.CreateAnd(Mask, MaskBits, "mask");
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric     // newv = undef
16690b57cec5SDimitry Andric     // mask = mask & maskbits
16700b57cec5SDimitry Andric     // for each elt
16710b57cec5SDimitry Andric     //   n = extract mask i
16720b57cec5SDimitry Andric     //   x = extract val n
16730b57cec5SDimitry Andric     //   newv = insert newv, x, i
16745ffd83dbSDimitry Andric     auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
16750b57cec5SDimitry Andric                                            MTy->getNumElements());
1676bdd1243dSDimitry Andric     Value* NewV = llvm::PoisonValue::get(RTy);
16770b57cec5SDimitry Andric     for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
16780b57cec5SDimitry Andric       Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
16790b57cec5SDimitry Andric       Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
16800b57cec5SDimitry Andric 
16810b57cec5SDimitry Andric       Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
16820b57cec5SDimitry Andric       NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
16830b57cec5SDimitry Andric     }
16840b57cec5SDimitry Andric     return NewV;
16850b57cec5SDimitry Andric   }
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric   Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
16880b57cec5SDimitry Andric   Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
16890b57cec5SDimitry Andric 
16905ffd83dbSDimitry Andric   SmallVector<int, 32> Indices;
16910b57cec5SDimitry Andric   for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
16920b57cec5SDimitry Andric     llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
16930b57cec5SDimitry Andric     // Check for -1 and output it as undef in the IR.
1694349cc55cSDimitry Andric     if (Idx.isSigned() && Idx.isAllOnes())
16955ffd83dbSDimitry Andric       Indices.push_back(-1);
16960b57cec5SDimitry Andric     else
16975ffd83dbSDimitry Andric       Indices.push_back(Idx.getZExtValue());
16980b57cec5SDimitry Andric   }
16990b57cec5SDimitry Andric 
17005ffd83dbSDimitry Andric   return Builder.CreateShuffleVector(V1, V2, Indices, "shuffle");
17010b57cec5SDimitry Andric }
17020b57cec5SDimitry Andric 
VisitConvertVectorExpr(ConvertVectorExpr * E)17030b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
17040b57cec5SDimitry Andric   QualType SrcType = E->getSrcExpr()->getType(),
17050b57cec5SDimitry Andric            DstType = E->getType();
17060b57cec5SDimitry Andric 
17070b57cec5SDimitry Andric   Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr());
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric   SrcType = CGF.getContext().getCanonicalType(SrcType);
17100b57cec5SDimitry Andric   DstType = CGF.getContext().getCanonicalType(DstType);
17110b57cec5SDimitry Andric   if (SrcType == DstType) return Src;
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric   assert(SrcType->isVectorType() &&
17140b57cec5SDimitry Andric          "ConvertVector source type must be a vector");
17150b57cec5SDimitry Andric   assert(DstType->isVectorType() &&
17160b57cec5SDimitry Andric          "ConvertVector destination type must be a vector");
17170b57cec5SDimitry Andric 
17180b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
17190b57cec5SDimitry Andric   llvm::Type *DstTy = ConvertType(DstType);
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric   // Ignore conversions like int -> uint.
17220b57cec5SDimitry Andric   if (SrcTy == DstTy)
17230b57cec5SDimitry Andric     return Src;
17240b57cec5SDimitry Andric 
1725a7dea167SDimitry Andric   QualType SrcEltType = SrcType->castAs<VectorType>()->getElementType(),
1726a7dea167SDimitry Andric            DstEltType = DstType->castAs<VectorType>()->getElementType();
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric   assert(SrcTy->isVectorTy() &&
17290b57cec5SDimitry Andric          "ConvertVector source IR type must be a vector");
17300b57cec5SDimitry Andric   assert(DstTy->isVectorTy() &&
17310b57cec5SDimitry Andric          "ConvertVector destination IR type must be a vector");
17320b57cec5SDimitry Andric 
17335ffd83dbSDimitry Andric   llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
17345ffd83dbSDimitry Andric              *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
17350b57cec5SDimitry Andric 
17360b57cec5SDimitry Andric   if (DstEltType->isBooleanType()) {
17370b57cec5SDimitry Andric     assert((SrcEltTy->isFloatingPointTy() ||
17380b57cec5SDimitry Andric             isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion");
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
17410b57cec5SDimitry Andric     if (SrcEltTy->isFloatingPointTy()) {
17420b57cec5SDimitry Andric       return Builder.CreateFCmpUNE(Src, Zero, "tobool");
17430b57cec5SDimitry Andric     } else {
17440b57cec5SDimitry Andric       return Builder.CreateICmpNE(Src, Zero, "tobool");
17450b57cec5SDimitry Andric     }
17460b57cec5SDimitry Andric   }
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric   // We have the arithmetic types: real int/float.
17490b57cec5SDimitry Andric   Value *Res = nullptr;
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric   if (isa<llvm::IntegerType>(SrcEltTy)) {
17520b57cec5SDimitry Andric     bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType();
17530b57cec5SDimitry Andric     if (isa<llvm::IntegerType>(DstEltTy))
17540b57cec5SDimitry Andric       Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
17550b57cec5SDimitry Andric     else if (InputSigned)
17560b57cec5SDimitry Andric       Res = Builder.CreateSIToFP(Src, DstTy, "conv");
17570b57cec5SDimitry Andric     else
17580b57cec5SDimitry Andric       Res = Builder.CreateUIToFP(Src, DstTy, "conv");
17590b57cec5SDimitry Andric   } else if (isa<llvm::IntegerType>(DstEltTy)) {
17600b57cec5SDimitry Andric     assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion");
17610b57cec5SDimitry Andric     if (DstEltType->isSignedIntegerOrEnumerationType())
17620b57cec5SDimitry Andric       Res = Builder.CreateFPToSI(Src, DstTy, "conv");
17630b57cec5SDimitry Andric     else
17640b57cec5SDimitry Andric       Res = Builder.CreateFPToUI(Src, DstTy, "conv");
17650b57cec5SDimitry Andric   } else {
17660b57cec5SDimitry Andric     assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
17670b57cec5SDimitry Andric            "Unknown real conversion");
17680b57cec5SDimitry Andric     if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
17690b57cec5SDimitry Andric       Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
17700b57cec5SDimitry Andric     else
17710b57cec5SDimitry Andric       Res = Builder.CreateFPExt(Src, DstTy, "conv");
17720b57cec5SDimitry Andric   }
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric   return Res;
17750b57cec5SDimitry Andric }
17760b57cec5SDimitry Andric 
VisitMemberExpr(MemberExpr * E)17770b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
17780b57cec5SDimitry Andric   if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) {
17790b57cec5SDimitry Andric     CGF.EmitIgnoredExpr(E->getBase());
17800b57cec5SDimitry Andric     return CGF.emitScalarConstant(Constant, E);
17810b57cec5SDimitry Andric   } else {
17820b57cec5SDimitry Andric     Expr::EvalResult Result;
17830b57cec5SDimitry Andric     if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) {
17840b57cec5SDimitry Andric       llvm::APSInt Value = Result.Val.getInt();
17850b57cec5SDimitry Andric       CGF.EmitIgnoredExpr(E->getBase());
17860b57cec5SDimitry Andric       return Builder.getInt(Value);
17870b57cec5SDimitry Andric     }
17880b57cec5SDimitry Andric   }
17890b57cec5SDimitry Andric 
17900b57cec5SDimitry Andric   return EmitLoadOfLValue(E);
17910b57cec5SDimitry Andric }
17920b57cec5SDimitry Andric 
VisitArraySubscriptExpr(ArraySubscriptExpr * E)17930b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
17940b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   // Emit subscript expressions in rvalue context's.  For most cases, this just
17970b57cec5SDimitry Andric   // loads the lvalue formed by the subscript expr.  However, we have to be
17980b57cec5SDimitry Andric   // careful, because the base of a vector subscript is occasionally an rvalue,
17990b57cec5SDimitry Andric   // so we can't get it as an lvalue.
180081ad6265SDimitry Andric   if (!E->getBase()->getType()->isVectorType() &&
1801c9157d92SDimitry Andric       !E->getBase()->getType()->isSveVLSBuiltinType())
18020b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
18030b57cec5SDimitry Andric 
18040b57cec5SDimitry Andric   // Handle the vector case.  The base must be a vector, the index must be an
18050b57cec5SDimitry Andric   // integer value.
18060b57cec5SDimitry Andric   Value *Base = Visit(E->getBase());
18070b57cec5SDimitry Andric   Value *Idx  = Visit(E->getIdx());
18080b57cec5SDimitry Andric   QualType IdxTy = E->getIdx()->getType();
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
18110b57cec5SDimitry Andric     CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
18120b57cec5SDimitry Andric 
18130b57cec5SDimitry Andric   return Builder.CreateExtractElement(Base, Idx, "vecext");
18140b57cec5SDimitry Andric }
18150b57cec5SDimitry Andric 
VisitMatrixSubscriptExpr(MatrixSubscriptExpr * E)18165ffd83dbSDimitry Andric Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
18175ffd83dbSDimitry Andric   TestAndClearIgnoreResultAssign();
18185ffd83dbSDimitry Andric 
18195ffd83dbSDimitry Andric   // Handle the vector case.  The base must be a vector, the index must be an
18205ffd83dbSDimitry Andric   // integer value.
18215ffd83dbSDimitry Andric   Value *RowIdx = Visit(E->getRowIdx());
18225ffd83dbSDimitry Andric   Value *ColumnIdx = Visit(E->getColumnIdx());
1823349cc55cSDimitry Andric 
1824349cc55cSDimitry Andric   const auto *MatrixTy = E->getBase()->getType()->castAs<ConstantMatrixType>();
1825349cc55cSDimitry Andric   unsigned NumRows = MatrixTy->getNumRows();
182681ad6265SDimitry Andric   llvm::MatrixBuilder MB(Builder);
1827349cc55cSDimitry Andric   Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
1828349cc55cSDimitry Andric   if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0)
1829349cc55cSDimitry Andric     MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
1830349cc55cSDimitry Andric 
18315ffd83dbSDimitry Andric   Value *Matrix = Visit(E->getBase());
18325ffd83dbSDimitry Andric 
18335ffd83dbSDimitry Andric   // TODO: Should we emit bounds checks with SanitizerKind::ArrayBounds?
1834349cc55cSDimitry Andric   return Builder.CreateExtractElement(Matrix, Idx, "matrixext");
18350b57cec5SDimitry Andric }
18360b57cec5SDimitry Andric 
getMaskElt(llvm::ShuffleVectorInst * SVI,unsigned Idx,unsigned Off)18375ffd83dbSDimitry Andric static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
18385ffd83dbSDimitry Andric                       unsigned Off) {
18395ffd83dbSDimitry Andric   int MV = SVI->getMaskValue(Idx);
18405ffd83dbSDimitry Andric   if (MV == -1)
18415ffd83dbSDimitry Andric     return -1;
18425ffd83dbSDimitry Andric   return Off + MV;
18430b57cec5SDimitry Andric }
18445ffd83dbSDimitry Andric 
getAsInt32(llvm::ConstantInt * C,llvm::Type * I32Ty)18455ffd83dbSDimitry Andric static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {
18465ffd83dbSDimitry Andric   assert(llvm::ConstantInt::isValueValidForType(I32Ty, C->getZExtValue()) &&
18475ffd83dbSDimitry Andric          "Index operand too large for shufflevector mask!");
18485ffd83dbSDimitry Andric   return C->getZExtValue();
18490b57cec5SDimitry Andric }
18500b57cec5SDimitry Andric 
VisitInitListExpr(InitListExpr * E)18510b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
18520b57cec5SDimitry Andric   bool Ignore = TestAndClearIgnoreResultAssign();
18530b57cec5SDimitry Andric   (void)Ignore;
18540b57cec5SDimitry Andric   assert (Ignore == false && "init list ignored");
18550b57cec5SDimitry Andric   unsigned NumInitElements = E->getNumInits();
18560b57cec5SDimitry Andric 
18570b57cec5SDimitry Andric   if (E->hadArrayRangeDesignator())
18580b57cec5SDimitry Andric     CGF.ErrorUnsupported(E, "GNU array range designator extension");
18590b57cec5SDimitry Andric 
18600b57cec5SDimitry Andric   llvm::VectorType *VType =
18610b57cec5SDimitry Andric     dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric   if (!VType) {
18640b57cec5SDimitry Andric     if (NumInitElements == 0) {
18650b57cec5SDimitry Andric       // C++11 value-initialization for the scalar.
18660b57cec5SDimitry Andric       return EmitNullValue(E->getType());
18670b57cec5SDimitry Andric     }
18680b57cec5SDimitry Andric     // We have a scalar in braces. Just use the first element.
18690b57cec5SDimitry Andric     return Visit(E->getInit(0));
18700b57cec5SDimitry Andric   }
18710b57cec5SDimitry Andric 
18726bbffa1aSDimitry Andric   if (isa<llvm::ScalableVectorType>(VType)) {
18736bbffa1aSDimitry Andric     if (NumInitElements == 0) {
18746bbffa1aSDimitry Andric       // C++11 value-initialization for the vector.
18756bbffa1aSDimitry Andric       return EmitNullValue(E->getType());
18766bbffa1aSDimitry Andric     }
18776bbffa1aSDimitry Andric 
18786bbffa1aSDimitry Andric     if (NumInitElements == 1) {
18796bbffa1aSDimitry Andric       Expr *InitVector = E->getInit(0);
18806bbffa1aSDimitry Andric 
18816bbffa1aSDimitry Andric       // Initialize from another scalable vector of the same type.
18826bbffa1aSDimitry Andric       if (InitVector->getType() == E->getType())
18836bbffa1aSDimitry Andric         return Visit(InitVector);
18846bbffa1aSDimitry Andric     }
18856bbffa1aSDimitry Andric 
18866bbffa1aSDimitry Andric     llvm_unreachable("Unexpected initialization of a scalable vector!");
18876bbffa1aSDimitry Andric   }
18886bbffa1aSDimitry Andric 
1889e8d8bef9SDimitry Andric   unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
18900b57cec5SDimitry Andric 
18910b57cec5SDimitry Andric   // Loop over initializers collecting the Value for each, and remembering
18920b57cec5SDimitry Andric   // whether the source was swizzle (ExtVectorElementExpr).  This will allow
18930b57cec5SDimitry Andric   // us to fold the shuffle for the swizzle into the shuffle for the vector
18940b57cec5SDimitry Andric   // initializer, since LLVM optimizers generally do not want to touch
18950b57cec5SDimitry Andric   // shuffles.
18960b57cec5SDimitry Andric   unsigned CurIdx = 0;
1897e710425bSDimitry Andric   bool VIsPoisonShuffle = false;
1898e710425bSDimitry Andric   llvm::Value *V = llvm::PoisonValue::get(VType);
18990b57cec5SDimitry Andric   for (unsigned i = 0; i != NumInitElements; ++i) {
19000b57cec5SDimitry Andric     Expr *IE = E->getInit(i);
19010b57cec5SDimitry Andric     Value *Init = Visit(IE);
19025ffd83dbSDimitry Andric     SmallVector<int, 16> Args;
19030b57cec5SDimitry Andric 
19040b57cec5SDimitry Andric     llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
19050b57cec5SDimitry Andric 
19060b57cec5SDimitry Andric     // Handle scalar elements.  If the scalar initializer is actually one
19070b57cec5SDimitry Andric     // element of a different vector of the same width, use shuffle instead of
19080b57cec5SDimitry Andric     // extract+insert.
19090b57cec5SDimitry Andric     if (!VVT) {
19100b57cec5SDimitry Andric       if (isa<ExtVectorElementExpr>(IE)) {
19110b57cec5SDimitry Andric         llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
19120b57cec5SDimitry Andric 
1913e8d8bef9SDimitry Andric         if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
1914e8d8bef9SDimitry Andric                 ->getNumElements() == ResElts) {
19150b57cec5SDimitry Andric           llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
19160b57cec5SDimitry Andric           Value *LHS = nullptr, *RHS = nullptr;
19170b57cec5SDimitry Andric           if (CurIdx == 0) {
1918e710425bSDimitry Andric             // insert into poison -> shuffle (src, poison)
19190b57cec5SDimitry Andric             // shufflemask must use an i32
19200b57cec5SDimitry Andric             Args.push_back(getAsInt32(C, CGF.Int32Ty));
19215ffd83dbSDimitry Andric             Args.resize(ResElts, -1);
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric             LHS = EI->getVectorOperand();
19240b57cec5SDimitry Andric             RHS = V;
1925e710425bSDimitry Andric             VIsPoisonShuffle = true;
1926e710425bSDimitry Andric           } else if (VIsPoisonShuffle) {
1927e710425bSDimitry Andric             // insert into poison shuffle && size match -> shuffle (v, src)
19280b57cec5SDimitry Andric             llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
19290b57cec5SDimitry Andric             for (unsigned j = 0; j != CurIdx; ++j)
19305ffd83dbSDimitry Andric               Args.push_back(getMaskElt(SVV, j, 0));
19315ffd83dbSDimitry Andric             Args.push_back(ResElts + C->getZExtValue());
19325ffd83dbSDimitry Andric             Args.resize(ResElts, -1);
19330b57cec5SDimitry Andric 
19340b57cec5SDimitry Andric             LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
19350b57cec5SDimitry Andric             RHS = EI->getVectorOperand();
1936e710425bSDimitry Andric             VIsPoisonShuffle = false;
19370b57cec5SDimitry Andric           }
19380b57cec5SDimitry Andric           if (!Args.empty()) {
19395ffd83dbSDimitry Andric             V = Builder.CreateShuffleVector(LHS, RHS, Args);
19400b57cec5SDimitry Andric             ++CurIdx;
19410b57cec5SDimitry Andric             continue;
19420b57cec5SDimitry Andric           }
19430b57cec5SDimitry Andric         }
19440b57cec5SDimitry Andric       }
19450b57cec5SDimitry Andric       V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
19460b57cec5SDimitry Andric                                       "vecinit");
1947e710425bSDimitry Andric       VIsPoisonShuffle = false;
19480b57cec5SDimitry Andric       ++CurIdx;
19490b57cec5SDimitry Andric       continue;
19500b57cec5SDimitry Andric     }
19510b57cec5SDimitry Andric 
1952e8d8bef9SDimitry Andric     unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric     // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's
19550b57cec5SDimitry Andric     // input is the same width as the vector being constructed, generate an
19560b57cec5SDimitry Andric     // optimized shuffle of the swizzle input into the result.
19570b57cec5SDimitry Andric     unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
19580b57cec5SDimitry Andric     if (isa<ExtVectorElementExpr>(IE)) {
19590b57cec5SDimitry Andric       llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
19600b57cec5SDimitry Andric       Value *SVOp = SVI->getOperand(0);
1961e8d8bef9SDimitry Andric       auto *OpTy = cast<llvm::FixedVectorType>(SVOp->getType());
19620b57cec5SDimitry Andric 
19630b57cec5SDimitry Andric       if (OpTy->getNumElements() == ResElts) {
19640b57cec5SDimitry Andric         for (unsigned j = 0; j != CurIdx; ++j) {
1965e710425bSDimitry Andric           // If the current vector initializer is a shuffle with poison, merge
19660b57cec5SDimitry Andric           // this shuffle directly into it.
1967e710425bSDimitry Andric           if (VIsPoisonShuffle) {
19685ffd83dbSDimitry Andric             Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0));
19690b57cec5SDimitry Andric           } else {
19705ffd83dbSDimitry Andric             Args.push_back(j);
19710b57cec5SDimitry Andric           }
19720b57cec5SDimitry Andric         }
19730b57cec5SDimitry Andric         for (unsigned j = 0, je = InitElts; j != je; ++j)
19745ffd83dbSDimitry Andric           Args.push_back(getMaskElt(SVI, j, Offset));
19755ffd83dbSDimitry Andric         Args.resize(ResElts, -1);
19760b57cec5SDimitry Andric 
1977e710425bSDimitry Andric         if (VIsPoisonShuffle)
19780b57cec5SDimitry Andric           V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
19790b57cec5SDimitry Andric 
19800b57cec5SDimitry Andric         Init = SVOp;
19810b57cec5SDimitry Andric       }
19820b57cec5SDimitry Andric     }
19830b57cec5SDimitry Andric 
19840b57cec5SDimitry Andric     // Extend init to result vector length, and then shuffle its contribution
19850b57cec5SDimitry Andric     // to the vector initializer into V.
19860b57cec5SDimitry Andric     if (Args.empty()) {
19870b57cec5SDimitry Andric       for (unsigned j = 0; j != InitElts; ++j)
19885ffd83dbSDimitry Andric         Args.push_back(j);
19895ffd83dbSDimitry Andric       Args.resize(ResElts, -1);
1990e8d8bef9SDimitry Andric       Init = Builder.CreateShuffleVector(Init, Args, "vext");
19910b57cec5SDimitry Andric 
19920b57cec5SDimitry Andric       Args.clear();
19930b57cec5SDimitry Andric       for (unsigned j = 0; j != CurIdx; ++j)
19945ffd83dbSDimitry Andric         Args.push_back(j);
19950b57cec5SDimitry Andric       for (unsigned j = 0; j != InitElts; ++j)
19965ffd83dbSDimitry Andric         Args.push_back(j + Offset);
19975ffd83dbSDimitry Andric       Args.resize(ResElts, -1);
19980b57cec5SDimitry Andric     }
19990b57cec5SDimitry Andric 
2000e710425bSDimitry Andric     // If V is poison, make sure it ends up on the RHS of the shuffle to aid
20010b57cec5SDimitry Andric     // merging subsequent shuffles into this one.
20020b57cec5SDimitry Andric     if (CurIdx == 0)
20030b57cec5SDimitry Andric       std::swap(V, Init);
20045ffd83dbSDimitry Andric     V = Builder.CreateShuffleVector(V, Init, Args, "vecinit");
2005e710425bSDimitry Andric     VIsPoisonShuffle = isa<llvm::PoisonValue>(Init);
20060b57cec5SDimitry Andric     CurIdx += InitElts;
20070b57cec5SDimitry Andric   }
20080b57cec5SDimitry Andric 
20090b57cec5SDimitry Andric   // FIXME: evaluate codegen vs. shuffling against constant null vector.
20100b57cec5SDimitry Andric   // Emit remaining default initializers.
20110b57cec5SDimitry Andric   llvm::Type *EltTy = VType->getElementType();
20120b57cec5SDimitry Andric 
20130b57cec5SDimitry Andric   // Emit remaining default initializers
20140b57cec5SDimitry Andric   for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
20150b57cec5SDimitry Andric     Value *Idx = Builder.getInt32(CurIdx);
20160b57cec5SDimitry Andric     llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
20170b57cec5SDimitry Andric     V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
20180b57cec5SDimitry Andric   }
20190b57cec5SDimitry Andric   return V;
20200b57cec5SDimitry Andric }
20210b57cec5SDimitry Andric 
ShouldNullCheckClassCastValue(const CastExpr * CE)20220b57cec5SDimitry Andric bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) {
20230b57cec5SDimitry Andric   const Expr *E = CE->getSubExpr();
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   if (CE->getCastKind() == CK_UncheckedDerivedToBase)
20260b57cec5SDimitry Andric     return false;
20270b57cec5SDimitry Andric 
20280b57cec5SDimitry Andric   if (isa<CXXThisExpr>(E->IgnoreParens())) {
20290b57cec5SDimitry Andric     // We always assume that 'this' is never null.
20300b57cec5SDimitry Andric     return false;
20310b57cec5SDimitry Andric   }
20320b57cec5SDimitry Andric 
20330b57cec5SDimitry Andric   if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
20340b57cec5SDimitry Andric     // And that glvalue casts are never null.
2035fe6060f1SDimitry Andric     if (ICE->isGLValue())
20360b57cec5SDimitry Andric       return false;
20370b57cec5SDimitry Andric   }
20380b57cec5SDimitry Andric 
20390b57cec5SDimitry Andric   return true;
20400b57cec5SDimitry Andric }
20410b57cec5SDimitry Andric 
20420b57cec5SDimitry Andric // VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
20430b57cec5SDimitry Andric // have to handle a more broad range of conversions than explicit casts, as they
20440b57cec5SDimitry Andric // handle things like function to ptr-to-function decay etc.
VisitCastExpr(CastExpr * CE)20450b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
20460b57cec5SDimitry Andric   Expr *E = CE->getSubExpr();
20470b57cec5SDimitry Andric   QualType DestTy = CE->getType();
20480b57cec5SDimitry Andric   CastKind Kind = CE->getCastKind();
2049bdd1243dSDimitry Andric   CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
20500b57cec5SDimitry Andric 
20510b57cec5SDimitry Andric   // These cases are generally not written to ignore the result of
20520b57cec5SDimitry Andric   // evaluating their sub-expressions, so we clear this now.
20530b57cec5SDimitry Andric   bool Ignored = TestAndClearIgnoreResultAssign();
20540b57cec5SDimitry Andric 
20550b57cec5SDimitry Andric   // Since almost all cast kinds apply to scalars, this switch doesn't have
20560b57cec5SDimitry Andric   // a default case, so the compiler will warn on a missing case.  The cases
20570b57cec5SDimitry Andric   // are in the same order as in the CastKind enum.
20580b57cec5SDimitry Andric   switch (Kind) {
20590b57cec5SDimitry Andric   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
20600b57cec5SDimitry Andric   case CK_BuiltinFnToFnPtr:
20610b57cec5SDimitry Andric     llvm_unreachable("builtin functions are handled elsewhere");
20620b57cec5SDimitry Andric 
20630b57cec5SDimitry Andric   case CK_LValueBitCast:
20640b57cec5SDimitry Andric   case CK_ObjCObjectLValueCast: {
2065480093f4SDimitry Andric     Address Addr = EmitLValue(E).getAddress(CGF);
2066fe013be4SDimitry Andric     Addr = Addr.withElementType(CGF.ConvertTypeForMem(DestTy));
20670b57cec5SDimitry Andric     LValue LV = CGF.MakeAddrLValue(Addr, DestTy);
20680b57cec5SDimitry Andric     return EmitLoadOfLValue(LV, CE->getExprLoc());
20690b57cec5SDimitry Andric   }
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric   case CK_LValueToRValueBitCast: {
20720b57cec5SDimitry Andric     LValue SourceLVal = CGF.EmitLValue(E);
2073fe013be4SDimitry Andric     Address Addr = SourceLVal.getAddress(CGF).withElementType(
20740b57cec5SDimitry Andric         CGF.ConvertTypeForMem(DestTy));
20750b57cec5SDimitry Andric     LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
20760b57cec5SDimitry Andric     DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
20770b57cec5SDimitry Andric     return EmitLoadOfLValue(DestLV, CE->getExprLoc());
20780b57cec5SDimitry Andric   }
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric   case CK_CPointerToObjCPointerCast:
20810b57cec5SDimitry Andric   case CK_BlockPointerToObjCPointerCast:
20820b57cec5SDimitry Andric   case CK_AnyPointerToBlockPointerCast:
20830b57cec5SDimitry Andric   case CK_BitCast: {
20840b57cec5SDimitry Andric     Value *Src = Visit(const_cast<Expr*>(E));
20850b57cec5SDimitry Andric     llvm::Type *SrcTy = Src->getType();
20860b57cec5SDimitry Andric     llvm::Type *DstTy = ConvertType(DestTy);
2087c9157d92SDimitry Andric     assert(
2088c9157d92SDimitry Andric         (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2089c9157d92SDimitry Andric          SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2090c9157d92SDimitry Andric         "Address-space cast must be used to convert address spaces");
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric     if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
209381ad6265SDimitry Andric       if (auto *PT = DestTy->getAs<PointerType>()) {
209481ad6265SDimitry Andric         CGF.EmitVTablePtrCheckForCast(
209581ad6265SDimitry Andric             PT->getPointeeType(),
209681ad6265SDimitry Andric             Address(Src,
209781ad6265SDimitry Andric                     CGF.ConvertTypeForMem(
209881ad6265SDimitry Andric                         E->getType()->castAs<PointerType>()->getPointeeType()),
209981ad6265SDimitry Andric                     CGF.getPointerAlign()),
210081ad6265SDimitry Andric             /*MayBeNull=*/true, CodeGenFunction::CFITCK_UnrelatedCast,
21010b57cec5SDimitry Andric             CE->getBeginLoc());
21020b57cec5SDimitry Andric       }
210381ad6265SDimitry Andric     }
21040b57cec5SDimitry Andric 
21050b57cec5SDimitry Andric     if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
21060b57cec5SDimitry Andric       const QualType SrcType = E->getType();
21070b57cec5SDimitry Andric 
21080b57cec5SDimitry Andric       if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) {
21090b57cec5SDimitry Andric         // Casting to pointer that could carry dynamic information (provided by
21100b57cec5SDimitry Andric         // invariant.group) requires launder.
21110b57cec5SDimitry Andric         Src = Builder.CreateLaunderInvariantGroup(Src);
21120b57cec5SDimitry Andric       } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) {
21130b57cec5SDimitry Andric         // Casting to pointer that does not carry dynamic information (provided
21140b57cec5SDimitry Andric         // by invariant.group) requires stripping it.  Note that we don't do it
21150b57cec5SDimitry Andric         // if the source could not be dynamic type and destination could be
21160b57cec5SDimitry Andric         // dynamic because dynamic information is already laundered.  It is
21170b57cec5SDimitry Andric         // because launder(strip(src)) == launder(src), so there is no need to
21180b57cec5SDimitry Andric         // add extra strip before launder.
21190b57cec5SDimitry Andric         Src = Builder.CreateStripInvariantGroup(Src);
21200b57cec5SDimitry Andric       }
21210b57cec5SDimitry Andric     }
21220b57cec5SDimitry Andric 
21235ffd83dbSDimitry Andric     // Update heapallocsite metadata when there is an explicit pointer cast.
21245ffd83dbSDimitry Andric     if (auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2125fe013be4SDimitry Andric       if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE) &&
2126fe013be4SDimitry Andric           !isa<CastExpr>(E)) {
21275ffd83dbSDimitry Andric         QualType PointeeType = DestTy->getPointeeType();
21285ffd83dbSDimitry Andric         if (!PointeeType.isNull())
21295ffd83dbSDimitry Andric           CGF.getDebugInfo()->addHeapAllocSiteMetadata(CI, PointeeType,
21305ffd83dbSDimitry Andric                                                        CE->getExprLoc());
21315ffd83dbSDimitry Andric       }
21325ffd83dbSDimitry Andric     }
21330b57cec5SDimitry Andric 
2134e8d8bef9SDimitry Andric     // If Src is a fixed vector and Dst is a scalable vector, and both have the
213581ad6265SDimitry Andric     // same element type, use the llvm.vector.insert intrinsic to perform the
213681ad6265SDimitry Andric     // bitcast.
2137e8d8bef9SDimitry Andric     if (const auto *FixedSrc = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2138e8d8bef9SDimitry Andric       if (const auto *ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2139349cc55cSDimitry Andric         // If we are casting a fixed i8 vector to a scalable 16 x i1 predicate
2140349cc55cSDimitry Andric         // vector, use a vector insert and bitcast the result.
2141349cc55cSDimitry Andric         bool NeedsBitCast = false;
2142349cc55cSDimitry Andric         auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16);
2143349cc55cSDimitry Andric         llvm::Type *OrigType = DstTy;
2144349cc55cSDimitry Andric         if (ScalableDst == PredType &&
2145349cc55cSDimitry Andric             FixedSrc->getElementType() == Builder.getInt8Ty()) {
2146349cc55cSDimitry Andric           DstTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2);
214781ad6265SDimitry Andric           ScalableDst = cast<llvm::ScalableVectorType>(DstTy);
2148349cc55cSDimitry Andric           NeedsBitCast = true;
2149349cc55cSDimitry Andric         }
2150e8d8bef9SDimitry Andric         if (FixedSrc->getElementType() == ScalableDst->getElementType()) {
2151e8d8bef9SDimitry Andric           llvm::Value *UndefVec = llvm::UndefValue::get(DstTy);
2152e8d8bef9SDimitry Andric           llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2153349cc55cSDimitry Andric           llvm::Value *Result = Builder.CreateInsertVector(
2154fe013be4SDimitry Andric               DstTy, UndefVec, Src, Zero, "cast.scalable");
2155349cc55cSDimitry Andric           if (NeedsBitCast)
2156349cc55cSDimitry Andric             Result = Builder.CreateBitCast(Result, OrigType);
2157349cc55cSDimitry Andric           return Result;
2158e8d8bef9SDimitry Andric         }
2159e8d8bef9SDimitry Andric       }
2160e8d8bef9SDimitry Andric     }
2161e8d8bef9SDimitry Andric 
2162e8d8bef9SDimitry Andric     // If Src is a scalable vector and Dst is a fixed vector, and both have the
216381ad6265SDimitry Andric     // same element type, use the llvm.vector.extract intrinsic to perform the
216481ad6265SDimitry Andric     // bitcast.
2165e8d8bef9SDimitry Andric     if (const auto *ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2166e8d8bef9SDimitry Andric       if (const auto *FixedDst = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2167349cc55cSDimitry Andric         // If we are casting a scalable 16 x i1 predicate vector to a fixed i8
2168349cc55cSDimitry Andric         // vector, bitcast the source and use a vector extract.
2169349cc55cSDimitry Andric         auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16);
2170349cc55cSDimitry Andric         if (ScalableSrc == PredType &&
2171349cc55cSDimitry Andric             FixedDst->getElementType() == Builder.getInt8Ty()) {
2172349cc55cSDimitry Andric           SrcTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2);
217381ad6265SDimitry Andric           ScalableSrc = cast<llvm::ScalableVectorType>(SrcTy);
2174349cc55cSDimitry Andric           Src = Builder.CreateBitCast(Src, SrcTy);
2175349cc55cSDimitry Andric         }
2176e8d8bef9SDimitry Andric         if (ScalableSrc->getElementType() == FixedDst->getElementType()) {
2177e8d8bef9SDimitry Andric           llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2178fe013be4SDimitry Andric           return Builder.CreateExtractVector(DstTy, Src, Zero, "cast.fixed");
2179e8d8bef9SDimitry Andric         }
2180e8d8bef9SDimitry Andric       }
2181e8d8bef9SDimitry Andric     }
2182e8d8bef9SDimitry Andric 
2183e8d8bef9SDimitry Andric     // Perform VLAT <-> VLST bitcast through memory.
2184e8d8bef9SDimitry Andric     // TODO: since the llvm.experimental.vector.{insert,extract} intrinsics
2185e8d8bef9SDimitry Andric     //       require the element types of the vectors to be the same, we
2186349cc55cSDimitry Andric     //       need to keep this around for bitcasts between VLAT <-> VLST where
2187349cc55cSDimitry Andric     //       the element types of the vectors are not the same, until we figure
2188349cc55cSDimitry Andric     //       out a better way of doing these casts.
2189e8d8bef9SDimitry Andric     if ((isa<llvm::FixedVectorType>(SrcTy) &&
2190e8d8bef9SDimitry Andric          isa<llvm::ScalableVectorType>(DstTy)) ||
2191e8d8bef9SDimitry Andric         (isa<llvm::ScalableVectorType>(SrcTy) &&
2192e8d8bef9SDimitry Andric          isa<llvm::FixedVectorType>(DstTy))) {
2193fe6060f1SDimitry Andric       Address Addr = CGF.CreateDefaultAlignTempAlloca(SrcTy, "saved-value");
2194fe6060f1SDimitry Andric       LValue LV = CGF.MakeAddrLValue(Addr, E->getType());
2195e8d8bef9SDimitry Andric       CGF.EmitStoreOfScalar(Src, LV);
2196fe013be4SDimitry Andric       Addr = Addr.withElementType(CGF.ConvertTypeForMem(DestTy));
2197e8d8bef9SDimitry Andric       LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
2198e8d8bef9SDimitry Andric       DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
2199e8d8bef9SDimitry Andric       return EmitLoadOfLValue(DestLV, CE->getExprLoc());
2200e8d8bef9SDimitry Andric     }
22010b57cec5SDimitry Andric     return Builder.CreateBitCast(Src, DstTy);
22020b57cec5SDimitry Andric   }
22030b57cec5SDimitry Andric   case CK_AddressSpaceConversion: {
22040b57cec5SDimitry Andric     Expr::EvalResult Result;
22050b57cec5SDimitry Andric     if (E->EvaluateAsRValue(Result, CGF.getContext()) &&
22060b57cec5SDimitry Andric         Result.Val.isNullPointer()) {
22070b57cec5SDimitry Andric       // If E has side effect, it is emitted even if its final result is a
22080b57cec5SDimitry Andric       // null pointer. In that case, a DCE pass should be able to
22090b57cec5SDimitry Andric       // eliminate the useless instructions emitted during translating E.
22100b57cec5SDimitry Andric       if (Result.HasSideEffects)
22110b57cec5SDimitry Andric         Visit(E);
22120b57cec5SDimitry Andric       return CGF.CGM.getNullPointer(cast<llvm::PointerType>(
22130b57cec5SDimitry Andric           ConvertType(DestTy)), DestTy);
22140b57cec5SDimitry Andric     }
22150b57cec5SDimitry Andric     // Since target may map different address spaces in AST to the same address
22160b57cec5SDimitry Andric     // space, an address space conversion may end up as a bitcast.
22170b57cec5SDimitry Andric     return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
22180b57cec5SDimitry Andric         CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
22190b57cec5SDimitry Andric         DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
22200b57cec5SDimitry Andric   }
22210b57cec5SDimitry Andric   case CK_AtomicToNonAtomic:
22220b57cec5SDimitry Andric   case CK_NonAtomicToAtomic:
22230b57cec5SDimitry Andric   case CK_UserDefinedConversion:
22240b57cec5SDimitry Andric     return Visit(const_cast<Expr*>(E));
22250b57cec5SDimitry Andric 
2226349cc55cSDimitry Andric   case CK_NoOp: {
2227c9157d92SDimitry Andric     return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
2228c9157d92SDimitry Andric                                               : Visit(const_cast<Expr *>(E));
2229349cc55cSDimitry Andric   }
2230349cc55cSDimitry Andric 
22310b57cec5SDimitry Andric   case CK_BaseToDerived: {
22320b57cec5SDimitry Andric     const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl();
22330b57cec5SDimitry Andric     assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!");
22340b57cec5SDimitry Andric 
22350b57cec5SDimitry Andric     Address Base = CGF.EmitPointerWithAlignment(E);
22360b57cec5SDimitry Andric     Address Derived =
22370b57cec5SDimitry Andric       CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl,
22380b57cec5SDimitry Andric                                    CE->path_begin(), CE->path_end(),
22390b57cec5SDimitry Andric                                    CGF.ShouldNullCheckClassCastValue(CE));
22400b57cec5SDimitry Andric 
22410b57cec5SDimitry Andric     // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
22420b57cec5SDimitry Andric     // performed and the object is not of the derived type.
22430b57cec5SDimitry Andric     if (CGF.sanitizePerformTypeCheck())
22440b57cec5SDimitry Andric       CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
22450b57cec5SDimitry Andric                         Derived.getPointer(), DestTy->getPointeeType());
22460b57cec5SDimitry Andric 
22470b57cec5SDimitry Andric     if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast))
224881ad6265SDimitry Andric       CGF.EmitVTablePtrCheckForCast(DestTy->getPointeeType(), Derived,
224981ad6265SDimitry Andric                                     /*MayBeNull=*/true,
225081ad6265SDimitry Andric                                     CodeGenFunction::CFITCK_DerivedCast,
22510b57cec5SDimitry Andric                                     CE->getBeginLoc());
22520b57cec5SDimitry Andric 
22530b57cec5SDimitry Andric     return Derived.getPointer();
22540b57cec5SDimitry Andric   }
22550b57cec5SDimitry Andric   case CK_UncheckedDerivedToBase:
22560b57cec5SDimitry Andric   case CK_DerivedToBase: {
22570b57cec5SDimitry Andric     // The EmitPointerWithAlignment path does this fine; just discard
22580b57cec5SDimitry Andric     // the alignment.
22590b57cec5SDimitry Andric     return CGF.EmitPointerWithAlignment(CE).getPointer();
22600b57cec5SDimitry Andric   }
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric   case CK_Dynamic: {
22630b57cec5SDimitry Andric     Address V = CGF.EmitPointerWithAlignment(E);
22640b57cec5SDimitry Andric     const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
22650b57cec5SDimitry Andric     return CGF.EmitDynamicCast(V, DCE);
22660b57cec5SDimitry Andric   }
22670b57cec5SDimitry Andric 
22680b57cec5SDimitry Andric   case CK_ArrayToPointerDecay:
22690b57cec5SDimitry Andric     return CGF.EmitArrayToPointerDecay(E).getPointer();
22700b57cec5SDimitry Andric   case CK_FunctionToPointerDecay:
2271480093f4SDimitry Andric     return EmitLValue(E).getPointer(CGF);
22720b57cec5SDimitry Andric 
22730b57cec5SDimitry Andric   case CK_NullToPointer:
22740b57cec5SDimitry Andric     if (MustVisitNullValue(E))
22750b57cec5SDimitry Andric       CGF.EmitIgnoredExpr(E);
22760b57cec5SDimitry Andric 
22770b57cec5SDimitry Andric     return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
22780b57cec5SDimitry Andric                               DestTy);
22790b57cec5SDimitry Andric 
22800b57cec5SDimitry Andric   case CK_NullToMemberPointer: {
22810b57cec5SDimitry Andric     if (MustVisitNullValue(E))
22820b57cec5SDimitry Andric       CGF.EmitIgnoredExpr(E);
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric     const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
22850b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
22860b57cec5SDimitry Andric   }
22870b57cec5SDimitry Andric 
22880b57cec5SDimitry Andric   case CK_ReinterpretMemberPointer:
22890b57cec5SDimitry Andric   case CK_BaseToDerivedMemberPointer:
22900b57cec5SDimitry Andric   case CK_DerivedToBaseMemberPointer: {
22910b57cec5SDimitry Andric     Value *Src = Visit(E);
22920b57cec5SDimitry Andric 
22930b57cec5SDimitry Andric     // Note that the AST doesn't distinguish between checked and
22940b57cec5SDimitry Andric     // unchecked member pointer conversions, so we always have to
22950b57cec5SDimitry Andric     // implement checked conversions here.  This is inefficient when
22960b57cec5SDimitry Andric     // actual control flow may be required in order to perform the
22970b57cec5SDimitry Andric     // check, which it is for data member pointers (but not member
22980b57cec5SDimitry Andric     // function pointers on Itanium and ARM).
22990b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);
23000b57cec5SDimitry Andric   }
23010b57cec5SDimitry Andric 
23020b57cec5SDimitry Andric   case CK_ARCProduceObject:
23030b57cec5SDimitry Andric     return CGF.EmitARCRetainScalarExpr(E);
23040b57cec5SDimitry Andric   case CK_ARCConsumeObject:
23050b57cec5SDimitry Andric     return CGF.EmitObjCConsumeObject(E->getType(), Visit(E));
23060b57cec5SDimitry Andric   case CK_ARCReclaimReturnedObject:
23070b57cec5SDimitry Andric     return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored);
23080b57cec5SDimitry Andric   case CK_ARCExtendBlockObject:
23090b57cec5SDimitry Andric     return CGF.EmitARCExtendBlockObject(E);
23100b57cec5SDimitry Andric 
23110b57cec5SDimitry Andric   case CK_CopyAndAutoreleaseBlockObject:
23120b57cec5SDimitry Andric     return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType());
23130b57cec5SDimitry Andric 
23140b57cec5SDimitry Andric   case CK_FloatingRealToComplex:
23150b57cec5SDimitry Andric   case CK_FloatingComplexCast:
23160b57cec5SDimitry Andric   case CK_IntegralRealToComplex:
23170b57cec5SDimitry Andric   case CK_IntegralComplexCast:
23180b57cec5SDimitry Andric   case CK_IntegralComplexToFloatingComplex:
23190b57cec5SDimitry Andric   case CK_FloatingComplexToIntegralComplex:
23200b57cec5SDimitry Andric   case CK_ConstructorConversion:
23210b57cec5SDimitry Andric   case CK_ToUnion:
23220b57cec5SDimitry Andric     llvm_unreachable("scalar cast to non-scalar value");
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric   case CK_LValueToRValue:
23250b57cec5SDimitry Andric     assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
23260b57cec5SDimitry Andric     assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!");
23270b57cec5SDimitry Andric     return Visit(const_cast<Expr*>(E));
23280b57cec5SDimitry Andric 
23290b57cec5SDimitry Andric   case CK_IntegralToPointer: {
23300b57cec5SDimitry Andric     Value *Src = Visit(const_cast<Expr*>(E));
23310b57cec5SDimitry Andric 
23320b57cec5SDimitry Andric     // First, convert to the correct width so that we control the kind of
23330b57cec5SDimitry Andric     // extension.
23340b57cec5SDimitry Andric     auto DestLLVMTy = ConvertType(DestTy);
23350b57cec5SDimitry Andric     llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy);
23360b57cec5SDimitry Andric     bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType();
23370b57cec5SDimitry Andric     llvm::Value* IntResult =
23380b57cec5SDimitry Andric       Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
23390b57cec5SDimitry Andric 
23400b57cec5SDimitry Andric     auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
23410b57cec5SDimitry Andric 
23420b57cec5SDimitry Andric     if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
23430b57cec5SDimitry Andric       // Going from integer to pointer that could be dynamic requires reloading
23440b57cec5SDimitry Andric       // dynamic information from invariant.group.
23450b57cec5SDimitry Andric       if (DestTy.mayBeDynamicClass())
23460b57cec5SDimitry Andric         IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
23470b57cec5SDimitry Andric     }
23480b57cec5SDimitry Andric     return IntToPtr;
23490b57cec5SDimitry Andric   }
23500b57cec5SDimitry Andric   case CK_PointerToIntegral: {
23510b57cec5SDimitry Andric     assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
23520b57cec5SDimitry Andric     auto *PtrExpr = Visit(E);
23530b57cec5SDimitry Andric 
23540b57cec5SDimitry Andric     if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
23550b57cec5SDimitry Andric       const QualType SrcType = E->getType();
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric       // Casting to integer requires stripping dynamic information as it does
23580b57cec5SDimitry Andric       // not carries it.
23590b57cec5SDimitry Andric       if (SrcType.mayBeDynamicClass())
23600b57cec5SDimitry Andric         PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
23610b57cec5SDimitry Andric     }
23620b57cec5SDimitry Andric 
23630b57cec5SDimitry Andric     return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
23640b57cec5SDimitry Andric   }
23650b57cec5SDimitry Andric   case CK_ToVoid: {
23660b57cec5SDimitry Andric     CGF.EmitIgnoredExpr(E);
23670b57cec5SDimitry Andric     return nullptr;
23680b57cec5SDimitry Andric   }
2369fe6060f1SDimitry Andric   case CK_MatrixCast: {
2370fe6060f1SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2371fe6060f1SDimitry Andric                                 CE->getExprLoc());
2372fe6060f1SDimitry Andric   }
23730b57cec5SDimitry Andric   case CK_VectorSplat: {
23740b57cec5SDimitry Andric     llvm::Type *DstTy = ConvertType(DestTy);
23750b57cec5SDimitry Andric     Value *Elt = Visit(const_cast<Expr *>(E));
23760b57cec5SDimitry Andric     // Splat the element across to all elements
237781ad6265SDimitry Andric     llvm::ElementCount NumElements =
237881ad6265SDimitry Andric         cast<llvm::VectorType>(DstTy)->getElementCount();
23790b57cec5SDimitry Andric     return Builder.CreateVectorSplat(NumElements, Elt, "splat");
23800b57cec5SDimitry Andric   }
23810b57cec5SDimitry Andric 
23820b57cec5SDimitry Andric   case CK_FixedPointCast:
23830b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23840b57cec5SDimitry Andric                                 CE->getExprLoc());
23850b57cec5SDimitry Andric 
23860b57cec5SDimitry Andric   case CK_FixedPointToBoolean:
23870b57cec5SDimitry Andric     assert(E->getType()->isFixedPointType() &&
23880b57cec5SDimitry Andric            "Expected src type to be fixed point type");
23890b57cec5SDimitry Andric     assert(DestTy->isBooleanType() && "Expected dest type to be boolean type");
23900b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23910b57cec5SDimitry Andric                                 CE->getExprLoc());
23920b57cec5SDimitry Andric 
23930b57cec5SDimitry Andric   case CK_FixedPointToIntegral:
23940b57cec5SDimitry Andric     assert(E->getType()->isFixedPointType() &&
23950b57cec5SDimitry Andric            "Expected src type to be fixed point type");
23960b57cec5SDimitry Andric     assert(DestTy->isIntegerType() && "Expected dest type to be an integer");
23970b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
23980b57cec5SDimitry Andric                                 CE->getExprLoc());
23990b57cec5SDimitry Andric 
24000b57cec5SDimitry Andric   case CK_IntegralToFixedPoint:
24010b57cec5SDimitry Andric     assert(E->getType()->isIntegerType() &&
24020b57cec5SDimitry Andric            "Expected src type to be an integer");
24030b57cec5SDimitry Andric     assert(DestTy->isFixedPointType() &&
24040b57cec5SDimitry Andric            "Expected dest type to be fixed point type");
24050b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
24060b57cec5SDimitry Andric                                 CE->getExprLoc());
24070b57cec5SDimitry Andric 
24080b57cec5SDimitry Andric   case CK_IntegralCast: {
24090b57cec5SDimitry Andric     ScalarConversionOpts Opts;
24100b57cec5SDimitry Andric     if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
24110b57cec5SDimitry Andric       if (!ICE->isPartOfExplicitCast())
24120b57cec5SDimitry Andric         Opts = ScalarConversionOpts(CGF.SanOpts);
24130b57cec5SDimitry Andric     }
24140b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
24150b57cec5SDimitry Andric                                 CE->getExprLoc(), Opts);
24160b57cec5SDimitry Andric   }
24170b57cec5SDimitry Andric   case CK_IntegralToFloating:
24180b57cec5SDimitry Andric   case CK_FloatingToIntegral:
24190b57cec5SDimitry Andric   case CK_FloatingCast:
2420e8d8bef9SDimitry Andric   case CK_FixedPointToFloating:
2421e8d8bef9SDimitry Andric   case CK_FloatingToFixedPoint: {
2422e8d8bef9SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
24230b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
24240b57cec5SDimitry Andric                                 CE->getExprLoc());
2425e8d8bef9SDimitry Andric   }
24260b57cec5SDimitry Andric   case CK_BooleanToSignedIntegral: {
24270b57cec5SDimitry Andric     ScalarConversionOpts Opts;
24280b57cec5SDimitry Andric     Opts.TreatBooleanAsSigned = true;
24290b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
24300b57cec5SDimitry Andric                                 CE->getExprLoc(), Opts);
24310b57cec5SDimitry Andric   }
24320b57cec5SDimitry Andric   case CK_IntegralToBoolean:
24330b57cec5SDimitry Andric     return EmitIntToBoolConversion(Visit(E));
24340b57cec5SDimitry Andric   case CK_PointerToBoolean:
24350b57cec5SDimitry Andric     return EmitPointerToBoolConversion(Visit(E), E->getType());
2436e8d8bef9SDimitry Andric   case CK_FloatingToBoolean: {
2437e8d8bef9SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
24380b57cec5SDimitry Andric     return EmitFloatToBoolConversion(Visit(E));
2439e8d8bef9SDimitry Andric   }
24400b57cec5SDimitry Andric   case CK_MemberPointerToBoolean: {
24410b57cec5SDimitry Andric     llvm::Value *MemPtr = Visit(E);
24420b57cec5SDimitry Andric     const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
24430b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
24440b57cec5SDimitry Andric   }
24450b57cec5SDimitry Andric 
24460b57cec5SDimitry Andric   case CK_FloatingComplexToReal:
24470b57cec5SDimitry Andric   case CK_IntegralComplexToReal:
24480b57cec5SDimitry Andric     return CGF.EmitComplexExpr(E, false, true).first;
24490b57cec5SDimitry Andric 
24500b57cec5SDimitry Andric   case CK_FloatingComplexToBoolean:
24510b57cec5SDimitry Andric   case CK_IntegralComplexToBoolean: {
24520b57cec5SDimitry Andric     CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric     // TODO: kill this function off, inline appropriate case here
24550b57cec5SDimitry Andric     return EmitComplexToScalarConversion(V, E->getType(), DestTy,
24560b57cec5SDimitry Andric                                          CE->getExprLoc());
24570b57cec5SDimitry Andric   }
24580b57cec5SDimitry Andric 
24590b57cec5SDimitry Andric   case CK_ZeroToOCLOpaqueType: {
24600b57cec5SDimitry Andric     assert((DestTy->isEventT() || DestTy->isQueueT() ||
24610b57cec5SDimitry Andric             DestTy->isOCLIntelSubgroupAVCType()) &&
24620b57cec5SDimitry Andric            "CK_ZeroToOCLEvent cast on non-event type");
24630b57cec5SDimitry Andric     return llvm::Constant::getNullValue(ConvertType(DestTy));
24640b57cec5SDimitry Andric   }
24650b57cec5SDimitry Andric 
24660b57cec5SDimitry Andric   case CK_IntToOCLSampler:
24670b57cec5SDimitry Andric     return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
24680b57cec5SDimitry Andric 
24690b57cec5SDimitry Andric   } // end of switch
24700b57cec5SDimitry Andric 
24710b57cec5SDimitry Andric   llvm_unreachable("unknown scalar cast");
24720b57cec5SDimitry Andric }
24730b57cec5SDimitry Andric 
VisitStmtExpr(const StmtExpr * E)24740b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
24750b57cec5SDimitry Andric   CodeGenFunction::StmtExprEvaluation eval(CGF);
24760b57cec5SDimitry Andric   Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(),
24770b57cec5SDimitry Andric                                            !E->getType()->isVoidType());
24780b57cec5SDimitry Andric   if (!RetAlloca.isValid())
24790b57cec5SDimitry Andric     return nullptr;
24800b57cec5SDimitry Andric   return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()),
24810b57cec5SDimitry Andric                               E->getExprLoc());
24820b57cec5SDimitry Andric }
24830b57cec5SDimitry Andric 
VisitExprWithCleanups(ExprWithCleanups * E)24840b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
24850b57cec5SDimitry Andric   CodeGenFunction::RunCleanupsScope Scope(CGF);
24860b57cec5SDimitry Andric   Value *V = Visit(E->getSubExpr());
24870b57cec5SDimitry Andric   // Defend against dominance problems caused by jumps out of expression
24880b57cec5SDimitry Andric   // evaluation through the shared cleanup block.
24890b57cec5SDimitry Andric   Scope.ForceCleanup({&V});
24900b57cec5SDimitry Andric   return V;
24910b57cec5SDimitry Andric }
24920b57cec5SDimitry Andric 
24930b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
24940b57cec5SDimitry Andric //                             Unary Operators
24950b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
24960b57cec5SDimitry Andric 
createBinOpInfoFromIncDec(const UnaryOperator * E,llvm::Value * InVal,bool IsInc,FPOptions FPFeatures)24970b57cec5SDimitry Andric static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
24985ffd83dbSDimitry Andric                                            llvm::Value *InVal, bool IsInc,
24995ffd83dbSDimitry Andric                                            FPOptions FPFeatures) {
25000b57cec5SDimitry Andric   BinOpInfo BinOp;
25010b57cec5SDimitry Andric   BinOp.LHS = InVal;
25020b57cec5SDimitry Andric   BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
25030b57cec5SDimitry Andric   BinOp.Ty = E->getType();
25040b57cec5SDimitry Andric   BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
25055ffd83dbSDimitry Andric   BinOp.FPFeatures = FPFeatures;
25060b57cec5SDimitry Andric   BinOp.E = E;
25070b57cec5SDimitry Andric   return BinOp;
25080b57cec5SDimitry Andric }
25090b57cec5SDimitry Andric 
EmitIncDecConsiderOverflowBehavior(const UnaryOperator * E,llvm::Value * InVal,bool IsInc)25100b57cec5SDimitry Andric llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
25110b57cec5SDimitry Andric     const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {
25120b57cec5SDimitry Andric   llvm::Value *Amount =
25130b57cec5SDimitry Andric       llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true);
25140b57cec5SDimitry Andric   StringRef Name = IsInc ? "inc" : "dec";
25150b57cec5SDimitry Andric   switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
25160b57cec5SDimitry Andric   case LangOptions::SOB_Defined:
25170b57cec5SDimitry Andric     return Builder.CreateAdd(InVal, Amount, Name);
25180b57cec5SDimitry Andric   case LangOptions::SOB_Undefined:
25190b57cec5SDimitry Andric     if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
25200b57cec5SDimitry Andric       return Builder.CreateNSWAdd(InVal, Amount, Name);
2521bdd1243dSDimitry Andric     [[fallthrough]];
25220b57cec5SDimitry Andric   case LangOptions::SOB_Trapping:
25230b57cec5SDimitry Andric     if (!E->canOverflow())
25240b57cec5SDimitry Andric       return Builder.CreateNSWAdd(InVal, Amount, Name);
25255ffd83dbSDimitry Andric     return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
25265ffd83dbSDimitry Andric         E, InVal, IsInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
25270b57cec5SDimitry Andric   }
25280b57cec5SDimitry Andric   llvm_unreachable("Unknown SignedOverflowBehaviorTy");
25290b57cec5SDimitry Andric }
25300b57cec5SDimitry Andric 
2531480093f4SDimitry Andric namespace {
2532480093f4SDimitry Andric /// Handles check and update for lastprivate conditional variables.
2533480093f4SDimitry Andric class OMPLastprivateConditionalUpdateRAII {
2534480093f4SDimitry Andric private:
2535480093f4SDimitry Andric   CodeGenFunction &CGF;
2536480093f4SDimitry Andric   const UnaryOperator *E;
2537480093f4SDimitry Andric 
2538480093f4SDimitry Andric public:
OMPLastprivateConditionalUpdateRAII(CodeGenFunction & CGF,const UnaryOperator * E)2539480093f4SDimitry Andric   OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
2540480093f4SDimitry Andric                                       const UnaryOperator *E)
2541480093f4SDimitry Andric       : CGF(CGF), E(E) {}
~OMPLastprivateConditionalUpdateRAII()2542480093f4SDimitry Andric   ~OMPLastprivateConditionalUpdateRAII() {
2543480093f4SDimitry Andric     if (CGF.getLangOpts().OpenMP)
2544480093f4SDimitry Andric       CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(
2545480093f4SDimitry Andric           CGF, E->getSubExpr());
2546480093f4SDimitry Andric   }
2547480093f4SDimitry Andric };
2548480093f4SDimitry Andric } // namespace
2549480093f4SDimitry Andric 
25500b57cec5SDimitry Andric llvm::Value *
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)25510b57cec5SDimitry Andric ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
25520b57cec5SDimitry Andric                                            bool isInc, bool isPre) {
2553480093f4SDimitry Andric   OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
25540b57cec5SDimitry Andric   QualType type = E->getSubExpr()->getType();
25550b57cec5SDimitry Andric   llvm::PHINode *atomicPHI = nullptr;
25560b57cec5SDimitry Andric   llvm::Value *value;
25570b57cec5SDimitry Andric   llvm::Value *input;
25580b57cec5SDimitry Andric 
25590b57cec5SDimitry Andric   int amount = (isInc ? 1 : -1);
25600b57cec5SDimitry Andric   bool isSubtraction = !isInc;
25610b57cec5SDimitry Andric 
25620b57cec5SDimitry Andric   if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
25630b57cec5SDimitry Andric     type = atomicTy->getValueType();
25640b57cec5SDimitry Andric     if (isInc && type->isBooleanType()) {
25650b57cec5SDimitry Andric       llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type);
25660b57cec5SDimitry Andric       if (isPre) {
2567480093f4SDimitry Andric         Builder.CreateStore(True, LV.getAddress(CGF), LV.isVolatileQualified())
25680b57cec5SDimitry Andric             ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
25690b57cec5SDimitry Andric         return Builder.getTrue();
25700b57cec5SDimitry Andric       }
25710b57cec5SDimitry Andric       // For atomic bool increment, we just store true and return it for
25720b57cec5SDimitry Andric       // preincrement, do an atomic swap with true for postincrement
25730b57cec5SDimitry Andric       return Builder.CreateAtomicRMW(
2574c9157d92SDimitry Andric           llvm::AtomicRMWInst::Xchg, LV.getAddress(CGF), True,
25750b57cec5SDimitry Andric           llvm::AtomicOrdering::SequentiallyConsistent);
25760b57cec5SDimitry Andric     }
25770b57cec5SDimitry Andric     // Special case for atomic increment / decrement on integers, emit
25780b57cec5SDimitry Andric     // atomicrmw instructions.  We skip this if we want to be doing overflow
25790b57cec5SDimitry Andric     // checking, and fall into the slow path with the atomic cmpxchg loop.
25800b57cec5SDimitry Andric     if (!type->isBooleanType() && type->isIntegerType() &&
25810b57cec5SDimitry Andric         !(type->isUnsignedIntegerType() &&
25820b57cec5SDimitry Andric           CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
25830b57cec5SDimitry Andric         CGF.getLangOpts().getSignedOverflowBehavior() !=
25840b57cec5SDimitry Andric             LangOptions::SOB_Trapping) {
25850b57cec5SDimitry Andric       llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
25860b57cec5SDimitry Andric         llvm::AtomicRMWInst::Sub;
25870b57cec5SDimitry Andric       llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
25880b57cec5SDimitry Andric         llvm::Instruction::Sub;
25890b57cec5SDimitry Andric       llvm::Value *amt = CGF.EmitToMemory(
25900b57cec5SDimitry Andric           llvm::ConstantInt::get(ConvertType(type), 1, true), type);
2591480093f4SDimitry Andric       llvm::Value *old =
2592c9157d92SDimitry Andric           Builder.CreateAtomicRMW(aop, LV.getAddress(CGF), amt,
2593480093f4SDimitry Andric                                   llvm::AtomicOrdering::SequentiallyConsistent);
25940b57cec5SDimitry Andric       return isPre ? Builder.CreateBinOp(op, old, amt) : old;
25950b57cec5SDimitry Andric     }
25960b57cec5SDimitry Andric     value = EmitLoadOfLValue(LV, E->getExprLoc());
25970b57cec5SDimitry Andric     input = value;
25980b57cec5SDimitry Andric     // For every other atomic operation, we need to emit a load-op-cmpxchg loop
25990b57cec5SDimitry Andric     llvm::BasicBlock *startBB = Builder.GetInsertBlock();
26000b57cec5SDimitry Andric     llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
26010b57cec5SDimitry Andric     value = CGF.EmitToMemory(value, type);
26020b57cec5SDimitry Andric     Builder.CreateBr(opBB);
26030b57cec5SDimitry Andric     Builder.SetInsertPoint(opBB);
26040b57cec5SDimitry Andric     atomicPHI = Builder.CreatePHI(value->getType(), 2);
26050b57cec5SDimitry Andric     atomicPHI->addIncoming(value, startBB);
26060b57cec5SDimitry Andric     value = atomicPHI;
26070b57cec5SDimitry Andric   } else {
26080b57cec5SDimitry Andric     value = EmitLoadOfLValue(LV, E->getExprLoc());
26090b57cec5SDimitry Andric     input = value;
26100b57cec5SDimitry Andric   }
26110b57cec5SDimitry Andric 
26120b57cec5SDimitry Andric   // Special case of integer increment that we have to check first: bool++.
26130b57cec5SDimitry Andric   // Due to promotion rules, we get:
26140b57cec5SDimitry Andric   //   bool++ -> bool = bool + 1
26150b57cec5SDimitry Andric   //          -> bool = (int)bool + 1
26160b57cec5SDimitry Andric   //          -> bool = ((int)bool + 1 != 0)
26170b57cec5SDimitry Andric   // An interesting aspect of this is that increment is always true.
26180b57cec5SDimitry Andric   // Decrement does not have this property.
26190b57cec5SDimitry Andric   if (isInc && type->isBooleanType()) {
26200b57cec5SDimitry Andric     value = Builder.getTrue();
26210b57cec5SDimitry Andric 
26220b57cec5SDimitry Andric   // Most common case by far: integer increment.
26230b57cec5SDimitry Andric   } else if (type->isIntegerType()) {
2624480093f4SDimitry Andric     QualType promotedType;
2625480093f4SDimitry Andric     bool canPerformLossyDemotionCheck = false;
2626bdd1243dSDimitry Andric     if (CGF.getContext().isPromotableIntegerType(type)) {
2627480093f4SDimitry Andric       promotedType = CGF.getContext().getPromotedIntegerType(type);
2628480093f4SDimitry Andric       assert(promotedType != type && "Shouldn't promote to the same type.");
2629480093f4SDimitry Andric       canPerformLossyDemotionCheck = true;
2630480093f4SDimitry Andric       canPerformLossyDemotionCheck &=
2631480093f4SDimitry Andric           CGF.getContext().getCanonicalType(type) !=
2632480093f4SDimitry Andric           CGF.getContext().getCanonicalType(promotedType);
2633480093f4SDimitry Andric       canPerformLossyDemotionCheck &=
2634480093f4SDimitry Andric           PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
2635480093f4SDimitry Andric               type, promotedType);
2636480093f4SDimitry Andric       assert((!canPerformLossyDemotionCheck ||
2637480093f4SDimitry Andric               type->isSignedIntegerOrEnumerationType() ||
2638480093f4SDimitry Andric               promotedType->isSignedIntegerOrEnumerationType() ||
2639480093f4SDimitry Andric               ConvertType(type)->getScalarSizeInBits() ==
2640480093f4SDimitry Andric                   ConvertType(promotedType)->getScalarSizeInBits()) &&
2641480093f4SDimitry Andric              "The following check expects that if we do promotion to different "
2642480093f4SDimitry Andric              "underlying canonical type, at least one of the types (either "
2643480093f4SDimitry Andric              "base or promoted) will be signed, or the bitwidths will match.");
2644480093f4SDimitry Andric     }
2645480093f4SDimitry Andric     if (CGF.SanOpts.hasOneOf(
2646480093f4SDimitry Andric             SanitizerKind::ImplicitIntegerArithmeticValueChange) &&
2647480093f4SDimitry Andric         canPerformLossyDemotionCheck) {
2648480093f4SDimitry Andric       // While `x += 1` (for `x` with width less than int) is modeled as
2649480093f4SDimitry Andric       // promotion+arithmetics+demotion, and we can catch lossy demotion with
2650480093f4SDimitry Andric       // ease; inc/dec with width less than int can't overflow because of
2651480093f4SDimitry Andric       // promotion rules, so we omit promotion+demotion, which means that we can
2652480093f4SDimitry Andric       // not catch lossy "demotion". Because we still want to catch these cases
2653480093f4SDimitry Andric       // when the sanitizer is enabled, we perform the promotion, then perform
2654480093f4SDimitry Andric       // the increment/decrement in the wider type, and finally
2655480093f4SDimitry Andric       // perform the demotion. This will catch lossy demotions.
2656480093f4SDimitry Andric 
2657480093f4SDimitry Andric       value = EmitScalarConversion(value, type, promotedType, E->getExprLoc());
2658480093f4SDimitry Andric       Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
2659480093f4SDimitry Andric       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
2660480093f4SDimitry Andric       // Do pass non-default ScalarConversionOpts so that sanitizer check is
2661480093f4SDimitry Andric       // emitted.
2662480093f4SDimitry Andric       value = EmitScalarConversion(value, promotedType, type, E->getExprLoc(),
2663480093f4SDimitry Andric                                    ScalarConversionOpts(CGF.SanOpts));
2664480093f4SDimitry Andric 
26650b57cec5SDimitry Andric       // Note that signed integer inc/dec with width less than int can't
2666480093f4SDimitry Andric       // overflow because of promotion rules; we're just eliding a few steps
2667480093f4SDimitry Andric       // here.
2668480093f4SDimitry Andric     } else if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
26690b57cec5SDimitry Andric       value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
26700b57cec5SDimitry Andric     } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
26710b57cec5SDimitry Andric                CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
26725ffd83dbSDimitry Andric       value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
26735ffd83dbSDimitry Andric           E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
26740b57cec5SDimitry Andric     } else {
26750b57cec5SDimitry Andric       llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
26760b57cec5SDimitry Andric       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
26770b57cec5SDimitry Andric     }
26780b57cec5SDimitry Andric 
26790b57cec5SDimitry Andric   // Next most common: pointer increment.
26800b57cec5SDimitry Andric   } else if (const PointerType *ptr = type->getAs<PointerType>()) {
26810b57cec5SDimitry Andric     QualType type = ptr->getPointeeType();
26820b57cec5SDimitry Andric 
26830b57cec5SDimitry Andric     // VLA types don't have constant size.
26840b57cec5SDimitry Andric     if (const VariableArrayType *vla
26850b57cec5SDimitry Andric           = CGF.getContext().getAsVariableArrayType(type)) {
26860b57cec5SDimitry Andric       llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
26870b57cec5SDimitry Andric       if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
268881ad6265SDimitry Andric       llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
26890b57cec5SDimitry Andric       if (CGF.getLangOpts().isSignedOverflowDefined())
26900eae32dcSDimitry Andric         value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc");
26910b57cec5SDimitry Andric       else
26920b57cec5SDimitry Andric         value = CGF.EmitCheckedInBoundsGEP(
26930eae32dcSDimitry Andric             elemTy, value, numElts, /*SignedIndices=*/false, isSubtraction,
26940b57cec5SDimitry Andric             E->getExprLoc(), "vla.inc");
26950b57cec5SDimitry Andric 
26960b57cec5SDimitry Andric     // Arithmetic on function pointers (!) is just +-1.
26970b57cec5SDimitry Andric     } else if (type->isFunctionType()) {
26980b57cec5SDimitry Andric       llvm::Value *amt = Builder.getInt32(amount);
26990b57cec5SDimitry Andric 
27000b57cec5SDimitry Andric       if (CGF.getLangOpts().isSignedOverflowDefined())
2701fe6060f1SDimitry Andric         value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
27020b57cec5SDimitry Andric       else
2703fe013be4SDimitry Andric         value =
2704fe013be4SDimitry Andric             CGF.EmitCheckedInBoundsGEP(CGF.Int8Ty, value, amt,
2705fe013be4SDimitry Andric                                        /*SignedIndices=*/false, isSubtraction,
2706fe013be4SDimitry Andric                                        E->getExprLoc(), "incdec.funcptr");
27070b57cec5SDimitry Andric 
27080b57cec5SDimitry Andric     // For everything else, we can just do a simple increment.
27090b57cec5SDimitry Andric     } else {
27100b57cec5SDimitry Andric       llvm::Value *amt = Builder.getInt32(amount);
27110eae32dcSDimitry Andric       llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
27120b57cec5SDimitry Andric       if (CGF.getLangOpts().isSignedOverflowDefined())
27130eae32dcSDimitry Andric         value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr");
27140b57cec5SDimitry Andric       else
27150eae32dcSDimitry Andric         value = CGF.EmitCheckedInBoundsGEP(
27160eae32dcSDimitry Andric             elemTy, value, amt, /*SignedIndices=*/false, isSubtraction,
27170eae32dcSDimitry Andric             E->getExprLoc(), "incdec.ptr");
27180b57cec5SDimitry Andric     }
27190b57cec5SDimitry Andric 
27200b57cec5SDimitry Andric   // Vector increment/decrement.
27210b57cec5SDimitry Andric   } else if (type->isVectorType()) {
27220b57cec5SDimitry Andric     if (type->hasIntegerRepresentation()) {
27230b57cec5SDimitry Andric       llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
27240b57cec5SDimitry Andric 
27250b57cec5SDimitry Andric       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
27260b57cec5SDimitry Andric     } else {
27270b57cec5SDimitry Andric       value = Builder.CreateFAdd(
27280b57cec5SDimitry Andric                   value,
27290b57cec5SDimitry Andric                   llvm::ConstantFP::get(value->getType(), amount),
27300b57cec5SDimitry Andric                   isInc ? "inc" : "dec");
27310b57cec5SDimitry Andric     }
27320b57cec5SDimitry Andric 
27330b57cec5SDimitry Andric   // Floating point.
27340b57cec5SDimitry Andric   } else if (type->isRealFloatingType()) {
27350b57cec5SDimitry Andric     // Add the inc/dec to the real part.
27360b57cec5SDimitry Andric     llvm::Value *amt;
2737e8d8bef9SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
27380b57cec5SDimitry Andric 
27390b57cec5SDimitry Andric     if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
27400b57cec5SDimitry Andric       // Another special case: half FP increment should be done via float
27410b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
27420b57cec5SDimitry Andric         value = Builder.CreateCall(
27430b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
27440b57cec5SDimitry Andric                                  CGF.CGM.FloatTy),
27450b57cec5SDimitry Andric             input, "incdec.conv");
27460b57cec5SDimitry Andric       } else {
27470b57cec5SDimitry Andric         value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv");
27480b57cec5SDimitry Andric       }
27490b57cec5SDimitry Andric     }
27500b57cec5SDimitry Andric 
27510b57cec5SDimitry Andric     if (value->getType()->isFloatTy())
27520b57cec5SDimitry Andric       amt = llvm::ConstantFP::get(VMContext,
27530b57cec5SDimitry Andric                                   llvm::APFloat(static_cast<float>(amount)));
27540b57cec5SDimitry Andric     else if (value->getType()->isDoubleTy())
27550b57cec5SDimitry Andric       amt = llvm::ConstantFP::get(VMContext,
27560b57cec5SDimitry Andric                                   llvm::APFloat(static_cast<double>(amount)));
27570b57cec5SDimitry Andric     else {
2758c9157d92SDimitry Andric       // Remaining types are Half, Bfloat16, LongDouble, __ibm128 or __float128.
2759c9157d92SDimitry Andric       // Convert from float.
27600b57cec5SDimitry Andric       llvm::APFloat F(static_cast<float>(amount));
27610b57cec5SDimitry Andric       bool ignored;
27620b57cec5SDimitry Andric       const llvm::fltSemantics *FS;
27630b57cec5SDimitry Andric       // Don't use getFloatTypeSemantics because Half isn't
27640b57cec5SDimitry Andric       // necessarily represented using the "half" LLVM type.
27650b57cec5SDimitry Andric       if (value->getType()->isFP128Ty())
27660b57cec5SDimitry Andric         FS = &CGF.getTarget().getFloat128Format();
27670b57cec5SDimitry Andric       else if (value->getType()->isHalfTy())
27680b57cec5SDimitry Andric         FS = &CGF.getTarget().getHalfFormat();
2769c9157d92SDimitry Andric       else if (value->getType()->isBFloatTy())
2770c9157d92SDimitry Andric         FS = &CGF.getTarget().getBFloat16Format();
2771349cc55cSDimitry Andric       else if (value->getType()->isPPC_FP128Ty())
2772349cc55cSDimitry Andric         FS = &CGF.getTarget().getIbm128Format();
27730b57cec5SDimitry Andric       else
27740b57cec5SDimitry Andric         FS = &CGF.getTarget().getLongDoubleFormat();
27750b57cec5SDimitry Andric       F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
27760b57cec5SDimitry Andric       amt = llvm::ConstantFP::get(VMContext, F);
27770b57cec5SDimitry Andric     }
27780b57cec5SDimitry Andric     value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
27790b57cec5SDimitry Andric 
27800b57cec5SDimitry Andric     if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
27810b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
27820b57cec5SDimitry Andric         value = Builder.CreateCall(
27830b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,
27840b57cec5SDimitry Andric                                  CGF.CGM.FloatTy),
27850b57cec5SDimitry Andric             value, "incdec.conv");
27860b57cec5SDimitry Andric       } else {
27870b57cec5SDimitry Andric         value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv");
27880b57cec5SDimitry Andric       }
27890b57cec5SDimitry Andric     }
27900b57cec5SDimitry Andric 
27915ffd83dbSDimitry Andric   // Fixed-point types.
27925ffd83dbSDimitry Andric   } else if (type->isFixedPointType()) {
27935ffd83dbSDimitry Andric     // Fixed-point types are tricky. In some cases, it isn't possible to
27945ffd83dbSDimitry Andric     // represent a 1 or a -1 in the type at all. Piggyback off of
27955ffd83dbSDimitry Andric     // EmitFixedPointBinOp to avoid having to reimplement saturation.
27965ffd83dbSDimitry Andric     BinOpInfo Info;
27975ffd83dbSDimitry Andric     Info.E = E;
27985ffd83dbSDimitry Andric     Info.Ty = E->getType();
27995ffd83dbSDimitry Andric     Info.Opcode = isInc ? BO_Add : BO_Sub;
28005ffd83dbSDimitry Andric     Info.LHS = value;
28015ffd83dbSDimitry Andric     Info.RHS = llvm::ConstantInt::get(value->getType(), 1, false);
28025ffd83dbSDimitry Andric     // If the type is signed, it's better to represent this as +(-1) or -(-1),
28035ffd83dbSDimitry Andric     // since -1 is guaranteed to be representable.
28045ffd83dbSDimitry Andric     if (type->isSignedFixedPointType()) {
28055ffd83dbSDimitry Andric       Info.Opcode = isInc ? BO_Sub : BO_Add;
28065ffd83dbSDimitry Andric       Info.RHS = Builder.CreateNeg(Info.RHS);
28075ffd83dbSDimitry Andric     }
28085ffd83dbSDimitry Andric     // Now, convert from our invented integer literal to the type of the unary
28095ffd83dbSDimitry Andric     // op. This will upscale and saturate if necessary. This value can become
28105ffd83dbSDimitry Andric     // undef in some cases.
2811e8d8bef9SDimitry Andric     llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
2812e8d8bef9SDimitry Andric     auto DstSema = CGF.getContext().getFixedPointSemantics(Info.Ty);
2813e8d8bef9SDimitry Andric     Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS, true, DstSema);
28145ffd83dbSDimitry Andric     value = EmitFixedPointBinOp(Info);
28155ffd83dbSDimitry Andric 
28160b57cec5SDimitry Andric   // Objective-C pointer types.
28170b57cec5SDimitry Andric   } else {
28180b57cec5SDimitry Andric     const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>();
28190b57cec5SDimitry Andric 
28200b57cec5SDimitry Andric     CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType());
28210b57cec5SDimitry Andric     if (!isInc) size = -size;
28220b57cec5SDimitry Andric     llvm::Value *sizeValue =
28230b57cec5SDimitry Andric       llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
28240b57cec5SDimitry Andric 
28250b57cec5SDimitry Andric     if (CGF.getLangOpts().isSignedOverflowDefined())
2826fe6060f1SDimitry Andric       value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
28270b57cec5SDimitry Andric     else
28280eae32dcSDimitry Andric       value = CGF.EmitCheckedInBoundsGEP(
28290eae32dcSDimitry Andric           CGF.Int8Ty, value, sizeValue, /*SignedIndices=*/false, isSubtraction,
28300b57cec5SDimitry Andric           E->getExprLoc(), "incdec.objptr");
28310b57cec5SDimitry Andric     value = Builder.CreateBitCast(value, input->getType());
28320b57cec5SDimitry Andric   }
28330b57cec5SDimitry Andric 
28340b57cec5SDimitry Andric   if (atomicPHI) {
28350b57cec5SDimitry Andric     llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
28360b57cec5SDimitry Andric     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
28370b57cec5SDimitry Andric     auto Pair = CGF.EmitAtomicCompareExchange(
28380b57cec5SDimitry Andric         LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
28390b57cec5SDimitry Andric     llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
28400b57cec5SDimitry Andric     llvm::Value *success = Pair.second;
28410b57cec5SDimitry Andric     atomicPHI->addIncoming(old, curBlock);
28420b57cec5SDimitry Andric     Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
28430b57cec5SDimitry Andric     Builder.SetInsertPoint(contBB);
28440b57cec5SDimitry Andric     return isPre ? value : input;
28450b57cec5SDimitry Andric   }
28460b57cec5SDimitry Andric 
28470b57cec5SDimitry Andric   // Store the updated result through the lvalue.
28480b57cec5SDimitry Andric   if (LV.isBitField())
28490b57cec5SDimitry Andric     CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
28500b57cec5SDimitry Andric   else
28510b57cec5SDimitry Andric     CGF.EmitStoreThroughLValue(RValue::get(value), LV);
28520b57cec5SDimitry Andric 
28530b57cec5SDimitry Andric   // If this is a postinc, return the value read from memory, otherwise use the
28540b57cec5SDimitry Andric   // updated value.
28550b57cec5SDimitry Andric   return isPre ? value : input;
28560b57cec5SDimitry Andric }
28570b57cec5SDimitry Andric 
28580b57cec5SDimitry Andric 
VisitUnaryPlus(const UnaryOperator * E,QualType PromotionType)2859bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
2860bdd1243dSDimitry Andric                                          QualType PromotionType) {
2861bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
2862bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
2863bdd1243dSDimitry Andric                              : PromotionType;
2864bdd1243dSDimitry Andric   Value *result = VisitPlus(E, promotionTy);
2865bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
2866bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
2867bdd1243dSDimitry Andric   return result;
2868bdd1243dSDimitry Andric }
28690b57cec5SDimitry Andric 
VisitPlus(const UnaryOperator * E,QualType PromotionType)2870bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitPlus(const UnaryOperator *E,
2871bdd1243dSDimitry Andric                                     QualType PromotionType) {
2872bdd1243dSDimitry Andric   // This differs from gcc, though, most likely due to a bug in gcc.
28730b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
2874bdd1243dSDimitry Andric   if (!PromotionType.isNull())
2875bdd1243dSDimitry Andric     return CGF.EmitPromotedScalarExpr(E->getSubExpr(), PromotionType);
2876bdd1243dSDimitry Andric   return Visit(E->getSubExpr());
2877bdd1243dSDimitry Andric }
2878bdd1243dSDimitry Andric 
VisitUnaryMinus(const UnaryOperator * E,QualType PromotionType)2879bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
2880bdd1243dSDimitry Andric                                           QualType PromotionType) {
2881bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
2882bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
2883bdd1243dSDimitry Andric                              : PromotionType;
2884bdd1243dSDimitry Andric   Value *result = VisitMinus(E, promotionTy);
2885bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
2886bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
2887bdd1243dSDimitry Andric   return result;
2888bdd1243dSDimitry Andric }
2889bdd1243dSDimitry Andric 
VisitMinus(const UnaryOperator * E,QualType PromotionType)2890bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitMinus(const UnaryOperator *E,
2891bdd1243dSDimitry Andric                                      QualType PromotionType) {
2892bdd1243dSDimitry Andric   TestAndClearIgnoreResultAssign();
2893bdd1243dSDimitry Andric   Value *Op;
2894bdd1243dSDimitry Andric   if (!PromotionType.isNull())
2895bdd1243dSDimitry Andric     Op = CGF.EmitPromotedScalarExpr(E->getSubExpr(), PromotionType);
2896bdd1243dSDimitry Andric   else
2897bdd1243dSDimitry Andric     Op = Visit(E->getSubExpr());
2898a7dea167SDimitry Andric 
2899a7dea167SDimitry Andric   // Generate a unary FNeg for FP ops.
2900a7dea167SDimitry Andric   if (Op->getType()->isFPOrFPVectorTy())
2901a7dea167SDimitry Andric     return Builder.CreateFNeg(Op, "fneg");
2902a7dea167SDimitry Andric 
29030b57cec5SDimitry Andric   // Emit unary minus with EmitSub so we handle overflow cases etc.
29040b57cec5SDimitry Andric   BinOpInfo BinOp;
2905a7dea167SDimitry Andric   BinOp.RHS = Op;
29060b57cec5SDimitry Andric   BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
29070b57cec5SDimitry Andric   BinOp.Ty = E->getType();
29080b57cec5SDimitry Andric   BinOp.Opcode = BO_Sub;
29095ffd83dbSDimitry Andric   BinOp.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
29100b57cec5SDimitry Andric   BinOp.E = E;
29110b57cec5SDimitry Andric   return EmitSub(BinOp);
29120b57cec5SDimitry Andric }
29130b57cec5SDimitry Andric 
VisitUnaryNot(const UnaryOperator * E)29140b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
29150b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
29160b57cec5SDimitry Andric   Value *Op = Visit(E->getSubExpr());
2917bdd1243dSDimitry Andric   return Builder.CreateNot(Op, "not");
29180b57cec5SDimitry Andric }
29190b57cec5SDimitry Andric 
VisitUnaryLNot(const UnaryOperator * E)29200b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
29210b57cec5SDimitry Andric   // Perform vector logical not on comparison with zero vector.
29225ffd83dbSDimitry Andric   if (E->getType()->isVectorType() &&
29235ffd83dbSDimitry Andric       E->getType()->castAs<VectorType>()->getVectorKind() ==
2924c9157d92SDimitry Andric           VectorKind::Generic) {
29250b57cec5SDimitry Andric     Value *Oper = Visit(E->getSubExpr());
29260b57cec5SDimitry Andric     Value *Zero = llvm::Constant::getNullValue(Oper->getType());
29270b57cec5SDimitry Andric     Value *Result;
29285ffd83dbSDimitry Andric     if (Oper->getType()->isFPOrFPVectorTy()) {
29295ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
29305ffd83dbSDimitry Andric           CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
29310b57cec5SDimitry Andric       Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
29325ffd83dbSDimitry Andric     } else
29330b57cec5SDimitry Andric       Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
29340b57cec5SDimitry Andric     return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
29350b57cec5SDimitry Andric   }
29360b57cec5SDimitry Andric 
29370b57cec5SDimitry Andric   // Compare operand to zero.
29380b57cec5SDimitry Andric   Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
29390b57cec5SDimitry Andric 
29400b57cec5SDimitry Andric   // Invert value.
29410b57cec5SDimitry Andric   // TODO: Could dynamically modify easy computations here.  For example, if
29420b57cec5SDimitry Andric   // the operand is an icmp ne, turn into icmp eq.
29430b57cec5SDimitry Andric   BoolVal = Builder.CreateNot(BoolVal, "lnot");
29440b57cec5SDimitry Andric 
29450b57cec5SDimitry Andric   // ZExt result to the expr type.
29460b57cec5SDimitry Andric   return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
29470b57cec5SDimitry Andric }
29480b57cec5SDimitry Andric 
VisitOffsetOfExpr(OffsetOfExpr * E)29490b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
29500b57cec5SDimitry Andric   // Try folding the offsetof to a constant.
29510b57cec5SDimitry Andric   Expr::EvalResult EVResult;
29520b57cec5SDimitry Andric   if (E->EvaluateAsInt(EVResult, CGF.getContext())) {
29530b57cec5SDimitry Andric     llvm::APSInt Value = EVResult.Val.getInt();
29540b57cec5SDimitry Andric     return Builder.getInt(Value);
29550b57cec5SDimitry Andric   }
29560b57cec5SDimitry Andric 
29570b57cec5SDimitry Andric   // Loop over the components of the offsetof to compute the value.
29580b57cec5SDimitry Andric   unsigned n = E->getNumComponents();
29590b57cec5SDimitry Andric   llvm::Type* ResultType = ConvertType(E->getType());
29600b57cec5SDimitry Andric   llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
29610b57cec5SDimitry Andric   QualType CurrentType = E->getTypeSourceInfo()->getType();
29620b57cec5SDimitry Andric   for (unsigned i = 0; i != n; ++i) {
29630b57cec5SDimitry Andric     OffsetOfNode ON = E->getComponent(i);
29640b57cec5SDimitry Andric     llvm::Value *Offset = nullptr;
29650b57cec5SDimitry Andric     switch (ON.getKind()) {
29660b57cec5SDimitry Andric     case OffsetOfNode::Array: {
29670b57cec5SDimitry Andric       // Compute the index
29680b57cec5SDimitry Andric       Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
29690b57cec5SDimitry Andric       llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
29700b57cec5SDimitry Andric       bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType();
29710b57cec5SDimitry Andric       Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv");
29720b57cec5SDimitry Andric 
29730b57cec5SDimitry Andric       // Save the element type
29740b57cec5SDimitry Andric       CurrentType =
29750b57cec5SDimitry Andric           CGF.getContext().getAsArrayType(CurrentType)->getElementType();
29760b57cec5SDimitry Andric 
29770b57cec5SDimitry Andric       // Compute the element size
29780b57cec5SDimitry Andric       llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
29790b57cec5SDimitry Andric           CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity());
29800b57cec5SDimitry Andric 
29810b57cec5SDimitry Andric       // Multiply out to compute the result
29820b57cec5SDimitry Andric       Offset = Builder.CreateMul(Idx, ElemSize);
29830b57cec5SDimitry Andric       break;
29840b57cec5SDimitry Andric     }
29850b57cec5SDimitry Andric 
29860b57cec5SDimitry Andric     case OffsetOfNode::Field: {
29870b57cec5SDimitry Andric       FieldDecl *MemberDecl = ON.getField();
2988a7dea167SDimitry Andric       RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
29890b57cec5SDimitry Andric       const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
29900b57cec5SDimitry Andric 
29910b57cec5SDimitry Andric       // Compute the index of the field in its parent.
29920b57cec5SDimitry Andric       unsigned i = 0;
29930b57cec5SDimitry Andric       // FIXME: It would be nice if we didn't have to loop here!
29940b57cec5SDimitry Andric       for (RecordDecl::field_iterator Field = RD->field_begin(),
29950b57cec5SDimitry Andric                                       FieldEnd = RD->field_end();
29960b57cec5SDimitry Andric            Field != FieldEnd; ++Field, ++i) {
29970b57cec5SDimitry Andric         if (*Field == MemberDecl)
29980b57cec5SDimitry Andric           break;
29990b57cec5SDimitry Andric       }
30000b57cec5SDimitry Andric       assert(i < RL.getFieldCount() && "offsetof field in wrong type");
30010b57cec5SDimitry Andric 
30020b57cec5SDimitry Andric       // Compute the offset to the field
30030b57cec5SDimitry Andric       int64_t OffsetInt = RL.getFieldOffset(i) /
30040b57cec5SDimitry Andric                           CGF.getContext().getCharWidth();
30050b57cec5SDimitry Andric       Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
30060b57cec5SDimitry Andric 
30070b57cec5SDimitry Andric       // Save the element type.
30080b57cec5SDimitry Andric       CurrentType = MemberDecl->getType();
30090b57cec5SDimitry Andric       break;
30100b57cec5SDimitry Andric     }
30110b57cec5SDimitry Andric 
30120b57cec5SDimitry Andric     case OffsetOfNode::Identifier:
30130b57cec5SDimitry Andric       llvm_unreachable("dependent __builtin_offsetof");
30140b57cec5SDimitry Andric 
30150b57cec5SDimitry Andric     case OffsetOfNode::Base: {
30160b57cec5SDimitry Andric       if (ON.getBase()->isVirtual()) {
30170b57cec5SDimitry Andric         CGF.ErrorUnsupported(E, "virtual base in offsetof");
30180b57cec5SDimitry Andric         continue;
30190b57cec5SDimitry Andric       }
30200b57cec5SDimitry Andric 
3021a7dea167SDimitry Andric       RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
30220b57cec5SDimitry Andric       const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
30230b57cec5SDimitry Andric 
30240b57cec5SDimitry Andric       // Save the element type.
30250b57cec5SDimitry Andric       CurrentType = ON.getBase()->getType();
30260b57cec5SDimitry Andric 
30270b57cec5SDimitry Andric       // Compute the offset to the base.
302881ad6265SDimitry Andric       auto *BaseRT = CurrentType->castAs<RecordType>();
302981ad6265SDimitry Andric       auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
30300b57cec5SDimitry Andric       CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD);
30310b57cec5SDimitry Andric       Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
30320b57cec5SDimitry Andric       break;
30330b57cec5SDimitry Andric     }
30340b57cec5SDimitry Andric     }
30350b57cec5SDimitry Andric     Result = Builder.CreateAdd(Result, Offset);
30360b57cec5SDimitry Andric   }
30370b57cec5SDimitry Andric   return Result;
30380b57cec5SDimitry Andric }
30390b57cec5SDimitry Andric 
30400b57cec5SDimitry Andric /// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of
30410b57cec5SDimitry Andric /// argument of the sizeof expression as an integer.
30420b57cec5SDimitry Andric Value *
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)30430b57cec5SDimitry Andric ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
30440b57cec5SDimitry Andric                               const UnaryExprOrTypeTraitExpr *E) {
30450b57cec5SDimitry Andric   QualType TypeToSize = E->getTypeOfArgument();
3046c9157d92SDimitry Andric   if (auto Kind = E->getKind();
3047c9157d92SDimitry Andric       Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
30480b57cec5SDimitry Andric     if (const VariableArrayType *VAT =
30490b57cec5SDimitry Andric             CGF.getContext().getAsVariableArrayType(TypeToSize)) {
30500b57cec5SDimitry Andric       if (E->isArgumentType()) {
30510b57cec5SDimitry Andric         // sizeof(type) - make sure to emit the VLA size.
30520b57cec5SDimitry Andric         CGF.EmitVariablyModifiedType(TypeToSize);
30530b57cec5SDimitry Andric       } else {
30540b57cec5SDimitry Andric         // C99 6.5.3.4p2: If the argument is an expression of type
30550b57cec5SDimitry Andric         // VLA, it is evaluated.
30560b57cec5SDimitry Andric         CGF.EmitIgnoredExpr(E->getArgumentExpr());
30570b57cec5SDimitry Andric       }
30580b57cec5SDimitry Andric 
30590b57cec5SDimitry Andric       auto VlaSize = CGF.getVLASize(VAT);
30600b57cec5SDimitry Andric       llvm::Value *size = VlaSize.NumElts;
30610b57cec5SDimitry Andric 
30620b57cec5SDimitry Andric       // Scale the number of non-VLA elements by the non-VLA element size.
30630b57cec5SDimitry Andric       CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type);
30640b57cec5SDimitry Andric       if (!eltSize.isOne())
30650b57cec5SDimitry Andric         size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size);
30660b57cec5SDimitry Andric 
30670b57cec5SDimitry Andric       return size;
30680b57cec5SDimitry Andric     }
30690b57cec5SDimitry Andric   } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) {
30700b57cec5SDimitry Andric     auto Alignment =
30710b57cec5SDimitry Andric         CGF.getContext()
30720b57cec5SDimitry Andric             .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
30730b57cec5SDimitry Andric                 E->getTypeOfArgument()->getPointeeType()))
30740b57cec5SDimitry Andric             .getQuantity();
30750b57cec5SDimitry Andric     return llvm::ConstantInt::get(CGF.SizeTy, Alignment);
3076c9157d92SDimitry Andric   } else if (E->getKind() == UETT_VectorElements) {
3077c9157d92SDimitry Andric     auto *VecTy = cast<llvm::VectorType>(ConvertType(E->getTypeOfArgument()));
3078c9157d92SDimitry Andric     return Builder.CreateElementCount(CGF.SizeTy, VecTy->getElementCount());
30790b57cec5SDimitry Andric   }
30800b57cec5SDimitry Andric 
30810b57cec5SDimitry Andric   // If this isn't sizeof(vla), the result must be constant; use the constant
30820b57cec5SDimitry Andric   // folding logic so we don't have to duplicate it here.
30830b57cec5SDimitry Andric   return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext()));
30840b57cec5SDimitry Andric }
30850b57cec5SDimitry Andric 
VisitUnaryReal(const UnaryOperator * E,QualType PromotionType)3086bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E,
3087bdd1243dSDimitry Andric                                          QualType PromotionType) {
3088bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
3089bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
3090bdd1243dSDimitry Andric                              : PromotionType;
3091bdd1243dSDimitry Andric   Value *result = VisitReal(E, promotionTy);
3092bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
3093bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
3094bdd1243dSDimitry Andric   return result;
3095bdd1243dSDimitry Andric }
3096bdd1243dSDimitry Andric 
VisitReal(const UnaryOperator * E,QualType PromotionType)3097bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitReal(const UnaryOperator *E,
3098bdd1243dSDimitry Andric                                     QualType PromotionType) {
30990b57cec5SDimitry Andric   Expr *Op = E->getSubExpr();
31000b57cec5SDimitry Andric   if (Op->getType()->isAnyComplexType()) {
31010b57cec5SDimitry Andric     // If it's an l-value, load through the appropriate subobject l-value.
31020b57cec5SDimitry Andric     // Note that we have to ask E because Op might be an l-value that
31030b57cec5SDimitry Andric     // this won't work for, e.g. an Obj-C property.
3104bdd1243dSDimitry Andric     if (E->isGLValue())  {
3105bdd1243dSDimitry Andric       if (!PromotionType.isNull()) {
3106bdd1243dSDimitry Andric         CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
3107bdd1243dSDimitry Andric             Op, /*IgnoreReal*/ IgnoreResultAssign, /*IgnoreImag*/ true);
3108bdd1243dSDimitry Andric         if (result.first)
3109bdd1243dSDimitry Andric           result.first = CGF.EmitPromotedValue(result, PromotionType).first;
3110bdd1243dSDimitry Andric         return result.first;
3111bdd1243dSDimitry Andric       } else {
3112bdd1243dSDimitry Andric         return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3113bdd1243dSDimitry Andric             .getScalarVal();
3114bdd1243dSDimitry Andric       }
3115bdd1243dSDimitry Andric     }
31160b57cec5SDimitry Andric     // Otherwise, calculate and project.
31170b57cec5SDimitry Andric     return CGF.EmitComplexExpr(Op, false, true).first;
31180b57cec5SDimitry Andric   }
31190b57cec5SDimitry Andric 
3120bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3121bdd1243dSDimitry Andric     return CGF.EmitPromotedScalarExpr(Op, PromotionType);
31220b57cec5SDimitry Andric   return Visit(Op);
31230b57cec5SDimitry Andric }
31240b57cec5SDimitry Andric 
VisitUnaryImag(const UnaryOperator * E,QualType PromotionType)3125bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E,
3126bdd1243dSDimitry Andric                                          QualType PromotionType) {
3127bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
3128bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
3129bdd1243dSDimitry Andric                              : PromotionType;
3130bdd1243dSDimitry Andric   Value *result = VisitImag(E, promotionTy);
3131bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
3132bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
3133bdd1243dSDimitry Andric   return result;
3134bdd1243dSDimitry Andric }
3135bdd1243dSDimitry Andric 
VisitImag(const UnaryOperator * E,QualType PromotionType)3136bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitImag(const UnaryOperator *E,
3137bdd1243dSDimitry Andric                                     QualType PromotionType) {
31380b57cec5SDimitry Andric   Expr *Op = E->getSubExpr();
31390b57cec5SDimitry Andric   if (Op->getType()->isAnyComplexType()) {
31400b57cec5SDimitry Andric     // If it's an l-value, load through the appropriate subobject l-value.
31410b57cec5SDimitry Andric     // Note that we have to ask E because Op might be an l-value that
31420b57cec5SDimitry Andric     // this won't work for, e.g. an Obj-C property.
3143bdd1243dSDimitry Andric     if (Op->isGLValue()) {
3144bdd1243dSDimitry Andric       if (!PromotionType.isNull()) {
3145bdd1243dSDimitry Andric         CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
3146bdd1243dSDimitry Andric             Op, /*IgnoreReal*/ true, /*IgnoreImag*/ IgnoreResultAssign);
3147bdd1243dSDimitry Andric         if (result.second)
3148bdd1243dSDimitry Andric           result.second = CGF.EmitPromotedValue(result, PromotionType).second;
3149bdd1243dSDimitry Andric         return result.second;
3150bdd1243dSDimitry Andric       } else {
3151bdd1243dSDimitry Andric         return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3152bdd1243dSDimitry Andric             .getScalarVal();
3153bdd1243dSDimitry Andric       }
3154bdd1243dSDimitry Andric     }
31550b57cec5SDimitry Andric     // Otherwise, calculate and project.
31560b57cec5SDimitry Andric     return CGF.EmitComplexExpr(Op, true, false).second;
31570b57cec5SDimitry Andric   }
31580b57cec5SDimitry Andric 
31590b57cec5SDimitry Andric   // __imag on a scalar returns zero.  Emit the subexpr to ensure side
31600b57cec5SDimitry Andric   // effects are evaluated, but not the actual value.
31610b57cec5SDimitry Andric   if (Op->isGLValue())
31620b57cec5SDimitry Andric     CGF.EmitLValue(Op);
3163bdd1243dSDimitry Andric   else if (!PromotionType.isNull())
3164bdd1243dSDimitry Andric     CGF.EmitPromotedScalarExpr(Op, PromotionType);
31650b57cec5SDimitry Andric   else
31660b57cec5SDimitry Andric     CGF.EmitScalarExpr(Op, true);
3167bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3168bdd1243dSDimitry Andric     return llvm::Constant::getNullValue(ConvertType(PromotionType));
31690b57cec5SDimitry Andric   return llvm::Constant::getNullValue(ConvertType(E->getType()));
31700b57cec5SDimitry Andric }
31710b57cec5SDimitry Andric 
31720b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
31730b57cec5SDimitry Andric //                           Binary Operators
31740b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
31750b57cec5SDimitry Andric 
EmitPromotedValue(Value * result,QualType PromotionType)3176bdd1243dSDimitry Andric Value *ScalarExprEmitter::EmitPromotedValue(Value *result,
3177bdd1243dSDimitry Andric                                             QualType PromotionType) {
3178bdd1243dSDimitry Andric   return CGF.Builder.CreateFPExt(result, ConvertType(PromotionType), "ext");
3179bdd1243dSDimitry Andric }
3180bdd1243dSDimitry Andric 
EmitUnPromotedValue(Value * result,QualType ExprType)3181bdd1243dSDimitry Andric Value *ScalarExprEmitter::EmitUnPromotedValue(Value *result,
3182bdd1243dSDimitry Andric                                               QualType ExprType) {
3183bdd1243dSDimitry Andric   return CGF.Builder.CreateFPTrunc(result, ConvertType(ExprType), "unpromotion");
3184bdd1243dSDimitry Andric }
3185bdd1243dSDimitry Andric 
EmitPromoted(const Expr * E,QualType PromotionType)3186bdd1243dSDimitry Andric Value *ScalarExprEmitter::EmitPromoted(const Expr *E, QualType PromotionType) {
3187bdd1243dSDimitry Andric   E = E->IgnoreParens();
3188bdd1243dSDimitry Andric   if (auto BO = dyn_cast<BinaryOperator>(E)) {
3189bdd1243dSDimitry Andric     switch (BO->getOpcode()) {
3190bdd1243dSDimitry Andric #define HANDLE_BINOP(OP)                                                       \
3191bdd1243dSDimitry Andric   case BO_##OP:                                                                \
3192bdd1243dSDimitry Andric     return Emit##OP(EmitBinOps(BO, PromotionType));
3193bdd1243dSDimitry Andric       HANDLE_BINOP(Add)
3194bdd1243dSDimitry Andric       HANDLE_BINOP(Sub)
3195bdd1243dSDimitry Andric       HANDLE_BINOP(Mul)
3196bdd1243dSDimitry Andric       HANDLE_BINOP(Div)
3197bdd1243dSDimitry Andric #undef HANDLE_BINOP
3198bdd1243dSDimitry Andric     default:
3199bdd1243dSDimitry Andric       break;
3200bdd1243dSDimitry Andric     }
3201bdd1243dSDimitry Andric   } else if (auto UO = dyn_cast<UnaryOperator>(E)) {
3202bdd1243dSDimitry Andric     switch (UO->getOpcode()) {
3203bdd1243dSDimitry Andric     case UO_Imag:
3204bdd1243dSDimitry Andric       return VisitImag(UO, PromotionType);
3205bdd1243dSDimitry Andric     case UO_Real:
3206bdd1243dSDimitry Andric       return VisitReal(UO, PromotionType);
3207bdd1243dSDimitry Andric     case UO_Minus:
3208bdd1243dSDimitry Andric       return VisitMinus(UO, PromotionType);
3209bdd1243dSDimitry Andric     case UO_Plus:
3210bdd1243dSDimitry Andric       return VisitPlus(UO, PromotionType);
3211bdd1243dSDimitry Andric     default:
3212bdd1243dSDimitry Andric       break;
3213bdd1243dSDimitry Andric     }
3214bdd1243dSDimitry Andric   }
3215bdd1243dSDimitry Andric   auto result = Visit(const_cast<Expr *>(E));
3216bdd1243dSDimitry Andric   if (result) {
3217bdd1243dSDimitry Andric     if (!PromotionType.isNull())
3218bdd1243dSDimitry Andric       return EmitPromotedValue(result, PromotionType);
3219bdd1243dSDimitry Andric     else
3220bdd1243dSDimitry Andric       return EmitUnPromotedValue(result, E->getType());
3221bdd1243dSDimitry Andric   }
3222bdd1243dSDimitry Andric   return result;
3223bdd1243dSDimitry Andric }
3224bdd1243dSDimitry Andric 
EmitBinOps(const BinaryOperator * E,QualType PromotionType)3225bdd1243dSDimitry Andric BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E,
3226bdd1243dSDimitry Andric                                         QualType PromotionType) {
32270b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
32280b57cec5SDimitry Andric   BinOpInfo Result;
3229bdd1243dSDimitry Andric   Result.LHS = CGF.EmitPromotedScalarExpr(E->getLHS(), PromotionType);
3230bdd1243dSDimitry Andric   Result.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionType);
3231bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3232bdd1243dSDimitry Andric     Result.Ty = PromotionType;
3233bdd1243dSDimitry Andric   else
32340b57cec5SDimitry Andric     Result.Ty  = E->getType();
32350b57cec5SDimitry Andric   Result.Opcode = E->getOpcode();
32365ffd83dbSDimitry Andric   Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
32370b57cec5SDimitry Andric   Result.E = E;
32380b57cec5SDimitry Andric   return Result;
32390b57cec5SDimitry Andric }
32400b57cec5SDimitry Andric 
EmitCompoundAssignLValue(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &),Value * & Result)32410b57cec5SDimitry Andric LValue ScalarExprEmitter::EmitCompoundAssignLValue(
32420b57cec5SDimitry Andric                                               const CompoundAssignOperator *E,
32430b57cec5SDimitry Andric                         Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
32440b57cec5SDimitry Andric                                                    Value *&Result) {
32450b57cec5SDimitry Andric   QualType LHSTy = E->getLHS()->getType();
32460b57cec5SDimitry Andric   BinOpInfo OpInfo;
32470b57cec5SDimitry Andric 
32480b57cec5SDimitry Andric   if (E->getComputationResultType()->isAnyComplexType())
32490b57cec5SDimitry Andric     return CGF.EmitScalarCompoundAssignWithComplex(E, Result);
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric   // Emit the RHS first.  __block variables need to have the rhs evaluated
32520b57cec5SDimitry Andric   // first, plus this should improve codegen a little.
3253bdd1243dSDimitry Andric 
3254bdd1243dSDimitry Andric   QualType PromotionTypeCR;
3255bdd1243dSDimitry Andric   PromotionTypeCR = getPromotionType(E->getComputationResultType());
3256bdd1243dSDimitry Andric   if (PromotionTypeCR.isNull())
3257bdd1243dSDimitry Andric       PromotionTypeCR = E->getComputationResultType();
3258bdd1243dSDimitry Andric   QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType());
3259bdd1243dSDimitry Andric   QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType());
3260bdd1243dSDimitry Andric   if (!PromotionTypeRHS.isNull())
3261bdd1243dSDimitry Andric     OpInfo.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS);
3262bdd1243dSDimitry Andric   else
32630b57cec5SDimitry Andric     OpInfo.RHS = Visit(E->getRHS());
3264bdd1243dSDimitry Andric   OpInfo.Ty = PromotionTypeCR;
32650b57cec5SDimitry Andric   OpInfo.Opcode = E->getOpcode();
32665ffd83dbSDimitry Andric   OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
32670b57cec5SDimitry Andric   OpInfo.E = E;
32680b57cec5SDimitry Andric   // Load/convert the LHS.
32690b57cec5SDimitry Andric   LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
32700b57cec5SDimitry Andric 
32710b57cec5SDimitry Andric   llvm::PHINode *atomicPHI = nullptr;
32720b57cec5SDimitry Andric   if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
32730b57cec5SDimitry Andric     QualType type = atomicTy->getValueType();
32740b57cec5SDimitry Andric     if (!type->isBooleanType() && type->isIntegerType() &&
32750b57cec5SDimitry Andric         !(type->isUnsignedIntegerType() &&
32760b57cec5SDimitry Andric           CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
32770b57cec5SDimitry Andric         CGF.getLangOpts().getSignedOverflowBehavior() !=
32780b57cec5SDimitry Andric             LangOptions::SOB_Trapping) {
3279480093f4SDimitry Andric       llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3280480093f4SDimitry Andric       llvm::Instruction::BinaryOps Op;
32810b57cec5SDimitry Andric       switch (OpInfo.Opcode) {
32820b57cec5SDimitry Andric         // We don't have atomicrmw operands for *, %, /, <<, >>
32830b57cec5SDimitry Andric         case BO_MulAssign: case BO_DivAssign:
32840b57cec5SDimitry Andric         case BO_RemAssign:
32850b57cec5SDimitry Andric         case BO_ShlAssign:
32860b57cec5SDimitry Andric         case BO_ShrAssign:
32870b57cec5SDimitry Andric           break;
32880b57cec5SDimitry Andric         case BO_AddAssign:
3289480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Add;
3290480093f4SDimitry Andric           Op = llvm::Instruction::Add;
32910b57cec5SDimitry Andric           break;
32920b57cec5SDimitry Andric         case BO_SubAssign:
3293480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Sub;
3294480093f4SDimitry Andric           Op = llvm::Instruction::Sub;
32950b57cec5SDimitry Andric           break;
32960b57cec5SDimitry Andric         case BO_AndAssign:
3297480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::And;
3298480093f4SDimitry Andric           Op = llvm::Instruction::And;
32990b57cec5SDimitry Andric           break;
33000b57cec5SDimitry Andric         case BO_XorAssign:
3301480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Xor;
3302480093f4SDimitry Andric           Op = llvm::Instruction::Xor;
33030b57cec5SDimitry Andric           break;
33040b57cec5SDimitry Andric         case BO_OrAssign:
3305480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Or;
3306480093f4SDimitry Andric           Op = llvm::Instruction::Or;
33070b57cec5SDimitry Andric           break;
33080b57cec5SDimitry Andric         default:
33090b57cec5SDimitry Andric           llvm_unreachable("Invalid compound assignment type");
33100b57cec5SDimitry Andric       }
3311480093f4SDimitry Andric       if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3312480093f4SDimitry Andric         llvm::Value *Amt = CGF.EmitToMemory(
33130b57cec5SDimitry Andric             EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
33140b57cec5SDimitry Andric                                  E->getExprLoc()),
33150b57cec5SDimitry Andric             LHSTy);
3316480093f4SDimitry Andric         Value *OldVal = Builder.CreateAtomicRMW(
3317c9157d92SDimitry Andric             AtomicOp, LHSLV.getAddress(CGF), Amt,
33180b57cec5SDimitry Andric             llvm::AtomicOrdering::SequentiallyConsistent);
3319480093f4SDimitry Andric 
3320480093f4SDimitry Andric         // Since operation is atomic, the result type is guaranteed to be the
3321480093f4SDimitry Andric         // same as the input in LLVM terms.
3322480093f4SDimitry Andric         Result = Builder.CreateBinOp(Op, OldVal, Amt);
33230b57cec5SDimitry Andric         return LHSLV;
33240b57cec5SDimitry Andric       }
33250b57cec5SDimitry Andric     }
33260b57cec5SDimitry Andric     // FIXME: For floating point types, we should be saving and restoring the
33270b57cec5SDimitry Andric     // floating point environment in the loop.
33280b57cec5SDimitry Andric     llvm::BasicBlock *startBB = Builder.GetInsertBlock();
33290b57cec5SDimitry Andric     llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
33300b57cec5SDimitry Andric     OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
33310b57cec5SDimitry Andric     OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type);
33320b57cec5SDimitry Andric     Builder.CreateBr(opBB);
33330b57cec5SDimitry Andric     Builder.SetInsertPoint(opBB);
33340b57cec5SDimitry Andric     atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
33350b57cec5SDimitry Andric     atomicPHI->addIncoming(OpInfo.LHS, startBB);
33360b57cec5SDimitry Andric     OpInfo.LHS = atomicPHI;
33370b57cec5SDimitry Andric   }
33380b57cec5SDimitry Andric   else
33390b57cec5SDimitry Andric     OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
33400b57cec5SDimitry Andric 
3341e8d8bef9SDimitry Andric   CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
33420b57cec5SDimitry Andric   SourceLocation Loc = E->getExprLoc();
3343bdd1243dSDimitry Andric   if (!PromotionTypeLHS.isNull())
3344bdd1243dSDimitry Andric     OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3345bdd1243dSDimitry Andric                                       E->getExprLoc());
3346bdd1243dSDimitry Andric   else
3347bdd1243dSDimitry Andric     OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3348bdd1243dSDimitry Andric                                       E->getComputationLHSType(), Loc);
33490b57cec5SDimitry Andric 
33500b57cec5SDimitry Andric   // Expand the binary operator.
33510b57cec5SDimitry Andric   Result = (this->*Func)(OpInfo);
33520b57cec5SDimitry Andric 
33530b57cec5SDimitry Andric   // Convert the result back to the LHS type,
33540b57cec5SDimitry Andric   // potentially with Implicit Conversion sanitizer check.
3355bdd1243dSDimitry Andric   Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc,
3356bdd1243dSDimitry Andric                                 ScalarConversionOpts(CGF.SanOpts));
33570b57cec5SDimitry Andric 
33580b57cec5SDimitry Andric   if (atomicPHI) {
33590b57cec5SDimitry Andric     llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
33600b57cec5SDimitry Andric     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
33610b57cec5SDimitry Andric     auto Pair = CGF.EmitAtomicCompareExchange(
33620b57cec5SDimitry Andric         LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc());
33630b57cec5SDimitry Andric     llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy);
33640b57cec5SDimitry Andric     llvm::Value *success = Pair.second;
33650b57cec5SDimitry Andric     atomicPHI->addIncoming(old, curBlock);
33660b57cec5SDimitry Andric     Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
33670b57cec5SDimitry Andric     Builder.SetInsertPoint(contBB);
33680b57cec5SDimitry Andric     return LHSLV;
33690b57cec5SDimitry Andric   }
33700b57cec5SDimitry Andric 
33710b57cec5SDimitry Andric   // Store the result value into the LHS lvalue. Bit-fields are handled
33720b57cec5SDimitry Andric   // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
33730b57cec5SDimitry Andric   // 'An assignment expression has the value of the left operand after the
33740b57cec5SDimitry Andric   // assignment...'.
33750b57cec5SDimitry Andric   if (LHSLV.isBitField())
33760b57cec5SDimitry Andric     CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
33770b57cec5SDimitry Andric   else
33780b57cec5SDimitry Andric     CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
33790b57cec5SDimitry Andric 
3380480093f4SDimitry Andric   if (CGF.getLangOpts().OpenMP)
3381480093f4SDimitry Andric     CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
3382480093f4SDimitry Andric                                                                   E->getLHS());
33830b57cec5SDimitry Andric   return LHSLV;
33840b57cec5SDimitry Andric }
33850b57cec5SDimitry Andric 
EmitCompoundAssign(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &))33860b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
33870b57cec5SDimitry Andric                       Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
33880b57cec5SDimitry Andric   bool Ignore = TestAndClearIgnoreResultAssign();
33890b57cec5SDimitry Andric   Value *RHS = nullptr;
33900b57cec5SDimitry Andric   LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
33910b57cec5SDimitry Andric 
33920b57cec5SDimitry Andric   // If the result is clearly ignored, return now.
33930b57cec5SDimitry Andric   if (Ignore)
33940b57cec5SDimitry Andric     return nullptr;
33950b57cec5SDimitry Andric 
33960b57cec5SDimitry Andric   // The result of an assignment in C is the assigned r-value.
33970b57cec5SDimitry Andric   if (!CGF.getLangOpts().CPlusPlus)
33980b57cec5SDimitry Andric     return RHS;
33990b57cec5SDimitry Andric 
34000b57cec5SDimitry Andric   // If the lvalue is non-volatile, return the computed value of the assignment.
34010b57cec5SDimitry Andric   if (!LHS.isVolatileQualified())
34020b57cec5SDimitry Andric     return RHS;
34030b57cec5SDimitry Andric 
34040b57cec5SDimitry Andric   // Otherwise, reload the value.
34050b57cec5SDimitry Andric   return EmitLoadOfLValue(LHS, E->getExprLoc());
34060b57cec5SDimitry Andric }
34070b57cec5SDimitry Andric 
EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo & Ops,llvm::Value * Zero,bool isDiv)34080b57cec5SDimitry Andric void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
34090b57cec5SDimitry Andric     const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
34100b57cec5SDimitry Andric   SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
34110b57cec5SDimitry Andric 
34120b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
34130b57cec5SDimitry Andric     Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
34140b57cec5SDimitry Andric                                     SanitizerKind::IntegerDivideByZero));
34150b57cec5SDimitry Andric   }
34160b57cec5SDimitry Andric 
34170b57cec5SDimitry Andric   const auto *BO = cast<BinaryOperator>(Ops.E);
34180b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
34190b57cec5SDimitry Andric       Ops.Ty->hasSignedIntegerRepresentation() &&
34200b57cec5SDimitry Andric       !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) &&
34210b57cec5SDimitry Andric       Ops.mayHaveIntegerOverflow()) {
34220b57cec5SDimitry Andric     llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
34230b57cec5SDimitry Andric 
34240b57cec5SDimitry Andric     llvm::Value *IntMin =
34250b57cec5SDimitry Andric       Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3426fe6060f1SDimitry Andric     llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
34270b57cec5SDimitry Andric 
34280b57cec5SDimitry Andric     llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
34290b57cec5SDimitry Andric     llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
34300b57cec5SDimitry Andric     llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
34310b57cec5SDimitry Andric     Checks.push_back(
34320b57cec5SDimitry Andric         std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
34330b57cec5SDimitry Andric   }
34340b57cec5SDimitry Andric 
34350b57cec5SDimitry Andric   if (Checks.size() > 0)
34360b57cec5SDimitry Andric     EmitBinOpCheck(Checks, Ops);
34370b57cec5SDimitry Andric }
34380b57cec5SDimitry Andric 
EmitDiv(const BinOpInfo & Ops)34390b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
34400b57cec5SDimitry Andric   {
34410b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
34420b57cec5SDimitry Andric     if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
34430b57cec5SDimitry Andric          CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
34440b57cec5SDimitry Andric         Ops.Ty->isIntegerType() &&
34450b57cec5SDimitry Andric         (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
34460b57cec5SDimitry Andric       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
34470b57cec5SDimitry Andric       EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
34480b57cec5SDimitry Andric     } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
34490b57cec5SDimitry Andric                Ops.Ty->isRealFloatingType() &&
34500b57cec5SDimitry Andric                Ops.mayHaveFloatDivisionByZero()) {
34510b57cec5SDimitry Andric       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
34520b57cec5SDimitry Andric       llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
34530b57cec5SDimitry Andric       EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
34540b57cec5SDimitry Andric                      Ops);
34550b57cec5SDimitry Andric     }
34560b57cec5SDimitry Andric   }
34570b57cec5SDimitry Andric 
3458fe6060f1SDimitry Andric   if (Ops.Ty->isConstantMatrixType()) {
345981ad6265SDimitry Andric     llvm::MatrixBuilder MB(Builder);
3460fe6060f1SDimitry Andric     // We need to check the types of the operands of the operator to get the
3461fe6060f1SDimitry Andric     // correct matrix dimensions.
3462fe6060f1SDimitry Andric     auto *BO = cast<BinaryOperator>(Ops.E);
3463fe6060f1SDimitry Andric     (void)BO;
3464fe6060f1SDimitry Andric     assert(
3465fe6060f1SDimitry Andric         isa<ConstantMatrixType>(BO->getLHS()->getType().getCanonicalType()) &&
3466fe6060f1SDimitry Andric         "first operand must be a matrix");
3467fe6060f1SDimitry Andric     assert(BO->getRHS()->getType().getCanonicalType()->isArithmeticType() &&
3468fe6060f1SDimitry Andric            "second operand must be an arithmetic type");
3469fe6060f1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3470fe6060f1SDimitry Andric     return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3471fe6060f1SDimitry Andric                               Ops.Ty->hasUnsignedIntegerRepresentation());
3472fe6060f1SDimitry Andric   }
3473fe6060f1SDimitry Andric 
34740b57cec5SDimitry Andric   if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
34755ffd83dbSDimitry Andric     llvm::Value *Val;
34765ffd83dbSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
34775ffd83dbSDimitry Andric     Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
3478fe013be4SDimitry Andric     CGF.SetDivFPAccuracy(Val);
34790b57cec5SDimitry Andric     return Val;
34800b57cec5SDimitry Andric   }
34815ffd83dbSDimitry Andric   else if (Ops.isFixedPointOp())
34825ffd83dbSDimitry Andric     return EmitFixedPointBinOp(Ops);
34830b57cec5SDimitry Andric   else if (Ops.Ty->hasUnsignedIntegerRepresentation())
34840b57cec5SDimitry Andric     return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
34850b57cec5SDimitry Andric   else
34860b57cec5SDimitry Andric     return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
34870b57cec5SDimitry Andric }
34880b57cec5SDimitry Andric 
EmitRem(const BinOpInfo & Ops)34890b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
34900b57cec5SDimitry Andric   // Rem in C can't be a floating point type: C99 6.5.5p2.
34910b57cec5SDimitry Andric   if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
34920b57cec5SDimitry Andric        CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
34930b57cec5SDimitry Andric       Ops.Ty->isIntegerType() &&
34940b57cec5SDimitry Andric       (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
34950b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
34960b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
34970b57cec5SDimitry Andric     EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
34980b57cec5SDimitry Andric   }
34990b57cec5SDimitry Andric 
35000b57cec5SDimitry Andric   if (Ops.Ty->hasUnsignedIntegerRepresentation())
35010b57cec5SDimitry Andric     return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
35020b57cec5SDimitry Andric   else
35030b57cec5SDimitry Andric     return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
35040b57cec5SDimitry Andric }
35050b57cec5SDimitry Andric 
EmitOverflowCheckedBinOp(const BinOpInfo & Ops)35060b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
35070b57cec5SDimitry Andric   unsigned IID;
35080b57cec5SDimitry Andric   unsigned OpID = 0;
3509e8d8bef9SDimitry Andric   SanitizerHandler OverflowKind;
35100b57cec5SDimitry Andric 
35110b57cec5SDimitry Andric   bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
35120b57cec5SDimitry Andric   switch (Ops.Opcode) {
35130b57cec5SDimitry Andric   case BO_Add:
35140b57cec5SDimitry Andric   case BO_AddAssign:
35150b57cec5SDimitry Andric     OpID = 1;
35160b57cec5SDimitry Andric     IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
35170b57cec5SDimitry Andric                      llvm::Intrinsic::uadd_with_overflow;
3518e8d8bef9SDimitry Andric     OverflowKind = SanitizerHandler::AddOverflow;
35190b57cec5SDimitry Andric     break;
35200b57cec5SDimitry Andric   case BO_Sub:
35210b57cec5SDimitry Andric   case BO_SubAssign:
35220b57cec5SDimitry Andric     OpID = 2;
35230b57cec5SDimitry Andric     IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
35240b57cec5SDimitry Andric                      llvm::Intrinsic::usub_with_overflow;
3525e8d8bef9SDimitry Andric     OverflowKind = SanitizerHandler::SubOverflow;
35260b57cec5SDimitry Andric     break;
35270b57cec5SDimitry Andric   case BO_Mul:
35280b57cec5SDimitry Andric   case BO_MulAssign:
35290b57cec5SDimitry Andric     OpID = 3;
35300b57cec5SDimitry Andric     IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
35310b57cec5SDimitry Andric                      llvm::Intrinsic::umul_with_overflow;
3532e8d8bef9SDimitry Andric     OverflowKind = SanitizerHandler::MulOverflow;
35330b57cec5SDimitry Andric     break;
35340b57cec5SDimitry Andric   default:
35350b57cec5SDimitry Andric     llvm_unreachable("Unsupported operation for overflow detection");
35360b57cec5SDimitry Andric   }
35370b57cec5SDimitry Andric   OpID <<= 1;
35380b57cec5SDimitry Andric   if (isSigned)
35390b57cec5SDimitry Andric     OpID |= 1;
35400b57cec5SDimitry Andric 
35410b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
35420b57cec5SDimitry Andric   llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
35430b57cec5SDimitry Andric 
35440b57cec5SDimitry Andric   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
35450b57cec5SDimitry Andric 
35460b57cec5SDimitry Andric   Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
35470b57cec5SDimitry Andric   Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
35480b57cec5SDimitry Andric   Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
35490b57cec5SDimitry Andric 
35500b57cec5SDimitry Andric   // Handle overflow with llvm.trap if no custom handler has been specified.
35510b57cec5SDimitry Andric   const std::string *handlerName =
35520b57cec5SDimitry Andric     &CGF.getLangOpts().OverflowHandler;
35530b57cec5SDimitry Andric   if (handlerName->empty()) {
35540b57cec5SDimitry Andric     // If the signed-integer-overflow sanitizer is enabled, emit a call to its
35550b57cec5SDimitry Andric     // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
35560b57cec5SDimitry Andric     if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
35570b57cec5SDimitry Andric       llvm::Value *NotOverflow = Builder.CreateNot(overflow);
35580b57cec5SDimitry Andric       SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
35590b57cec5SDimitry Andric                               : SanitizerKind::UnsignedIntegerOverflow;
35600b57cec5SDimitry Andric       EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
35610b57cec5SDimitry Andric     } else
3562e8d8bef9SDimitry Andric       CGF.EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
35630b57cec5SDimitry Andric     return result;
35640b57cec5SDimitry Andric   }
35650b57cec5SDimitry Andric 
35660b57cec5SDimitry Andric   // Branch in case of overflow.
35670b57cec5SDimitry Andric   llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
35680b57cec5SDimitry Andric   llvm::BasicBlock *continueBB =
35690b57cec5SDimitry Andric       CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode());
35700b57cec5SDimitry Andric   llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
35710b57cec5SDimitry Andric 
35720b57cec5SDimitry Andric   Builder.CreateCondBr(overflow, overflowBB, continueBB);
35730b57cec5SDimitry Andric 
35740b57cec5SDimitry Andric   // If an overflow handler is set, then we want to call it and then use its
35750b57cec5SDimitry Andric   // result, if it returns.
35760b57cec5SDimitry Andric   Builder.SetInsertPoint(overflowBB);
35770b57cec5SDimitry Andric 
35780b57cec5SDimitry Andric   // Get the overflow handler.
35790b57cec5SDimitry Andric   llvm::Type *Int8Ty = CGF.Int8Ty;
35800b57cec5SDimitry Andric   llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty };
35810b57cec5SDimitry Andric   llvm::FunctionType *handlerTy =
35820b57cec5SDimitry Andric       llvm::FunctionType::get(CGF.Int64Ty, argTypes, true);
35830b57cec5SDimitry Andric   llvm::FunctionCallee handler =
35840b57cec5SDimitry Andric       CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
35850b57cec5SDimitry Andric 
35860b57cec5SDimitry Andric   // Sign extend the args to 64-bit, so that we can use the same handler for
35870b57cec5SDimitry Andric   // all types of overflow.
35880b57cec5SDimitry Andric   llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty);
35890b57cec5SDimitry Andric   llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty);
35900b57cec5SDimitry Andric 
35910b57cec5SDimitry Andric   // Call the handler with the two arguments, the operation, and the size of
35920b57cec5SDimitry Andric   // the result.
35930b57cec5SDimitry Andric   llvm::Value *handlerArgs[] = {
35940b57cec5SDimitry Andric     lhs,
35950b57cec5SDimitry Andric     rhs,
35960b57cec5SDimitry Andric     Builder.getInt8(OpID),
35970b57cec5SDimitry Andric     Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
35980b57cec5SDimitry Andric   };
35990b57cec5SDimitry Andric   llvm::Value *handlerResult =
36000b57cec5SDimitry Andric     CGF.EmitNounwindRuntimeCall(handler, handlerArgs);
36010b57cec5SDimitry Andric 
36020b57cec5SDimitry Andric   // Truncate the result back to the desired size.
36030b57cec5SDimitry Andric   handlerResult = Builder.CreateTrunc(handlerResult, opTy);
36040b57cec5SDimitry Andric   Builder.CreateBr(continueBB);
36050b57cec5SDimitry Andric 
36060b57cec5SDimitry Andric   Builder.SetInsertPoint(continueBB);
36070b57cec5SDimitry Andric   llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
36080b57cec5SDimitry Andric   phi->addIncoming(result, initialBB);
36090b57cec5SDimitry Andric   phi->addIncoming(handlerResult, overflowBB);
36100b57cec5SDimitry Andric 
36110b57cec5SDimitry Andric   return phi;
36120b57cec5SDimitry Andric }
36130b57cec5SDimitry Andric 
36140b57cec5SDimitry Andric /// Emit pointer + index arithmetic.
emitPointerArithmetic(CodeGenFunction & CGF,const BinOpInfo & op,bool isSubtraction)36150b57cec5SDimitry Andric static Value *emitPointerArithmetic(CodeGenFunction &CGF,
36160b57cec5SDimitry Andric                                     const BinOpInfo &op,
36170b57cec5SDimitry Andric                                     bool isSubtraction) {
36180b57cec5SDimitry Andric   // Must have binary (not unary) expr here.  Unary pointer
36190b57cec5SDimitry Andric   // increment/decrement doesn't use this path.
36200b57cec5SDimitry Andric   const BinaryOperator *expr = cast<BinaryOperator>(op.E);
36210b57cec5SDimitry Andric 
36220b57cec5SDimitry Andric   Value *pointer = op.LHS;
36230b57cec5SDimitry Andric   Expr *pointerOperand = expr->getLHS();
36240b57cec5SDimitry Andric   Value *index = op.RHS;
36250b57cec5SDimitry Andric   Expr *indexOperand = expr->getRHS();
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric   // In a subtraction, the LHS is always the pointer.
36280b57cec5SDimitry Andric   if (!isSubtraction && !pointer->getType()->isPointerTy()) {
36290b57cec5SDimitry Andric     std::swap(pointer, index);
36300b57cec5SDimitry Andric     std::swap(pointerOperand, indexOperand);
36310b57cec5SDimitry Andric   }
36320b57cec5SDimitry Andric 
36330b57cec5SDimitry Andric   bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
36340b57cec5SDimitry Andric 
36350b57cec5SDimitry Andric   unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
36360b57cec5SDimitry Andric   auto &DL = CGF.CGM.getDataLayout();
36370b57cec5SDimitry Andric   auto PtrTy = cast<llvm::PointerType>(pointer->getType());
36380b57cec5SDimitry Andric 
36390b57cec5SDimitry Andric   // Some versions of glibc and gcc use idioms (particularly in their malloc
36400b57cec5SDimitry Andric   // routines) that add a pointer-sized integer (known to be a pointer value)
36410b57cec5SDimitry Andric   // to a null pointer in order to cast the value back to an integer or as
36420b57cec5SDimitry Andric   // part of a pointer alignment algorithm.  This is undefined behavior, but
36430b57cec5SDimitry Andric   // we'd like to be able to compile programs that use it.
36440b57cec5SDimitry Andric   //
36450b57cec5SDimitry Andric   // Normally, we'd generate a GEP with a null-pointer base here in response
36460b57cec5SDimitry Andric   // to that code, but it's also UB to dereference a pointer created that
36470b57cec5SDimitry Andric   // way.  Instead (as an acknowledged hack to tolerate the idiom) we will
36480b57cec5SDimitry Andric   // generate a direct cast of the integer value to a pointer.
36490b57cec5SDimitry Andric   //
36500b57cec5SDimitry Andric   // The idiom (p = nullptr + N) is not met if any of the following are true:
36510b57cec5SDimitry Andric   //
36520b57cec5SDimitry Andric   //   The operation is subtraction.
36530b57cec5SDimitry Andric   //   The index is not pointer-sized.
36540b57cec5SDimitry Andric   //   The pointer type is not byte-sized.
36550b57cec5SDimitry Andric   //
36560b57cec5SDimitry Andric   if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(),
36570b57cec5SDimitry Andric                                                        op.Opcode,
36580b57cec5SDimitry Andric                                                        expr->getLHS(),
36590b57cec5SDimitry Andric                                                        expr->getRHS()))
36600b57cec5SDimitry Andric     return CGF.Builder.CreateIntToPtr(index, pointer->getType());
36610b57cec5SDimitry Andric 
3662480093f4SDimitry Andric   if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
36630b57cec5SDimitry Andric     // Zero-extend or sign-extend the pointer value according to
36640b57cec5SDimitry Andric     // whether the index is signed or not.
3665480093f4SDimitry Andric     index = CGF.Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
36660b57cec5SDimitry Andric                                       "idx.ext");
36670b57cec5SDimitry Andric   }
36680b57cec5SDimitry Andric 
36690b57cec5SDimitry Andric   // If this is subtraction, negate the index.
36700b57cec5SDimitry Andric   if (isSubtraction)
36710b57cec5SDimitry Andric     index = CGF.Builder.CreateNeg(index, "idx.neg");
36720b57cec5SDimitry Andric 
36730b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
36740b57cec5SDimitry Andric     CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
36750b57cec5SDimitry Andric                         /*Accessed*/ false);
36760b57cec5SDimitry Andric 
36770b57cec5SDimitry Andric   const PointerType *pointerType
36780b57cec5SDimitry Andric     = pointerOperand->getType()->getAs<PointerType>();
36790b57cec5SDimitry Andric   if (!pointerType) {
36800b57cec5SDimitry Andric     QualType objectType = pointerOperand->getType()
36810b57cec5SDimitry Andric                                         ->castAs<ObjCObjectPointerType>()
36820b57cec5SDimitry Andric                                         ->getPointeeType();
36830b57cec5SDimitry Andric     llvm::Value *objectSize
36840b57cec5SDimitry Andric       = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType));
36850b57cec5SDimitry Andric 
36860b57cec5SDimitry Andric     index = CGF.Builder.CreateMul(index, objectSize);
36870b57cec5SDimitry Andric 
3688c9157d92SDimitry Andric     Value *result =
3689c9157d92SDimitry Andric         CGF.Builder.CreateGEP(CGF.Int8Ty, pointer, index, "add.ptr");
36900b57cec5SDimitry Andric     return CGF.Builder.CreateBitCast(result, pointer->getType());
36910b57cec5SDimitry Andric   }
36920b57cec5SDimitry Andric 
36930b57cec5SDimitry Andric   QualType elementType = pointerType->getPointeeType();
36940b57cec5SDimitry Andric   if (const VariableArrayType *vla
36950b57cec5SDimitry Andric         = CGF.getContext().getAsVariableArrayType(elementType)) {
36960b57cec5SDimitry Andric     // The element count here is the total number of non-VLA elements.
36970b57cec5SDimitry Andric     llvm::Value *numElements = CGF.getVLASize(vla).NumElts;
36980b57cec5SDimitry Andric 
36990b57cec5SDimitry Andric     // Effectively, the multiply by the VLA size is part of the GEP.
37000b57cec5SDimitry Andric     // GEP indexes are signed, and scaling an index isn't permitted to
37010b57cec5SDimitry Andric     // signed-overflow, so we use the same semantics for our explicit
37020b57cec5SDimitry Andric     // multiply.  We suppress this if overflow is not undefined behavior.
370381ad6265SDimitry Andric     llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
37040b57cec5SDimitry Andric     if (CGF.getLangOpts().isSignedOverflowDefined()) {
37050b57cec5SDimitry Andric       index = CGF.Builder.CreateMul(index, numElements, "vla.index");
37060eae32dcSDimitry Andric       pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
37070b57cec5SDimitry Andric     } else {
37080b57cec5SDimitry Andric       index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
37090eae32dcSDimitry Andric       pointer = CGF.EmitCheckedInBoundsGEP(
37100eae32dcSDimitry Andric           elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
37110eae32dcSDimitry Andric           "add.ptr");
37120b57cec5SDimitry Andric     }
37130b57cec5SDimitry Andric     return pointer;
37140b57cec5SDimitry Andric   }
37150b57cec5SDimitry Andric 
37160b57cec5SDimitry Andric   // Explicitly handle GNU void* and function pointer arithmetic extensions. The
37170b57cec5SDimitry Andric   // GNU void* casts amount to no-ops since our void* type is i8*, but this is
37180b57cec5SDimitry Andric   // future proof.
3719c9157d92SDimitry Andric   llvm::Type *elemTy;
3720fe013be4SDimitry Andric   if (elementType->isVoidType() || elementType->isFunctionType())
3721c9157d92SDimitry Andric     elemTy = CGF.Int8Ty;
3722c9157d92SDimitry Andric   else
3723c9157d92SDimitry Andric     elemTy = CGF.ConvertTypeForMem(elementType);
37240b57cec5SDimitry Andric 
37250b57cec5SDimitry Andric   if (CGF.getLangOpts().isSignedOverflowDefined())
37260eae32dcSDimitry Andric     return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
37270b57cec5SDimitry Andric 
37280eae32dcSDimitry Andric   return CGF.EmitCheckedInBoundsGEP(
37290eae32dcSDimitry Andric       elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
37300eae32dcSDimitry Andric       "add.ptr");
37310b57cec5SDimitry Andric }
37320b57cec5SDimitry Andric 
37330b57cec5SDimitry Andric // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
37340b57cec5SDimitry Andric // Addend. Use negMul and negAdd to negate the first operand of the Mul or
37350b57cec5SDimitry Andric // the add operand respectively. This allows fmuladd to represent a*b-c, or
37360b57cec5SDimitry Andric // c-a*b. Patterns in LLVM should catch the negated forms and translate them to
37370b57cec5SDimitry Andric // efficient operations.
buildFMulAdd(llvm::Instruction * MulOp,Value * Addend,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool negMul,bool negAdd)37385ffd83dbSDimitry Andric static Value* buildFMulAdd(llvm::Instruction *MulOp, Value *Addend,
37390b57cec5SDimitry Andric                            const CodeGenFunction &CGF, CGBuilderTy &Builder,
37400b57cec5SDimitry Andric                            bool negMul, bool negAdd) {
37410b57cec5SDimitry Andric   Value *MulOp0 = MulOp->getOperand(0);
37420b57cec5SDimitry Andric   Value *MulOp1 = MulOp->getOperand(1);
3743480093f4SDimitry Andric   if (negMul)
3744480093f4SDimitry Andric     MulOp0 = Builder.CreateFNeg(MulOp0, "neg");
3745480093f4SDimitry Andric   if (negAdd)
3746480093f4SDimitry Andric     Addend = Builder.CreateFNeg(Addend, "neg");
37470b57cec5SDimitry Andric 
37485ffd83dbSDimitry Andric   Value *FMulAdd = nullptr;
37495ffd83dbSDimitry Andric   if (Builder.getIsFPConstrained()) {
37505ffd83dbSDimitry Andric     assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
37515ffd83dbSDimitry Andric            "Only constrained operation should be created when Builder is in FP "
37525ffd83dbSDimitry Andric            "constrained mode");
37535ffd83dbSDimitry Andric     FMulAdd = Builder.CreateConstrainedFPCall(
37545ffd83dbSDimitry Andric         CGF.CGM.getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
37555ffd83dbSDimitry Andric                              Addend->getType()),
37565ffd83dbSDimitry Andric         {MulOp0, MulOp1, Addend});
37575ffd83dbSDimitry Andric   } else {
37585ffd83dbSDimitry Andric     FMulAdd = Builder.CreateCall(
37590b57cec5SDimitry Andric         CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
37600b57cec5SDimitry Andric         {MulOp0, MulOp1, Addend});
37615ffd83dbSDimitry Andric   }
37620b57cec5SDimitry Andric   MulOp->eraseFromParent();
37630b57cec5SDimitry Andric 
37640b57cec5SDimitry Andric   return FMulAdd;
37650b57cec5SDimitry Andric }
37660b57cec5SDimitry Andric 
37670b57cec5SDimitry Andric // Check whether it would be legal to emit an fmuladd intrinsic call to
37680b57cec5SDimitry Andric // represent op and if so, build the fmuladd.
37690b57cec5SDimitry Andric //
37700b57cec5SDimitry Andric // Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
37710b57cec5SDimitry Andric // Does NOT check the type of the operation - it's assumed that this function
37720b57cec5SDimitry 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)37730b57cec5SDimitry Andric static Value* tryEmitFMulAdd(const BinOpInfo &op,
37740b57cec5SDimitry Andric                          const CodeGenFunction &CGF, CGBuilderTy &Builder,
37750b57cec5SDimitry Andric                          bool isSub=false) {
37760b57cec5SDimitry Andric 
37770b57cec5SDimitry Andric   assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
37780b57cec5SDimitry Andric           op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
37790b57cec5SDimitry Andric          "Only fadd/fsub can be the root of an fmuladd.");
37800b57cec5SDimitry Andric 
37810b57cec5SDimitry Andric   // Check whether this op is marked as fusable.
37820b57cec5SDimitry Andric   if (!op.FPFeatures.allowFPContractWithinStatement())
37830b57cec5SDimitry Andric     return nullptr;
37840b57cec5SDimitry Andric 
3785fe013be4SDimitry Andric   Value *LHS = op.LHS;
3786fe013be4SDimitry Andric   Value *RHS = op.RHS;
3787fe013be4SDimitry Andric 
3788fe013be4SDimitry Andric   // Peek through fneg to look for fmul. Make sure fneg has no users, and that
3789fe013be4SDimitry Andric   // it is the only use of its operand.
3790fe013be4SDimitry Andric   bool NegLHS = false;
3791fe013be4SDimitry Andric   if (auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
3792fe013be4SDimitry Andric     if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
3793fe013be4SDimitry Andric         LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
3794fe013be4SDimitry Andric       LHS = LHSUnOp->getOperand(0);
3795fe013be4SDimitry Andric       NegLHS = true;
3796fe013be4SDimitry Andric     }
3797fe013be4SDimitry Andric   }
3798fe013be4SDimitry Andric 
3799fe013be4SDimitry Andric   bool NegRHS = false;
3800fe013be4SDimitry Andric   if (auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
3801fe013be4SDimitry Andric     if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
3802fe013be4SDimitry Andric         RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
3803fe013be4SDimitry Andric       RHS = RHSUnOp->getOperand(0);
3804fe013be4SDimitry Andric       NegRHS = true;
3805fe013be4SDimitry Andric     }
3806fe013be4SDimitry Andric   }
3807fe013be4SDimitry Andric 
38080b57cec5SDimitry Andric   // We have a potentially fusable op. Look for a mul on one of the operands.
38090b57cec5SDimitry Andric   // Also, make sure that the mul result isn't used directly. In that case,
38100b57cec5SDimitry Andric   // there's no point creating a muladd operation.
3811fe013be4SDimitry Andric   if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
38120b57cec5SDimitry Andric     if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3813fe013be4SDimitry Andric         (LHSBinOp->use_empty() || NegLHS)) {
3814fe013be4SDimitry Andric       // If we looked through fneg, erase it.
3815fe013be4SDimitry Andric       if (NegLHS)
3816fe013be4SDimitry Andric         cast<llvm::Instruction>(op.LHS)->eraseFromParent();
3817fe013be4SDimitry Andric       return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
38180b57cec5SDimitry Andric     }
3819fe013be4SDimitry Andric   }
3820fe013be4SDimitry Andric   if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
38210b57cec5SDimitry Andric     if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
3822fe013be4SDimitry Andric         (RHSBinOp->use_empty() || NegRHS)) {
3823fe013be4SDimitry Andric       // If we looked through fneg, erase it.
3824fe013be4SDimitry Andric       if (NegRHS)
3825fe013be4SDimitry Andric         cast<llvm::Instruction>(op.RHS)->eraseFromParent();
3826fe013be4SDimitry Andric       return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS, false);
3827fe013be4SDimitry Andric     }
38280b57cec5SDimitry Andric   }
38290b57cec5SDimitry Andric 
3830fe013be4SDimitry Andric   if (auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
38315ffd83dbSDimitry Andric     if (LHSBinOp->getIntrinsicID() ==
38325ffd83dbSDimitry Andric             llvm::Intrinsic::experimental_constrained_fmul &&
3833fe013be4SDimitry Andric         (LHSBinOp->use_empty() || NegLHS)) {
3834fe013be4SDimitry Andric       // If we looked through fneg, erase it.
3835fe013be4SDimitry Andric       if (NegLHS)
3836fe013be4SDimitry Andric         cast<llvm::Instruction>(op.LHS)->eraseFromParent();
3837fe013be4SDimitry Andric       return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
38385ffd83dbSDimitry Andric     }
3839fe013be4SDimitry Andric   }
3840fe013be4SDimitry Andric   if (auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
38415ffd83dbSDimitry Andric     if (RHSBinOp->getIntrinsicID() ==
38425ffd83dbSDimitry Andric             llvm::Intrinsic::experimental_constrained_fmul &&
3843fe013be4SDimitry Andric         (RHSBinOp->use_empty() || NegRHS)) {
3844fe013be4SDimitry Andric       // If we looked through fneg, erase it.
3845fe013be4SDimitry Andric       if (NegRHS)
3846fe013be4SDimitry Andric         cast<llvm::Instruction>(op.RHS)->eraseFromParent();
3847fe013be4SDimitry Andric       return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS, false);
3848fe013be4SDimitry Andric     }
38495ffd83dbSDimitry Andric   }
38505ffd83dbSDimitry Andric 
38510b57cec5SDimitry Andric   return nullptr;
38520b57cec5SDimitry Andric }
38530b57cec5SDimitry Andric 
EmitAdd(const BinOpInfo & op)38540b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
38550b57cec5SDimitry Andric   if (op.LHS->getType()->isPointerTy() ||
38560b57cec5SDimitry Andric       op.RHS->getType()->isPointerTy())
38570b57cec5SDimitry Andric     return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction);
38580b57cec5SDimitry Andric 
38590b57cec5SDimitry Andric   if (op.Ty->isSignedIntegerOrEnumerationType()) {
38600b57cec5SDimitry Andric     switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
38610b57cec5SDimitry Andric     case LangOptions::SOB_Defined:
38620b57cec5SDimitry Andric       return Builder.CreateAdd(op.LHS, op.RHS, "add");
38630b57cec5SDimitry Andric     case LangOptions::SOB_Undefined:
38640b57cec5SDimitry Andric       if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
38650b57cec5SDimitry Andric         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
3866bdd1243dSDimitry Andric       [[fallthrough]];
38670b57cec5SDimitry Andric     case LangOptions::SOB_Trapping:
38680b57cec5SDimitry Andric       if (CanElideOverflowCheck(CGF.getContext(), op))
38690b57cec5SDimitry Andric         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
38700b57cec5SDimitry Andric       return EmitOverflowCheckedBinOp(op);
38710b57cec5SDimitry Andric     }
38720b57cec5SDimitry Andric   }
38730b57cec5SDimitry Andric 
3874c9157d92SDimitry Andric   // For vector and matrix adds, try to fold into a fmuladd.
3875c9157d92SDimitry Andric   if (op.LHS->getType()->isFPOrFPVectorTy()) {
3876c9157d92SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
3877c9157d92SDimitry Andric     // Try to form an fmuladd.
3878c9157d92SDimitry Andric     if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
3879c9157d92SDimitry Andric       return FMulAdd;
3880c9157d92SDimitry Andric   }
3881c9157d92SDimitry Andric 
38825ffd83dbSDimitry Andric   if (op.Ty->isConstantMatrixType()) {
388381ad6265SDimitry Andric     llvm::MatrixBuilder MB(Builder);
3884fe6060f1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
38855ffd83dbSDimitry Andric     return MB.CreateAdd(op.LHS, op.RHS);
38865ffd83dbSDimitry Andric   }
38875ffd83dbSDimitry Andric 
38880b57cec5SDimitry Andric   if (op.Ty->isUnsignedIntegerType() &&
38890b57cec5SDimitry Andric       CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
38900b57cec5SDimitry Andric       !CanElideOverflowCheck(CGF.getContext(), op))
38910b57cec5SDimitry Andric     return EmitOverflowCheckedBinOp(op);
38920b57cec5SDimitry Andric 
38930b57cec5SDimitry Andric   if (op.LHS->getType()->isFPOrFPVectorTy()) {
38945ffd83dbSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
38955ffd83dbSDimitry Andric     return Builder.CreateFAdd(op.LHS, op.RHS, "add");
38960b57cec5SDimitry Andric   }
38970b57cec5SDimitry Andric 
38985ffd83dbSDimitry Andric   if (op.isFixedPointOp())
38990b57cec5SDimitry Andric     return EmitFixedPointBinOp(op);
39000b57cec5SDimitry Andric 
39010b57cec5SDimitry Andric   return Builder.CreateAdd(op.LHS, op.RHS, "add");
39020b57cec5SDimitry Andric }
39030b57cec5SDimitry Andric 
39040b57cec5SDimitry Andric /// The resulting value must be calculated with exact precision, so the operands
39050b57cec5SDimitry Andric /// may not be the same type.
EmitFixedPointBinOp(const BinOpInfo & op)39060b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {
39070b57cec5SDimitry Andric   using llvm::APSInt;
39080b57cec5SDimitry Andric   using llvm::ConstantInt;
39090b57cec5SDimitry Andric 
39105ffd83dbSDimitry Andric   // This is either a binary operation where at least one of the operands is
39115ffd83dbSDimitry Andric   // a fixed-point type, or a unary operation where the operand is a fixed-point
39125ffd83dbSDimitry Andric   // type. The result type of a binary operation is determined by
39135ffd83dbSDimitry Andric   // Sema::handleFixedPointConversions().
39140b57cec5SDimitry Andric   QualType ResultTy = op.Ty;
39155ffd83dbSDimitry Andric   QualType LHSTy, RHSTy;
39165ffd83dbSDimitry Andric   if (const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
39175ffd83dbSDimitry Andric     RHSTy = BinOp->getRHS()->getType();
39185ffd83dbSDimitry Andric     if (const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
39195ffd83dbSDimitry Andric       // For compound assignment, the effective type of the LHS at this point
39205ffd83dbSDimitry Andric       // is the computation LHS type, not the actual LHS type, and the final
39215ffd83dbSDimitry Andric       // result type is not the type of the expression but rather the
39225ffd83dbSDimitry Andric       // computation result type.
39235ffd83dbSDimitry Andric       LHSTy = CAO->getComputationLHSType();
39245ffd83dbSDimitry Andric       ResultTy = CAO->getComputationResultType();
39255ffd83dbSDimitry Andric     } else
39265ffd83dbSDimitry Andric       LHSTy = BinOp->getLHS()->getType();
39275ffd83dbSDimitry Andric   } else if (const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
39285ffd83dbSDimitry Andric     LHSTy = UnOp->getSubExpr()->getType();
39295ffd83dbSDimitry Andric     RHSTy = UnOp->getSubExpr()->getType();
39305ffd83dbSDimitry Andric   }
39310b57cec5SDimitry Andric   ASTContext &Ctx = CGF.getContext();
39320b57cec5SDimitry Andric   Value *LHS = op.LHS;
39330b57cec5SDimitry Andric   Value *RHS = op.RHS;
39340b57cec5SDimitry Andric 
39350b57cec5SDimitry Andric   auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy);
39360b57cec5SDimitry Andric   auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy);
39370b57cec5SDimitry Andric   auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy);
39380b57cec5SDimitry Andric   auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
39390b57cec5SDimitry Andric 
39405ffd83dbSDimitry Andric   // Perform the actual operation.
39410b57cec5SDimitry Andric   Value *Result;
3942e8d8bef9SDimitry Andric   llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
39435ffd83dbSDimitry Andric   switch (op.Opcode) {
39445ffd83dbSDimitry Andric   case BO_AddAssign:
3945e8d8bef9SDimitry Andric   case BO_Add:
3946e8d8bef9SDimitry Andric     Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
39470b57cec5SDimitry Andric     break;
39485ffd83dbSDimitry Andric   case BO_SubAssign:
3949e8d8bef9SDimitry Andric   case BO_Sub:
3950e8d8bef9SDimitry Andric     Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
39510b57cec5SDimitry Andric     break;
39525ffd83dbSDimitry Andric   case BO_MulAssign:
3953e8d8bef9SDimitry Andric   case BO_Mul:
3954e8d8bef9SDimitry Andric     Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
39555ffd83dbSDimitry Andric     break;
39565ffd83dbSDimitry Andric   case BO_DivAssign:
3957e8d8bef9SDimitry Andric   case BO_Div:
3958e8d8bef9SDimitry Andric     Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
39595ffd83dbSDimitry Andric     break;
3960e8d8bef9SDimitry Andric   case BO_ShlAssign:
3961e8d8bef9SDimitry Andric   case BO_Shl:
3962e8d8bef9SDimitry Andric     Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
3963e8d8bef9SDimitry Andric     break;
3964e8d8bef9SDimitry Andric   case BO_ShrAssign:
3965e8d8bef9SDimitry Andric   case BO_Shr:
3966e8d8bef9SDimitry Andric     Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
3967e8d8bef9SDimitry Andric     break;
39680b57cec5SDimitry Andric   case BO_LT:
3969e8d8bef9SDimitry Andric     return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
39700b57cec5SDimitry Andric   case BO_GT:
3971e8d8bef9SDimitry Andric     return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
39720b57cec5SDimitry Andric   case BO_LE:
3973e8d8bef9SDimitry Andric     return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
39740b57cec5SDimitry Andric   case BO_GE:
3975e8d8bef9SDimitry Andric     return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
39760b57cec5SDimitry Andric   case BO_EQ:
39770b57cec5SDimitry Andric     // For equality operations, we assume any padding bits on unsigned types are
39780b57cec5SDimitry Andric     // zero'd out. They could be overwritten through non-saturating operations
39790b57cec5SDimitry Andric     // that cause overflow, but this leads to undefined behavior.
3980e8d8bef9SDimitry Andric     return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
39810b57cec5SDimitry Andric   case BO_NE:
3982e8d8bef9SDimitry Andric     return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
39830b57cec5SDimitry Andric   case BO_Cmp:
39840b57cec5SDimitry Andric   case BO_LAnd:
39850b57cec5SDimitry Andric   case BO_LOr:
39860b57cec5SDimitry Andric     llvm_unreachable("Found unimplemented fixed point binary operation");
39870b57cec5SDimitry Andric   case BO_PtrMemD:
39880b57cec5SDimitry Andric   case BO_PtrMemI:
39890b57cec5SDimitry Andric   case BO_Rem:
39900b57cec5SDimitry Andric   case BO_Xor:
39910b57cec5SDimitry Andric   case BO_And:
39920b57cec5SDimitry Andric   case BO_Or:
39930b57cec5SDimitry Andric   case BO_Assign:
39940b57cec5SDimitry Andric   case BO_RemAssign:
39950b57cec5SDimitry Andric   case BO_AndAssign:
39960b57cec5SDimitry Andric   case BO_XorAssign:
39970b57cec5SDimitry Andric   case BO_OrAssign:
39980b57cec5SDimitry Andric   case BO_Comma:
39990b57cec5SDimitry Andric     llvm_unreachable("Found unsupported binary operation for fixed point types.");
40000b57cec5SDimitry Andric   }
40010b57cec5SDimitry Andric 
4002e8d8bef9SDimitry Andric   bool IsShift = BinaryOperator::isShiftOp(op.Opcode) ||
4003e8d8bef9SDimitry Andric                  BinaryOperator::isShiftAssignOp(op.Opcode);
40040b57cec5SDimitry Andric   // Convert to the result type.
4005e8d8bef9SDimitry Andric   return FPBuilder.CreateFixedToFixed(Result, IsShift ? LHSFixedSema
4006e8d8bef9SDimitry Andric                                                       : CommonFixedSema,
4007e8d8bef9SDimitry Andric                                       ResultFixedSema);
40080b57cec5SDimitry Andric }
40090b57cec5SDimitry Andric 
EmitSub(const BinOpInfo & op)40100b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
40110b57cec5SDimitry Andric   // The LHS is always a pointer if either side is.
40120b57cec5SDimitry Andric   if (!op.LHS->getType()->isPointerTy()) {
40130b57cec5SDimitry Andric     if (op.Ty->isSignedIntegerOrEnumerationType()) {
40140b57cec5SDimitry Andric       switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
40150b57cec5SDimitry Andric       case LangOptions::SOB_Defined:
40160b57cec5SDimitry Andric         return Builder.CreateSub(op.LHS, op.RHS, "sub");
40170b57cec5SDimitry Andric       case LangOptions::SOB_Undefined:
40180b57cec5SDimitry Andric         if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
40190b57cec5SDimitry Andric           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
4020bdd1243dSDimitry Andric         [[fallthrough]];
40210b57cec5SDimitry Andric       case LangOptions::SOB_Trapping:
40220b57cec5SDimitry Andric         if (CanElideOverflowCheck(CGF.getContext(), op))
40230b57cec5SDimitry Andric           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
40240b57cec5SDimitry Andric         return EmitOverflowCheckedBinOp(op);
40250b57cec5SDimitry Andric       }
40260b57cec5SDimitry Andric     }
40270b57cec5SDimitry Andric 
4028c9157d92SDimitry Andric     // For vector and matrix subs, try to fold into a fmuladd.
4029c9157d92SDimitry Andric     if (op.LHS->getType()->isFPOrFPVectorTy()) {
4030c9157d92SDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4031c9157d92SDimitry Andric       // Try to form an fmuladd.
4032c9157d92SDimitry Andric       if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
4033c9157d92SDimitry Andric         return FMulAdd;
4034c9157d92SDimitry Andric     }
4035c9157d92SDimitry Andric 
40365ffd83dbSDimitry Andric     if (op.Ty->isConstantMatrixType()) {
403781ad6265SDimitry Andric       llvm::MatrixBuilder MB(Builder);
4038fe6060f1SDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
40395ffd83dbSDimitry Andric       return MB.CreateSub(op.LHS, op.RHS);
40405ffd83dbSDimitry Andric     }
40415ffd83dbSDimitry Andric 
40420b57cec5SDimitry Andric     if (op.Ty->isUnsignedIntegerType() &&
40430b57cec5SDimitry Andric         CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
40440b57cec5SDimitry Andric         !CanElideOverflowCheck(CGF.getContext(), op))
40450b57cec5SDimitry Andric       return EmitOverflowCheckedBinOp(op);
40460b57cec5SDimitry Andric 
40470b57cec5SDimitry Andric     if (op.LHS->getType()->isFPOrFPVectorTy()) {
40485ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
40495ffd83dbSDimitry Andric       return Builder.CreateFSub(op.LHS, op.RHS, "sub");
40500b57cec5SDimitry Andric     }
40510b57cec5SDimitry Andric 
40525ffd83dbSDimitry Andric     if (op.isFixedPointOp())
40530b57cec5SDimitry Andric       return EmitFixedPointBinOp(op);
40540b57cec5SDimitry Andric 
40550b57cec5SDimitry Andric     return Builder.CreateSub(op.LHS, op.RHS, "sub");
40560b57cec5SDimitry Andric   }
40570b57cec5SDimitry Andric 
40580b57cec5SDimitry Andric   // If the RHS is not a pointer, then we have normal pointer
40590b57cec5SDimitry Andric   // arithmetic.
40600b57cec5SDimitry Andric   if (!op.RHS->getType()->isPointerTy())
40610b57cec5SDimitry Andric     return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction);
40620b57cec5SDimitry Andric 
40630b57cec5SDimitry Andric   // Otherwise, this is a pointer subtraction.
40640b57cec5SDimitry Andric 
40650b57cec5SDimitry Andric   // Do the raw subtraction part.
40660b57cec5SDimitry Andric   llvm::Value *LHS
40670b57cec5SDimitry Andric     = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast");
40680b57cec5SDimitry Andric   llvm::Value *RHS
40690b57cec5SDimitry Andric     = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast");
40700b57cec5SDimitry Andric   Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
40710b57cec5SDimitry Andric 
40720b57cec5SDimitry Andric   // Okay, figure out the element size.
40730b57cec5SDimitry Andric   const BinaryOperator *expr = cast<BinaryOperator>(op.E);
40740b57cec5SDimitry Andric   QualType elementType = expr->getLHS()->getType()->getPointeeType();
40750b57cec5SDimitry Andric 
40760b57cec5SDimitry Andric   llvm::Value *divisor = nullptr;
40770b57cec5SDimitry Andric 
40780b57cec5SDimitry Andric   // For a variable-length array, this is going to be non-constant.
40790b57cec5SDimitry Andric   if (const VariableArrayType *vla
40800b57cec5SDimitry Andric         = CGF.getContext().getAsVariableArrayType(elementType)) {
40810b57cec5SDimitry Andric     auto VlaSize = CGF.getVLASize(vla);
40820b57cec5SDimitry Andric     elementType = VlaSize.Type;
40830b57cec5SDimitry Andric     divisor = VlaSize.NumElts;
40840b57cec5SDimitry Andric 
40850b57cec5SDimitry Andric     // Scale the number of non-VLA elements by the non-VLA element size.
40860b57cec5SDimitry Andric     CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType);
40870b57cec5SDimitry Andric     if (!eltSize.isOne())
40880b57cec5SDimitry Andric       divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor);
40890b57cec5SDimitry Andric 
40900b57cec5SDimitry Andric   // For everything elese, we can just compute it, safe in the
40910b57cec5SDimitry Andric   // assumption that Sema won't let anything through that we can't
40920b57cec5SDimitry Andric   // safely compute the size of.
40930b57cec5SDimitry Andric   } else {
40940b57cec5SDimitry Andric     CharUnits elementSize;
40950b57cec5SDimitry Andric     // Handle GCC extension for pointer arithmetic on void* and
40960b57cec5SDimitry Andric     // function pointer types.
40970b57cec5SDimitry Andric     if (elementType->isVoidType() || elementType->isFunctionType())
40980b57cec5SDimitry Andric       elementSize = CharUnits::One();
40990b57cec5SDimitry Andric     else
41000b57cec5SDimitry Andric       elementSize = CGF.getContext().getTypeSizeInChars(elementType);
41010b57cec5SDimitry Andric 
41020b57cec5SDimitry Andric     // Don't even emit the divide for element size of 1.
41030b57cec5SDimitry Andric     if (elementSize.isOne())
41040b57cec5SDimitry Andric       return diffInChars;
41050b57cec5SDimitry Andric 
41060b57cec5SDimitry Andric     divisor = CGF.CGM.getSize(elementSize);
41070b57cec5SDimitry Andric   }
41080b57cec5SDimitry Andric 
41090b57cec5SDimitry Andric   // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
41100b57cec5SDimitry Andric   // pointer difference in C is only defined in the case where both operands
41110b57cec5SDimitry Andric   // are pointing to elements of an array.
41120b57cec5SDimitry Andric   return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div");
41130b57cec5SDimitry Andric }
41140b57cec5SDimitry Andric 
GetWidthMinusOneValue(Value * LHS,Value * RHS)41150b57cec5SDimitry Andric Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) {
41160b57cec5SDimitry Andric   llvm::IntegerType *Ty;
41170b57cec5SDimitry Andric   if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
41180b57cec5SDimitry Andric     Ty = cast<llvm::IntegerType>(VT->getElementType());
41190b57cec5SDimitry Andric   else
41200b57cec5SDimitry Andric     Ty = cast<llvm::IntegerType>(LHS->getType());
41210b57cec5SDimitry Andric   return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1);
41220b57cec5SDimitry Andric }
41230b57cec5SDimitry Andric 
ConstrainShiftValue(Value * LHS,Value * RHS,const Twine & Name)41245ffd83dbSDimitry Andric Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS,
41255ffd83dbSDimitry Andric                                               const Twine &Name) {
41265ffd83dbSDimitry Andric   llvm::IntegerType *Ty;
41275ffd83dbSDimitry Andric   if (auto *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
41285ffd83dbSDimitry Andric     Ty = cast<llvm::IntegerType>(VT->getElementType());
41295ffd83dbSDimitry Andric   else
41305ffd83dbSDimitry Andric     Ty = cast<llvm::IntegerType>(LHS->getType());
41315ffd83dbSDimitry Andric 
41325ffd83dbSDimitry Andric   if (llvm::isPowerOf2_64(Ty->getBitWidth()))
41335ffd83dbSDimitry Andric         return Builder.CreateAnd(RHS, GetWidthMinusOneValue(LHS, RHS), Name);
41345ffd83dbSDimitry Andric 
41355ffd83dbSDimitry Andric   return Builder.CreateURem(
41365ffd83dbSDimitry Andric       RHS, llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth()), Name);
41375ffd83dbSDimitry Andric }
41385ffd83dbSDimitry Andric 
EmitShl(const BinOpInfo & Ops)41390b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
4140e8d8bef9SDimitry Andric   // TODO: This misses out on the sanitizer check below.
4141e8d8bef9SDimitry Andric   if (Ops.isFixedPointOp())
4142e8d8bef9SDimitry Andric     return EmitFixedPointBinOp(Ops);
4143e8d8bef9SDimitry Andric 
41440b57cec5SDimitry Andric   // LLVM requires the LHS and RHS to be the same type: promote or truncate the
41450b57cec5SDimitry Andric   // RHS to the same size as the LHS.
41460b57cec5SDimitry Andric   Value *RHS = Ops.RHS;
41470b57cec5SDimitry Andric   if (Ops.LHS->getType() != RHS->getType())
41480b57cec5SDimitry Andric     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
41490b57cec5SDimitry Andric 
4150e8d8bef9SDimitry Andric   bool SanitizeSignedBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
41510b57cec5SDimitry Andric                             Ops.Ty->hasSignedIntegerRepresentation() &&
41520b57cec5SDimitry Andric                             !CGF.getLangOpts().isSignedOverflowDefined() &&
41535ffd83dbSDimitry Andric                             !CGF.getLangOpts().CPlusPlus20;
4154e8d8bef9SDimitry Andric   bool SanitizeUnsignedBase =
4155e8d8bef9SDimitry Andric       CGF.SanOpts.has(SanitizerKind::UnsignedShiftBase) &&
4156e8d8bef9SDimitry Andric       Ops.Ty->hasUnsignedIntegerRepresentation();
4157e8d8bef9SDimitry Andric   bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
41580b57cec5SDimitry Andric   bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
41590b57cec5SDimitry Andric   // OpenCL 6.3j: shift values are effectively % word size of LHS.
41600b57cec5SDimitry Andric   if (CGF.getLangOpts().OpenCL)
41615ffd83dbSDimitry Andric     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
41620b57cec5SDimitry Andric   else if ((SanitizeBase || SanitizeExponent) &&
41630b57cec5SDimitry Andric            isa<llvm::IntegerType>(Ops.LHS->getType())) {
41640b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
41650b57cec5SDimitry Andric     SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
41660b57cec5SDimitry Andric     llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
41670b57cec5SDimitry Andric     llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
41680b57cec5SDimitry Andric 
41690b57cec5SDimitry Andric     if (SanitizeExponent) {
41700b57cec5SDimitry Andric       Checks.push_back(
41710b57cec5SDimitry Andric           std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
41720b57cec5SDimitry Andric     }
41730b57cec5SDimitry Andric 
41740b57cec5SDimitry Andric     if (SanitizeBase) {
41750b57cec5SDimitry Andric       // Check whether we are shifting any non-zero bits off the top of the
41760b57cec5SDimitry Andric       // integer. We only emit this check if exponent is valid - otherwise
41770b57cec5SDimitry Andric       // instructions below will have undefined behavior themselves.
41780b57cec5SDimitry Andric       llvm::BasicBlock *Orig = Builder.GetInsertBlock();
41790b57cec5SDimitry Andric       llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
41800b57cec5SDimitry Andric       llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
41810b57cec5SDimitry Andric       Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
41820b57cec5SDimitry Andric       llvm::Value *PromotedWidthMinusOne =
41830b57cec5SDimitry Andric           (RHS == Ops.RHS) ? WidthMinusOne
41840b57cec5SDimitry Andric                            : GetWidthMinusOneValue(Ops.LHS, RHS);
41850b57cec5SDimitry Andric       CGF.EmitBlock(CheckShiftBase);
41860b57cec5SDimitry Andric       llvm::Value *BitsShiftedOff = Builder.CreateLShr(
41870b57cec5SDimitry Andric           Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
41880b57cec5SDimitry Andric                                      /*NUW*/ true, /*NSW*/ true),
41890b57cec5SDimitry Andric           "shl.check");
4190e8d8bef9SDimitry Andric       if (SanitizeUnsignedBase || CGF.getLangOpts().CPlusPlus) {
41910b57cec5SDimitry Andric         // In C99, we are not permitted to shift a 1 bit into the sign bit.
41920b57cec5SDimitry Andric         // Under C++11's rules, shifting a 1 bit into the sign bit is
41930b57cec5SDimitry Andric         // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't
41940b57cec5SDimitry Andric         // define signed left shifts, so we use the C99 and C++11 rules there).
4195e8d8bef9SDimitry Andric         // Unsigned shifts can always shift into the top bit.
41960b57cec5SDimitry Andric         llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
41970b57cec5SDimitry Andric         BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
41980b57cec5SDimitry Andric       }
41990b57cec5SDimitry Andric       llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
42000b57cec5SDimitry Andric       llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
42010b57cec5SDimitry Andric       CGF.EmitBlock(Cont);
42020b57cec5SDimitry Andric       llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
42030b57cec5SDimitry Andric       BaseCheck->addIncoming(Builder.getTrue(), Orig);
42040b57cec5SDimitry Andric       BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4205e8d8bef9SDimitry Andric       Checks.push_back(std::make_pair(
4206e8d8bef9SDimitry Andric           BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4207e8d8bef9SDimitry Andric                                         : SanitizerKind::UnsignedShiftBase));
42080b57cec5SDimitry Andric     }
42090b57cec5SDimitry Andric 
42100b57cec5SDimitry Andric     assert(!Checks.empty());
42110b57cec5SDimitry Andric     EmitBinOpCheck(Checks, Ops);
42120b57cec5SDimitry Andric   }
42130b57cec5SDimitry Andric 
42140b57cec5SDimitry Andric   return Builder.CreateShl(Ops.LHS, RHS, "shl");
42150b57cec5SDimitry Andric }
42160b57cec5SDimitry Andric 
EmitShr(const BinOpInfo & Ops)42170b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
4218e8d8bef9SDimitry Andric   // TODO: This misses out on the sanitizer check below.
4219e8d8bef9SDimitry Andric   if (Ops.isFixedPointOp())
4220e8d8bef9SDimitry Andric     return EmitFixedPointBinOp(Ops);
4221e8d8bef9SDimitry Andric 
42220b57cec5SDimitry Andric   // LLVM requires the LHS and RHS to be the same type: promote or truncate the
42230b57cec5SDimitry Andric   // RHS to the same size as the LHS.
42240b57cec5SDimitry Andric   Value *RHS = Ops.RHS;
42250b57cec5SDimitry Andric   if (Ops.LHS->getType() != RHS->getType())
42260b57cec5SDimitry Andric     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
42270b57cec5SDimitry Andric 
42280b57cec5SDimitry Andric   // OpenCL 6.3j: shift values are effectively % word size of LHS.
42290b57cec5SDimitry Andric   if (CGF.getLangOpts().OpenCL)
42305ffd83dbSDimitry Andric     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
42310b57cec5SDimitry Andric   else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
42320b57cec5SDimitry Andric            isa<llvm::IntegerType>(Ops.LHS->getType())) {
42330b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
42340b57cec5SDimitry Andric     llvm::Value *Valid =
42350b57cec5SDimitry Andric         Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
42360b57cec5SDimitry Andric     EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
42370b57cec5SDimitry Andric   }
42380b57cec5SDimitry Andric 
42390b57cec5SDimitry Andric   if (Ops.Ty->hasUnsignedIntegerRepresentation())
42400b57cec5SDimitry Andric     return Builder.CreateLShr(Ops.LHS, RHS, "shr");
42410b57cec5SDimitry Andric   return Builder.CreateAShr(Ops.LHS, RHS, "shr");
42420b57cec5SDimitry Andric }
42430b57cec5SDimitry Andric 
42440b57cec5SDimitry Andric enum IntrinsicType { VCMPEQ, VCMPGT };
42450b57cec5SDimitry Andric // return corresponding comparison intrinsic for given vector type
GetIntrinsic(IntrinsicType IT,BuiltinType::Kind ElemKind)42460b57cec5SDimitry Andric static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
42470b57cec5SDimitry Andric                                         BuiltinType::Kind ElemKind) {
42480b57cec5SDimitry Andric   switch (ElemKind) {
42490b57cec5SDimitry Andric   default: llvm_unreachable("unexpected element type");
42500b57cec5SDimitry Andric   case BuiltinType::Char_U:
42510b57cec5SDimitry Andric   case BuiltinType::UChar:
42520b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
42530b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
42540b57cec5SDimitry Andric   case BuiltinType::Char_S:
42550b57cec5SDimitry Andric   case BuiltinType::SChar:
42560b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
42570b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
42580b57cec5SDimitry Andric   case BuiltinType::UShort:
42590b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
42600b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
42610b57cec5SDimitry Andric   case BuiltinType::Short:
42620b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
42630b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
42640b57cec5SDimitry Andric   case BuiltinType::UInt:
42650b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
42660b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
42670b57cec5SDimitry Andric   case BuiltinType::Int:
42680b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
42690b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
42700b57cec5SDimitry Andric   case BuiltinType::ULong:
42710b57cec5SDimitry Andric   case BuiltinType::ULongLong:
42720b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
42730b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
42740b57cec5SDimitry Andric   case BuiltinType::Long:
42750b57cec5SDimitry Andric   case BuiltinType::LongLong:
42760b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
42770b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
42780b57cec5SDimitry Andric   case BuiltinType::Float:
42790b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
42800b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
42810b57cec5SDimitry Andric   case BuiltinType::Double:
42820b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
42830b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4284e8d8bef9SDimitry Andric   case BuiltinType::UInt128:
4285e8d8bef9SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4286e8d8bef9SDimitry Andric                           : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4287e8d8bef9SDimitry Andric   case BuiltinType::Int128:
4288e8d8bef9SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4289e8d8bef9SDimitry Andric                           : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
42900b57cec5SDimitry Andric   }
42910b57cec5SDimitry Andric }
42920b57cec5SDimitry Andric 
EmitCompare(const BinaryOperator * E,llvm::CmpInst::Predicate UICmpOpc,llvm::CmpInst::Predicate SICmpOpc,llvm::CmpInst::Predicate FCmpOpc,bool IsSignaling)42930b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
42940b57cec5SDimitry Andric                                       llvm::CmpInst::Predicate UICmpOpc,
42950b57cec5SDimitry Andric                                       llvm::CmpInst::Predicate SICmpOpc,
4296480093f4SDimitry Andric                                       llvm::CmpInst::Predicate FCmpOpc,
4297480093f4SDimitry Andric                                       bool IsSignaling) {
42980b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
42990b57cec5SDimitry Andric   Value *Result;
43000b57cec5SDimitry Andric   QualType LHSTy = E->getLHS()->getType();
43010b57cec5SDimitry Andric   QualType RHSTy = E->getRHS()->getType();
43020b57cec5SDimitry Andric   if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) {
43030b57cec5SDimitry Andric     assert(E->getOpcode() == BO_EQ ||
43040b57cec5SDimitry Andric            E->getOpcode() == BO_NE);
43050b57cec5SDimitry Andric     Value *LHS = CGF.EmitScalarExpr(E->getLHS());
43060b57cec5SDimitry Andric     Value *RHS = CGF.EmitScalarExpr(E->getRHS());
43070b57cec5SDimitry Andric     Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
43080b57cec5SDimitry Andric                    CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
43090b57cec5SDimitry Andric   } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) {
43100b57cec5SDimitry Andric     BinOpInfo BOInfo = EmitBinOps(E);
43110b57cec5SDimitry Andric     Value *LHS = BOInfo.LHS;
43120b57cec5SDimitry Andric     Value *RHS = BOInfo.RHS;
43130b57cec5SDimitry Andric 
43140b57cec5SDimitry Andric     // If AltiVec, the comparison results in a numeric type, so we use
43150b57cec5SDimitry Andric     // intrinsics comparing vectors and giving 0 or 1 as a result
43160b57cec5SDimitry Andric     if (LHSTy->isVectorType() && !E->getType()->isVectorType()) {
43170b57cec5SDimitry Andric       // constants for mapping CR6 register bits to predicate result
43180b57cec5SDimitry Andric       enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
43190b57cec5SDimitry Andric 
43200b57cec5SDimitry Andric       llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic;
43210b57cec5SDimitry Andric 
43220b57cec5SDimitry Andric       // in several cases vector arguments order will be reversed
43230b57cec5SDimitry Andric       Value *FirstVecArg = LHS,
43240b57cec5SDimitry Andric             *SecondVecArg = RHS;
43250b57cec5SDimitry Andric 
4326a7dea167SDimitry Andric       QualType ElTy = LHSTy->castAs<VectorType>()->getElementType();
4327480093f4SDimitry Andric       BuiltinType::Kind ElementKind = ElTy->castAs<BuiltinType>()->getKind();
43280b57cec5SDimitry Andric 
43290b57cec5SDimitry Andric       switch(E->getOpcode()) {
43300b57cec5SDimitry Andric       default: llvm_unreachable("is not a comparison operation");
43310b57cec5SDimitry Andric       case BO_EQ:
43320b57cec5SDimitry Andric         CR6 = CR6_LT;
43330b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPEQ, ElementKind);
43340b57cec5SDimitry Andric         break;
43350b57cec5SDimitry Andric       case BO_NE:
43360b57cec5SDimitry Andric         CR6 = CR6_EQ;
43370b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPEQ, ElementKind);
43380b57cec5SDimitry Andric         break;
43390b57cec5SDimitry Andric       case BO_LT:
43400b57cec5SDimitry Andric         CR6 = CR6_LT;
43410b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPGT, ElementKind);
43420b57cec5SDimitry Andric         std::swap(FirstVecArg, SecondVecArg);
43430b57cec5SDimitry Andric         break;
43440b57cec5SDimitry Andric       case BO_GT:
43450b57cec5SDimitry Andric         CR6 = CR6_LT;
43460b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPGT, ElementKind);
43470b57cec5SDimitry Andric         break;
43480b57cec5SDimitry Andric       case BO_LE:
43490b57cec5SDimitry Andric         if (ElementKind == BuiltinType::Float) {
43500b57cec5SDimitry Andric           CR6 = CR6_LT;
43510b57cec5SDimitry Andric           ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
43520b57cec5SDimitry Andric           std::swap(FirstVecArg, SecondVecArg);
43530b57cec5SDimitry Andric         }
43540b57cec5SDimitry Andric         else {
43550b57cec5SDimitry Andric           CR6 = CR6_EQ;
43560b57cec5SDimitry Andric           ID = GetIntrinsic(VCMPGT, ElementKind);
43570b57cec5SDimitry Andric         }
43580b57cec5SDimitry Andric         break;
43590b57cec5SDimitry Andric       case BO_GE:
43600b57cec5SDimitry Andric         if (ElementKind == BuiltinType::Float) {
43610b57cec5SDimitry Andric           CR6 = CR6_LT;
43620b57cec5SDimitry Andric           ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
43630b57cec5SDimitry Andric         }
43640b57cec5SDimitry Andric         else {
43650b57cec5SDimitry Andric           CR6 = CR6_EQ;
43660b57cec5SDimitry Andric           ID = GetIntrinsic(VCMPGT, ElementKind);
43670b57cec5SDimitry Andric           std::swap(FirstVecArg, SecondVecArg);
43680b57cec5SDimitry Andric         }
43690b57cec5SDimitry Andric         break;
43700b57cec5SDimitry Andric       }
43710b57cec5SDimitry Andric 
43720b57cec5SDimitry Andric       Value *CR6Param = Builder.getInt32(CR6);
43730b57cec5SDimitry Andric       llvm::Function *F = CGF.CGM.getIntrinsic(ID);
43740b57cec5SDimitry Andric       Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
43750b57cec5SDimitry Andric 
43760b57cec5SDimitry Andric       // The result type of intrinsic may not be same as E->getType().
43770b57cec5SDimitry Andric       // If E->getType() is not BoolTy, EmitScalarConversion will do the
43780b57cec5SDimitry Andric       // conversion work. If E->getType() is BoolTy, EmitScalarConversion will
43790b57cec5SDimitry Andric       // do nothing, if ResultTy is not i1 at the same time, it will cause
43800b57cec5SDimitry Andric       // crash later.
43810b57cec5SDimitry Andric       llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
43820b57cec5SDimitry Andric       if (ResultTy->getBitWidth() > 1 &&
43830b57cec5SDimitry Andric           E->getType() == CGF.getContext().BoolTy)
43840b57cec5SDimitry Andric         Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
43850b57cec5SDimitry Andric       return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
43860b57cec5SDimitry Andric                                   E->getExprLoc());
43870b57cec5SDimitry Andric     }
43880b57cec5SDimitry Andric 
43895ffd83dbSDimitry Andric     if (BOInfo.isFixedPointOp()) {
43900b57cec5SDimitry Andric       Result = EmitFixedPointBinOp(BOInfo);
43910b57cec5SDimitry Andric     } else if (LHS->getType()->isFPOrFPVectorTy()) {
43925ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4393480093f4SDimitry Andric       if (!IsSignaling)
43940b57cec5SDimitry Andric         Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
4395480093f4SDimitry Andric       else
4396480093f4SDimitry Andric         Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS, "cmp");
43970b57cec5SDimitry Andric     } else if (LHSTy->hasSignedIntegerRepresentation()) {
43980b57cec5SDimitry Andric       Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
43990b57cec5SDimitry Andric     } else {
44000b57cec5SDimitry Andric       // Unsigned integers and pointers.
44010b57cec5SDimitry Andric 
44020b57cec5SDimitry Andric       if (CGF.CGM.getCodeGenOpts().StrictVTablePointers &&
44030b57cec5SDimitry Andric           !isa<llvm::ConstantPointerNull>(LHS) &&
44040b57cec5SDimitry Andric           !isa<llvm::ConstantPointerNull>(RHS)) {
44050b57cec5SDimitry Andric 
44060b57cec5SDimitry Andric         // Dynamic information is required to be stripped for comparisons,
44070b57cec5SDimitry Andric         // because it could leak the dynamic information.  Based on comparisons
44080b57cec5SDimitry Andric         // of pointers to dynamic objects, the optimizer can replace one pointer
44090b57cec5SDimitry Andric         // with another, which might be incorrect in presence of invariant
44100b57cec5SDimitry Andric         // groups. Comparison with null is safe because null does not carry any
44110b57cec5SDimitry Andric         // dynamic information.
44120b57cec5SDimitry Andric         if (LHSTy.mayBeDynamicClass())
44130b57cec5SDimitry Andric           LHS = Builder.CreateStripInvariantGroup(LHS);
44140b57cec5SDimitry Andric         if (RHSTy.mayBeDynamicClass())
44150b57cec5SDimitry Andric           RHS = Builder.CreateStripInvariantGroup(RHS);
44160b57cec5SDimitry Andric       }
44170b57cec5SDimitry Andric 
44180b57cec5SDimitry Andric       Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
44190b57cec5SDimitry Andric     }
44200b57cec5SDimitry Andric 
44210b57cec5SDimitry Andric     // If this is a vector comparison, sign extend the result to the appropriate
44220b57cec5SDimitry Andric     // vector integer type and return it (don't convert to bool).
44230b57cec5SDimitry Andric     if (LHSTy->isVectorType())
44240b57cec5SDimitry Andric       return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
44250b57cec5SDimitry Andric 
44260b57cec5SDimitry Andric   } else {
44270b57cec5SDimitry Andric     // Complex Comparison: can only be an equality comparison.
44280b57cec5SDimitry Andric     CodeGenFunction::ComplexPairTy LHS, RHS;
44290b57cec5SDimitry Andric     QualType CETy;
44300b57cec5SDimitry Andric     if (auto *CTy = LHSTy->getAs<ComplexType>()) {
44310b57cec5SDimitry Andric       LHS = CGF.EmitComplexExpr(E->getLHS());
44320b57cec5SDimitry Andric       CETy = CTy->getElementType();
44330b57cec5SDimitry Andric     } else {
44340b57cec5SDimitry Andric       LHS.first = Visit(E->getLHS());
44350b57cec5SDimitry Andric       LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
44360b57cec5SDimitry Andric       CETy = LHSTy;
44370b57cec5SDimitry Andric     }
44380b57cec5SDimitry Andric     if (auto *CTy = RHSTy->getAs<ComplexType>()) {
44390b57cec5SDimitry Andric       RHS = CGF.EmitComplexExpr(E->getRHS());
44400b57cec5SDimitry Andric       assert(CGF.getContext().hasSameUnqualifiedType(CETy,
44410b57cec5SDimitry Andric                                                      CTy->getElementType()) &&
44420b57cec5SDimitry Andric              "The element types must always match.");
44430b57cec5SDimitry Andric       (void)CTy;
44440b57cec5SDimitry Andric     } else {
44450b57cec5SDimitry Andric       RHS.first = Visit(E->getRHS());
44460b57cec5SDimitry Andric       RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
44470b57cec5SDimitry Andric       assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) &&
44480b57cec5SDimitry Andric              "The element types must always match.");
44490b57cec5SDimitry Andric     }
44500b57cec5SDimitry Andric 
44510b57cec5SDimitry Andric     Value *ResultR, *ResultI;
44520b57cec5SDimitry Andric     if (CETy->isRealFloatingType()) {
4453480093f4SDimitry Andric       // As complex comparisons can only be equality comparisons, they
4454480093f4SDimitry Andric       // are never signaling comparisons.
44550b57cec5SDimitry Andric       ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r");
44560b57cec5SDimitry Andric       ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i");
44570b57cec5SDimitry Andric     } else {
44580b57cec5SDimitry Andric       // Complex comparisons can only be equality comparisons.  As such, signed
44590b57cec5SDimitry Andric       // and unsigned opcodes are the same.
44600b57cec5SDimitry Andric       ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r");
44610b57cec5SDimitry Andric       ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i");
44620b57cec5SDimitry Andric     }
44630b57cec5SDimitry Andric 
44640b57cec5SDimitry Andric     if (E->getOpcode() == BO_EQ) {
44650b57cec5SDimitry Andric       Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
44660b57cec5SDimitry Andric     } else {
44670b57cec5SDimitry Andric       assert(E->getOpcode() == BO_NE &&
44680b57cec5SDimitry Andric              "Complex comparison other than == or != ?");
44690b57cec5SDimitry Andric       Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
44700b57cec5SDimitry Andric     }
44710b57cec5SDimitry Andric   }
44720b57cec5SDimitry Andric 
44730b57cec5SDimitry Andric   return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
44740b57cec5SDimitry Andric                               E->getExprLoc());
44750b57cec5SDimitry Andric }
44760b57cec5SDimitry Andric 
VisitBinAssign(const BinaryOperator * E)44770b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
44780b57cec5SDimitry Andric   bool Ignore = TestAndClearIgnoreResultAssign();
44790b57cec5SDimitry Andric 
44800b57cec5SDimitry Andric   Value *RHS;
44810b57cec5SDimitry Andric   LValue LHS;
44820b57cec5SDimitry Andric 
44830b57cec5SDimitry Andric   switch (E->getLHS()->getType().getObjCLifetime()) {
44840b57cec5SDimitry Andric   case Qualifiers::OCL_Strong:
44850b57cec5SDimitry Andric     std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
44860b57cec5SDimitry Andric     break;
44870b57cec5SDimitry Andric 
44880b57cec5SDimitry Andric   case Qualifiers::OCL_Autoreleasing:
44890b57cec5SDimitry Andric     std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E);
44900b57cec5SDimitry Andric     break;
44910b57cec5SDimitry Andric 
44920b57cec5SDimitry Andric   case Qualifiers::OCL_ExplicitNone:
44930b57cec5SDimitry Andric     std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore);
44940b57cec5SDimitry Andric     break;
44950b57cec5SDimitry Andric 
44960b57cec5SDimitry Andric   case Qualifiers::OCL_Weak:
44970b57cec5SDimitry Andric     RHS = Visit(E->getRHS());
44980b57cec5SDimitry Andric     LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
4499480093f4SDimitry Andric     RHS = CGF.EmitARCStoreWeak(LHS.getAddress(CGF), RHS, Ignore);
45000b57cec5SDimitry Andric     break;
45010b57cec5SDimitry Andric 
45020b57cec5SDimitry Andric   case Qualifiers::OCL_None:
45030b57cec5SDimitry Andric     // __block variables need to have the rhs evaluated first, plus
45040b57cec5SDimitry Andric     // this should improve codegen just a little.
45050b57cec5SDimitry Andric     RHS = Visit(E->getRHS());
45060b57cec5SDimitry Andric     LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
45070b57cec5SDimitry Andric 
45080b57cec5SDimitry Andric     // Store the value into the LHS.  Bit-fields are handled specially
45090b57cec5SDimitry Andric     // because the result is altered by the store, i.e., [C99 6.5.16p1]
45100b57cec5SDimitry Andric     // 'An assignment expression has the value of the left operand after
45110b57cec5SDimitry Andric     // the assignment...'.
45120b57cec5SDimitry Andric     if (LHS.isBitField()) {
45130b57cec5SDimitry Andric       CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
45140b57cec5SDimitry Andric     } else {
45150b57cec5SDimitry Andric       CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
45160b57cec5SDimitry Andric       CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
45170b57cec5SDimitry Andric     }
45180b57cec5SDimitry Andric   }
45190b57cec5SDimitry Andric 
45200b57cec5SDimitry Andric   // If the result is clearly ignored, return now.
45210b57cec5SDimitry Andric   if (Ignore)
45220b57cec5SDimitry Andric     return nullptr;
45230b57cec5SDimitry Andric 
45240b57cec5SDimitry Andric   // The result of an assignment in C is the assigned r-value.
45250b57cec5SDimitry Andric   if (!CGF.getLangOpts().CPlusPlus)
45260b57cec5SDimitry Andric     return RHS;
45270b57cec5SDimitry Andric 
45280b57cec5SDimitry Andric   // If the lvalue is non-volatile, return the computed value of the assignment.
45290b57cec5SDimitry Andric   if (!LHS.isVolatileQualified())
45300b57cec5SDimitry Andric     return RHS;
45310b57cec5SDimitry Andric 
45320b57cec5SDimitry Andric   // Otherwise, reload the value.
45330b57cec5SDimitry Andric   return EmitLoadOfLValue(LHS, E->getExprLoc());
45340b57cec5SDimitry Andric }
45350b57cec5SDimitry Andric 
VisitBinLAnd(const BinaryOperator * E)45360b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
45370b57cec5SDimitry Andric   // Perform vector logical and on comparisons with zero vectors.
45380b57cec5SDimitry Andric   if (E->getType()->isVectorType()) {
45390b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
45400b57cec5SDimitry Andric 
45410b57cec5SDimitry Andric     Value *LHS = Visit(E->getLHS());
45420b57cec5SDimitry Andric     Value *RHS = Visit(E->getRHS());
45430b57cec5SDimitry Andric     Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
45440b57cec5SDimitry Andric     if (LHS->getType()->isFPOrFPVectorTy()) {
45455ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
45465ffd83dbSDimitry Andric           CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
45470b57cec5SDimitry Andric       LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
45480b57cec5SDimitry Andric       RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
45490b57cec5SDimitry Andric     } else {
45500b57cec5SDimitry Andric       LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
45510b57cec5SDimitry Andric       RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
45520b57cec5SDimitry Andric     }
45530b57cec5SDimitry Andric     Value *And = Builder.CreateAnd(LHS, RHS);
45540b57cec5SDimitry Andric     return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");
45550b57cec5SDimitry Andric   }
45560b57cec5SDimitry Andric 
4557e8d8bef9SDimitry Andric   bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
45580b57cec5SDimitry Andric   llvm::Type *ResTy = ConvertType(E->getType());
45590b57cec5SDimitry Andric 
45600b57cec5SDimitry Andric   // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
45610b57cec5SDimitry Andric   // If we have 1 && X, just emit X without inserting the control flow.
45620b57cec5SDimitry Andric   bool LHSCondVal;
45630b57cec5SDimitry Andric   if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
45640b57cec5SDimitry Andric     if (LHSCondVal) { // If we have 1 && X, just emit X.
45650b57cec5SDimitry Andric       CGF.incrementProfileCounter(E);
45660b57cec5SDimitry Andric 
4567cdc20ff6SDimitry Andric       // If the top of the logical operator nest, reset the MCDC temp to 0.
4568cdc20ff6SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
4569cdc20ff6SDimitry Andric         CGF.maybeResetMCDCCondBitmap(E);
4570cdc20ff6SDimitry Andric 
4571cdc20ff6SDimitry Andric       CGF.MCDCLogOpStack.push_back(E);
4572cdc20ff6SDimitry Andric 
45730b57cec5SDimitry Andric       Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4574e8d8bef9SDimitry Andric 
4575e8d8bef9SDimitry Andric       // If we're generating for profiling or coverage, generate a branch to a
4576e8d8bef9SDimitry Andric       // block that increments the RHS counter needed to track branch condition
4577e8d8bef9SDimitry Andric       // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
4578e8d8bef9SDimitry Andric       // "FalseBlock" after the increment is done.
4579e8d8bef9SDimitry Andric       if (InstrumentRegions &&
4580e8d8bef9SDimitry Andric           CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4581cdc20ff6SDimitry Andric         CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4582e8d8bef9SDimitry Andric         llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end");
4583e8d8bef9SDimitry Andric         llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4584e8d8bef9SDimitry Andric         Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4585e8d8bef9SDimitry Andric         CGF.EmitBlock(RHSBlockCnt);
4586e8d8bef9SDimitry Andric         CGF.incrementProfileCounter(E->getRHS());
4587e8d8bef9SDimitry Andric         CGF.EmitBranch(FBlock);
4588e8d8bef9SDimitry Andric         CGF.EmitBlock(FBlock);
4589e8d8bef9SDimitry Andric       }
4590e8d8bef9SDimitry Andric 
4591cdc20ff6SDimitry Andric       CGF.MCDCLogOpStack.pop_back();
4592cdc20ff6SDimitry Andric       // If the top of the logical operator nest, update the MCDC bitmap.
4593cdc20ff6SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
4594cdc20ff6SDimitry Andric         CGF.maybeUpdateMCDCTestVectorBitmap(E);
4595cdc20ff6SDimitry Andric 
45960b57cec5SDimitry Andric       // ZExt result to int or bool.
45970b57cec5SDimitry Andric       return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
45980b57cec5SDimitry Andric     }
45990b57cec5SDimitry Andric 
46000b57cec5SDimitry Andric     // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
46010b57cec5SDimitry Andric     if (!CGF.ContainsLabel(E->getRHS()))
46020b57cec5SDimitry Andric       return llvm::Constant::getNullValue(ResTy);
46030b57cec5SDimitry Andric   }
46040b57cec5SDimitry Andric 
4605cdc20ff6SDimitry Andric   // If the top of the logical operator nest, reset the MCDC temp to 0.
4606cdc20ff6SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4607cdc20ff6SDimitry Andric     CGF.maybeResetMCDCCondBitmap(E);
4608cdc20ff6SDimitry Andric 
4609cdc20ff6SDimitry Andric   CGF.MCDCLogOpStack.push_back(E);
4610cdc20ff6SDimitry Andric 
46110b57cec5SDimitry Andric   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
46120b57cec5SDimitry Andric   llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
46130b57cec5SDimitry Andric 
46140b57cec5SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
46150b57cec5SDimitry Andric 
46160b57cec5SDimitry Andric   // Branch on the LHS first.  If it is false, go to the failure (cont) block.
46170b57cec5SDimitry Andric   CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
46180b57cec5SDimitry Andric                            CGF.getProfileCount(E->getRHS()));
46190b57cec5SDimitry Andric 
46200b57cec5SDimitry Andric   // Any edges into the ContBlock are now from an (indeterminate number of)
46210b57cec5SDimitry Andric   // edges from this first condition.  All of these values will be false.  Start
46220b57cec5SDimitry Andric   // setting up the PHI node in the Cont Block for this.
46230b57cec5SDimitry Andric   llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
46240b57cec5SDimitry Andric                                             "", ContBlock);
46250b57cec5SDimitry Andric   for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
46260b57cec5SDimitry Andric        PI != PE; ++PI)
46270b57cec5SDimitry Andric     PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
46280b57cec5SDimitry Andric 
46290b57cec5SDimitry Andric   eval.begin(CGF);
46300b57cec5SDimitry Andric   CGF.EmitBlock(RHSBlock);
46310b57cec5SDimitry Andric   CGF.incrementProfileCounter(E);
46320b57cec5SDimitry Andric   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
46330b57cec5SDimitry Andric   eval.end(CGF);
46340b57cec5SDimitry Andric 
46350b57cec5SDimitry Andric   // Reaquire the RHS block, as there may be subblocks inserted.
46360b57cec5SDimitry Andric   RHSBlock = Builder.GetInsertBlock();
46370b57cec5SDimitry Andric 
4638e8d8bef9SDimitry Andric   // If we're generating for profiling or coverage, generate a branch on the
4639e8d8bef9SDimitry Andric   // RHS to a block that increments the RHS true counter needed to track branch
4640e8d8bef9SDimitry Andric   // condition coverage.
4641e8d8bef9SDimitry Andric   if (InstrumentRegions &&
4642e8d8bef9SDimitry Andric       CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4643cdc20ff6SDimitry Andric     CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4644e8d8bef9SDimitry Andric     llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4645e8d8bef9SDimitry Andric     Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4646e8d8bef9SDimitry Andric     CGF.EmitBlock(RHSBlockCnt);
4647e8d8bef9SDimitry Andric     CGF.incrementProfileCounter(E->getRHS());
4648e8d8bef9SDimitry Andric     CGF.EmitBranch(ContBlock);
4649e8d8bef9SDimitry Andric     PN->addIncoming(RHSCond, RHSBlockCnt);
4650e8d8bef9SDimitry Andric   }
4651e8d8bef9SDimitry Andric 
46520b57cec5SDimitry Andric   // Emit an unconditional branch from this block to ContBlock.
46530b57cec5SDimitry Andric   {
46540b57cec5SDimitry Andric     // There is no need to emit line number for unconditional branch.
46550b57cec5SDimitry Andric     auto NL = ApplyDebugLocation::CreateEmpty(CGF);
46560b57cec5SDimitry Andric     CGF.EmitBlock(ContBlock);
46570b57cec5SDimitry Andric   }
46580b57cec5SDimitry Andric   // Insert an entry into the phi node for the edge with the value of RHSCond.
46590b57cec5SDimitry Andric   PN->addIncoming(RHSCond, RHSBlock);
46600b57cec5SDimitry Andric 
4661cdc20ff6SDimitry Andric   CGF.MCDCLogOpStack.pop_back();
4662cdc20ff6SDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap.
4663cdc20ff6SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4664cdc20ff6SDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(E);
4665cdc20ff6SDimitry Andric 
46660b57cec5SDimitry Andric   // Artificial location to preserve the scope information
46670b57cec5SDimitry Andric   {
46680b57cec5SDimitry Andric     auto NL = ApplyDebugLocation::CreateArtificial(CGF);
46690b57cec5SDimitry Andric     PN->setDebugLoc(Builder.getCurrentDebugLocation());
46700b57cec5SDimitry Andric   }
46710b57cec5SDimitry Andric 
46720b57cec5SDimitry Andric   // ZExt result to int.
46730b57cec5SDimitry Andric   return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");
46740b57cec5SDimitry Andric }
46750b57cec5SDimitry Andric 
VisitBinLOr(const BinaryOperator * E)46760b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
46770b57cec5SDimitry Andric   // Perform vector logical or on comparisons with zero vectors.
46780b57cec5SDimitry Andric   if (E->getType()->isVectorType()) {
46790b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
46800b57cec5SDimitry Andric 
46810b57cec5SDimitry Andric     Value *LHS = Visit(E->getLHS());
46820b57cec5SDimitry Andric     Value *RHS = Visit(E->getRHS());
46830b57cec5SDimitry Andric     Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
46840b57cec5SDimitry Andric     if (LHS->getType()->isFPOrFPVectorTy()) {
46855ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
46865ffd83dbSDimitry Andric           CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
46870b57cec5SDimitry Andric       LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
46880b57cec5SDimitry Andric       RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
46890b57cec5SDimitry Andric     } else {
46900b57cec5SDimitry Andric       LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
46910b57cec5SDimitry Andric       RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
46920b57cec5SDimitry Andric     }
46930b57cec5SDimitry Andric     Value *Or = Builder.CreateOr(LHS, RHS);
46940b57cec5SDimitry Andric     return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");
46950b57cec5SDimitry Andric   }
46960b57cec5SDimitry Andric 
4697e8d8bef9SDimitry Andric   bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
46980b57cec5SDimitry Andric   llvm::Type *ResTy = ConvertType(E->getType());
46990b57cec5SDimitry Andric 
47000b57cec5SDimitry Andric   // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
47010b57cec5SDimitry Andric   // If we have 0 || X, just emit X without inserting the control flow.
47020b57cec5SDimitry Andric   bool LHSCondVal;
47030b57cec5SDimitry Andric   if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
47040b57cec5SDimitry Andric     if (!LHSCondVal) { // If we have 0 || X, just emit X.
47050b57cec5SDimitry Andric       CGF.incrementProfileCounter(E);
47060b57cec5SDimitry Andric 
4707cdc20ff6SDimitry Andric       // If the top of the logical operator nest, reset the MCDC temp to 0.
4708cdc20ff6SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
4709cdc20ff6SDimitry Andric         CGF.maybeResetMCDCCondBitmap(E);
4710cdc20ff6SDimitry Andric 
4711cdc20ff6SDimitry Andric       CGF.MCDCLogOpStack.push_back(E);
4712cdc20ff6SDimitry Andric 
47130b57cec5SDimitry Andric       Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4714e8d8bef9SDimitry Andric 
4715e8d8bef9SDimitry Andric       // If we're generating for profiling or coverage, generate a branch to a
4716e8d8bef9SDimitry Andric       // block that increments the RHS counter need to track branch condition
4717e8d8bef9SDimitry Andric       // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
4718e8d8bef9SDimitry Andric       // "FalseBlock" after the increment is done.
4719e8d8bef9SDimitry Andric       if (InstrumentRegions &&
4720e8d8bef9SDimitry Andric           CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4721cdc20ff6SDimitry Andric         CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4722e8d8bef9SDimitry Andric         llvm::BasicBlock *FBlock = CGF.createBasicBlock("lor.end");
4723e8d8bef9SDimitry Andric         llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
4724e8d8bef9SDimitry Andric         Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
4725e8d8bef9SDimitry Andric         CGF.EmitBlock(RHSBlockCnt);
4726e8d8bef9SDimitry Andric         CGF.incrementProfileCounter(E->getRHS());
4727e8d8bef9SDimitry Andric         CGF.EmitBranch(FBlock);
4728e8d8bef9SDimitry Andric         CGF.EmitBlock(FBlock);
4729e8d8bef9SDimitry Andric       }
4730e8d8bef9SDimitry Andric 
4731cdc20ff6SDimitry Andric       CGF.MCDCLogOpStack.pop_back();
4732cdc20ff6SDimitry Andric       // If the top of the logical operator nest, update the MCDC bitmap.
4733cdc20ff6SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
4734cdc20ff6SDimitry Andric         CGF.maybeUpdateMCDCTestVectorBitmap(E);
4735cdc20ff6SDimitry Andric 
47360b57cec5SDimitry Andric       // ZExt result to int or bool.
47370b57cec5SDimitry Andric       return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
47380b57cec5SDimitry Andric     }
47390b57cec5SDimitry Andric 
47400b57cec5SDimitry Andric     // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.
47410b57cec5SDimitry Andric     if (!CGF.ContainsLabel(E->getRHS()))
47420b57cec5SDimitry Andric       return llvm::ConstantInt::get(ResTy, 1);
47430b57cec5SDimitry Andric   }
47440b57cec5SDimitry Andric 
4745cdc20ff6SDimitry Andric   // If the top of the logical operator nest, reset the MCDC temp to 0.
4746cdc20ff6SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4747cdc20ff6SDimitry Andric     CGF.maybeResetMCDCCondBitmap(E);
4748cdc20ff6SDimitry Andric 
4749cdc20ff6SDimitry Andric   CGF.MCDCLogOpStack.push_back(E);
4750cdc20ff6SDimitry Andric 
47510b57cec5SDimitry Andric   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
47520b57cec5SDimitry Andric   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
47530b57cec5SDimitry Andric 
47540b57cec5SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
47550b57cec5SDimitry Andric 
47560b57cec5SDimitry Andric   // Branch on the LHS first.  If it is true, go to the success (cont) block.
47570b57cec5SDimitry Andric   CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock,
47580b57cec5SDimitry Andric                            CGF.getCurrentProfileCount() -
47590b57cec5SDimitry Andric                                CGF.getProfileCount(E->getRHS()));
47600b57cec5SDimitry Andric 
47610b57cec5SDimitry Andric   // Any edges into the ContBlock are now from an (indeterminate number of)
47620b57cec5SDimitry Andric   // edges from this first condition.  All of these values will be true.  Start
47630b57cec5SDimitry Andric   // setting up the PHI node in the Cont Block for this.
47640b57cec5SDimitry Andric   llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
47650b57cec5SDimitry Andric                                             "", ContBlock);
47660b57cec5SDimitry Andric   for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
47670b57cec5SDimitry Andric        PI != PE; ++PI)
47680b57cec5SDimitry Andric     PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
47690b57cec5SDimitry Andric 
47700b57cec5SDimitry Andric   eval.begin(CGF);
47710b57cec5SDimitry Andric 
47720b57cec5SDimitry Andric   // Emit the RHS condition as a bool value.
47730b57cec5SDimitry Andric   CGF.EmitBlock(RHSBlock);
47740b57cec5SDimitry Andric   CGF.incrementProfileCounter(E);
47750b57cec5SDimitry Andric   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
47760b57cec5SDimitry Andric 
47770b57cec5SDimitry Andric   eval.end(CGF);
47780b57cec5SDimitry Andric 
47790b57cec5SDimitry Andric   // Reaquire the RHS block, as there may be subblocks inserted.
47800b57cec5SDimitry Andric   RHSBlock = Builder.GetInsertBlock();
47810b57cec5SDimitry Andric 
4782e8d8bef9SDimitry Andric   // If we're generating for profiling or coverage, generate a branch on the
4783e8d8bef9SDimitry Andric   // RHS to a block that increments the RHS true counter needed to track branch
4784e8d8bef9SDimitry Andric   // condition coverage.
4785e8d8bef9SDimitry Andric   if (InstrumentRegions &&
4786e8d8bef9SDimitry Andric       CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
4787cdc20ff6SDimitry Andric     CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4788e8d8bef9SDimitry Andric     llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
4789e8d8bef9SDimitry Andric     Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
4790e8d8bef9SDimitry Andric     CGF.EmitBlock(RHSBlockCnt);
4791e8d8bef9SDimitry Andric     CGF.incrementProfileCounter(E->getRHS());
4792e8d8bef9SDimitry Andric     CGF.EmitBranch(ContBlock);
4793e8d8bef9SDimitry Andric     PN->addIncoming(RHSCond, RHSBlockCnt);
4794e8d8bef9SDimitry Andric   }
4795e8d8bef9SDimitry Andric 
47960b57cec5SDimitry Andric   // Emit an unconditional branch from this block to ContBlock.  Insert an entry
47970b57cec5SDimitry Andric   // into the phi node for the edge with the value of RHSCond.
47980b57cec5SDimitry Andric   CGF.EmitBlock(ContBlock);
47990b57cec5SDimitry Andric   PN->addIncoming(RHSCond, RHSBlock);
48000b57cec5SDimitry Andric 
4801cdc20ff6SDimitry Andric   CGF.MCDCLogOpStack.pop_back();
4802cdc20ff6SDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap.
4803cdc20ff6SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4804cdc20ff6SDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(E);
4805cdc20ff6SDimitry Andric 
48060b57cec5SDimitry Andric   // ZExt result to int.
48070b57cec5SDimitry Andric   return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");
48080b57cec5SDimitry Andric }
48090b57cec5SDimitry Andric 
VisitBinComma(const BinaryOperator * E)48100b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
48110b57cec5SDimitry Andric   CGF.EmitIgnoredExpr(E->getLHS());
48120b57cec5SDimitry Andric   CGF.EnsureInsertPoint();
48130b57cec5SDimitry Andric   return Visit(E->getRHS());
48140b57cec5SDimitry Andric }
48150b57cec5SDimitry Andric 
48160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
48170b57cec5SDimitry Andric //                             Other Operators
48180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
48190b57cec5SDimitry Andric 
48200b57cec5SDimitry Andric /// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
48210b57cec5SDimitry Andric /// expression is cheap enough and side-effect-free enough to evaluate
48220b57cec5SDimitry Andric /// unconditionally instead of conditionally.  This is used to convert control
48230b57cec5SDimitry Andric /// flow into selects in some cases.
isCheapEnoughToEvaluateUnconditionally(const Expr * E,CodeGenFunction & CGF)48240b57cec5SDimitry Andric static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
48250b57cec5SDimitry Andric                                                    CodeGenFunction &CGF) {
48260b57cec5SDimitry Andric   // Anything that is an integer or floating point constant is fine.
48270b57cec5SDimitry Andric   return E->IgnoreParens()->isEvaluatable(CGF.getContext());
48280b57cec5SDimitry Andric 
48290b57cec5SDimitry Andric   // Even non-volatile automatic variables can't be evaluated unconditionally.
48300b57cec5SDimitry Andric   // Referencing a thread_local may cause non-trivial initialization work to
48310b57cec5SDimitry Andric   // occur. If we're inside a lambda and one of the variables is from the scope
48320b57cec5SDimitry Andric   // outside the lambda, that function may have returned already. Reading its
48330b57cec5SDimitry Andric   // locals is a bad idea. Also, these reads may introduce races there didn't
48340b57cec5SDimitry Andric   // exist in the source-level program.
48350b57cec5SDimitry Andric }
48360b57cec5SDimitry Andric 
48370b57cec5SDimitry Andric 
48380b57cec5SDimitry Andric Value *ScalarExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)48390b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
48400b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
48410b57cec5SDimitry Andric 
48420b57cec5SDimitry Andric   // Bind the common expression if necessary.
48430b57cec5SDimitry Andric   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
48440b57cec5SDimitry Andric 
48450b57cec5SDimitry Andric   Expr *condExpr = E->getCond();
48460b57cec5SDimitry Andric   Expr *lhsExpr = E->getTrueExpr();
48470b57cec5SDimitry Andric   Expr *rhsExpr = E->getFalseExpr();
48480b57cec5SDimitry Andric 
48490b57cec5SDimitry Andric   // If the condition constant folds and can be elided, try to avoid emitting
48500b57cec5SDimitry Andric   // the condition and the dead arm.
48510b57cec5SDimitry Andric   bool CondExprBool;
48520b57cec5SDimitry Andric   if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
48530b57cec5SDimitry Andric     Expr *live = lhsExpr, *dead = rhsExpr;
48540b57cec5SDimitry Andric     if (!CondExprBool) std::swap(live, dead);
48550b57cec5SDimitry Andric 
48560b57cec5SDimitry Andric     // If the dead side doesn't have labels we need, just emit the Live part.
48570b57cec5SDimitry Andric     if (!CGF.ContainsLabel(dead)) {
48580b57cec5SDimitry Andric       if (CondExprBool)
48590b57cec5SDimitry Andric         CGF.incrementProfileCounter(E);
48600b57cec5SDimitry Andric       Value *Result = Visit(live);
48610b57cec5SDimitry Andric 
48620b57cec5SDimitry Andric       // If the live part is a throw expression, it acts like it has a void
48630b57cec5SDimitry Andric       // type, so evaluating it returns a null Value*.  However, a conditional
48640b57cec5SDimitry Andric       // with non-void type must return a non-null Value*.
48650b57cec5SDimitry Andric       if (!Result && !E->getType()->isVoidType())
48660b57cec5SDimitry Andric         Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
48670b57cec5SDimitry Andric 
48680b57cec5SDimitry Andric       return Result;
48690b57cec5SDimitry Andric     }
48700b57cec5SDimitry Andric   }
48710b57cec5SDimitry Andric 
48720b57cec5SDimitry Andric   // OpenCL: If the condition is a vector, we can treat this condition like
48730b57cec5SDimitry Andric   // the select function.
48745ffd83dbSDimitry Andric   if ((CGF.getLangOpts().OpenCL && condExpr->getType()->isVectorType()) ||
48755ffd83dbSDimitry Andric       condExpr->getType()->isExtVectorType()) {
48760b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
48770b57cec5SDimitry Andric 
48780b57cec5SDimitry Andric     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
48790b57cec5SDimitry Andric     llvm::Value *LHS = Visit(lhsExpr);
48800b57cec5SDimitry Andric     llvm::Value *RHS = Visit(rhsExpr);
48810b57cec5SDimitry Andric 
48820b57cec5SDimitry Andric     llvm::Type *condType = ConvertType(condExpr->getType());
4883e8d8bef9SDimitry Andric     auto *vecTy = cast<llvm::FixedVectorType>(condType);
48840b57cec5SDimitry Andric 
48850b57cec5SDimitry Andric     unsigned numElem = vecTy->getNumElements();
48860b57cec5SDimitry Andric     llvm::Type *elemType = vecTy->getElementType();
48870b57cec5SDimitry Andric 
48880b57cec5SDimitry Andric     llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
48890b57cec5SDimitry Andric     llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
48905ffd83dbSDimitry Andric     llvm::Value *tmp = Builder.CreateSExt(
48915ffd83dbSDimitry Andric         TestMSB, llvm::FixedVectorType::get(elemType, numElem), "sext");
48920b57cec5SDimitry Andric     llvm::Value *tmp2 = Builder.CreateNot(tmp);
48930b57cec5SDimitry Andric 
48940b57cec5SDimitry Andric     // Cast float to int to perform ANDs if necessary.
48950b57cec5SDimitry Andric     llvm::Value *RHSTmp = RHS;
48960b57cec5SDimitry Andric     llvm::Value *LHSTmp = LHS;
48970b57cec5SDimitry Andric     bool wasCast = false;
48980b57cec5SDimitry Andric     llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
48990b57cec5SDimitry Andric     if (rhsVTy->getElementType()->isFloatingPointTy()) {
49000b57cec5SDimitry Andric       RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
49010b57cec5SDimitry Andric       LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
49020b57cec5SDimitry Andric       wasCast = true;
49030b57cec5SDimitry Andric     }
49040b57cec5SDimitry Andric 
49050b57cec5SDimitry Andric     llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
49060b57cec5SDimitry Andric     llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
49070b57cec5SDimitry Andric     llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond");
49080b57cec5SDimitry Andric     if (wasCast)
49090b57cec5SDimitry Andric       tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
49100b57cec5SDimitry Andric 
49110b57cec5SDimitry Andric     return tmp5;
49120b57cec5SDimitry Andric   }
49130b57cec5SDimitry Andric 
491481ad6265SDimitry Andric   if (condExpr->getType()->isVectorType() ||
4915c9157d92SDimitry Andric       condExpr->getType()->isSveVLSBuiltinType()) {
4916480093f4SDimitry Andric     CGF.incrementProfileCounter(E);
4917480093f4SDimitry Andric 
4918480093f4SDimitry Andric     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
4919480093f4SDimitry Andric     llvm::Value *LHS = Visit(lhsExpr);
4920480093f4SDimitry Andric     llvm::Value *RHS = Visit(rhsExpr);
4921480093f4SDimitry Andric 
4922480093f4SDimitry Andric     llvm::Type *CondType = ConvertType(condExpr->getType());
4923480093f4SDimitry Andric     auto *VecTy = cast<llvm::VectorType>(CondType);
4924480093f4SDimitry Andric     llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
4925480093f4SDimitry Andric 
4926480093f4SDimitry Andric     CondV = Builder.CreateICmpNE(CondV, ZeroVec, "vector_cond");
4927480093f4SDimitry Andric     return Builder.CreateSelect(CondV, LHS, RHS, "vector_select");
4928480093f4SDimitry Andric   }
4929480093f4SDimitry Andric 
49300b57cec5SDimitry Andric   // If this is a really simple expression (like x ? 4 : 5), emit this as a
49310b57cec5SDimitry Andric   // select instead of as control flow.  We can only do this if it is cheap and
49320b57cec5SDimitry Andric   // safe to evaluate the LHS and RHS unconditionally.
49330b57cec5SDimitry Andric   if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
49340b57cec5SDimitry Andric       isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
49350b57cec5SDimitry Andric     llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
49360b57cec5SDimitry Andric     llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
49370b57cec5SDimitry Andric 
49380b57cec5SDimitry Andric     CGF.incrementProfileCounter(E, StepV);
49390b57cec5SDimitry Andric 
49400b57cec5SDimitry Andric     llvm::Value *LHS = Visit(lhsExpr);
49410b57cec5SDimitry Andric     llvm::Value *RHS = Visit(rhsExpr);
49420b57cec5SDimitry Andric     if (!LHS) {
49430b57cec5SDimitry Andric       // If the conditional has void type, make sure we return a null Value*.
49440b57cec5SDimitry Andric       assert(!RHS && "LHS and RHS types must match");
49450b57cec5SDimitry Andric       return nullptr;
49460b57cec5SDimitry Andric     }
49470b57cec5SDimitry Andric     return Builder.CreateSelect(CondV, LHS, RHS, "cond");
49480b57cec5SDimitry Andric   }
49490b57cec5SDimitry Andric 
4950cdc20ff6SDimitry Andric   // If the top of the logical operator nest, reset the MCDC temp to 0.
4951cdc20ff6SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4952cdc20ff6SDimitry Andric     CGF.maybeResetMCDCCondBitmap(condExpr);
4953cdc20ff6SDimitry Andric 
49540b57cec5SDimitry Andric   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
49550b57cec5SDimitry Andric   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
49560b57cec5SDimitry Andric   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
49570b57cec5SDimitry Andric 
49580b57cec5SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
49590b57cec5SDimitry Andric   CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock,
49600b57cec5SDimitry Andric                            CGF.getProfileCount(lhsExpr));
49610b57cec5SDimitry Andric 
49620b57cec5SDimitry Andric   CGF.EmitBlock(LHSBlock);
4963*a58f00eaSDimitry Andric 
4964*a58f00eaSDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap for the
4965*a58f00eaSDimitry Andric   // ConditionalOperator prior to visiting its LHS and RHS blocks, since they
4966*a58f00eaSDimitry Andric   // may also contain a boolean expression.
4967*a58f00eaSDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4968*a58f00eaSDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
4969*a58f00eaSDimitry Andric 
49700b57cec5SDimitry Andric   CGF.incrementProfileCounter(E);
49710b57cec5SDimitry Andric   eval.begin(CGF);
49720b57cec5SDimitry Andric   Value *LHS = Visit(lhsExpr);
49730b57cec5SDimitry Andric   eval.end(CGF);
49740b57cec5SDimitry Andric 
49750b57cec5SDimitry Andric   LHSBlock = Builder.GetInsertBlock();
49760b57cec5SDimitry Andric   Builder.CreateBr(ContBlock);
49770b57cec5SDimitry Andric 
49780b57cec5SDimitry Andric   CGF.EmitBlock(RHSBlock);
4979*a58f00eaSDimitry Andric 
4980*a58f00eaSDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap for the
4981*a58f00eaSDimitry Andric   // ConditionalOperator prior to visiting its LHS and RHS blocks, since they
4982*a58f00eaSDimitry Andric   // may also contain a boolean expression.
4983*a58f00eaSDimitry Andric   if (CGF.MCDCLogOpStack.empty())
4984*a58f00eaSDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
4985*a58f00eaSDimitry Andric 
49860b57cec5SDimitry Andric   eval.begin(CGF);
49870b57cec5SDimitry Andric   Value *RHS = Visit(rhsExpr);
49880b57cec5SDimitry Andric   eval.end(CGF);
49890b57cec5SDimitry Andric 
49900b57cec5SDimitry Andric   RHSBlock = Builder.GetInsertBlock();
49910b57cec5SDimitry Andric   CGF.EmitBlock(ContBlock);
49920b57cec5SDimitry Andric 
49930b57cec5SDimitry Andric   // If the LHS or RHS is a throw expression, it will be legitimately null.
49940b57cec5SDimitry Andric   if (!LHS)
49950b57cec5SDimitry Andric     return RHS;
49960b57cec5SDimitry Andric   if (!RHS)
49970b57cec5SDimitry Andric     return LHS;
49980b57cec5SDimitry Andric 
49990b57cec5SDimitry Andric   // Create a PHI node for the real part.
50000b57cec5SDimitry Andric   llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond");
50010b57cec5SDimitry Andric   PN->addIncoming(LHS, LHSBlock);
50020b57cec5SDimitry Andric   PN->addIncoming(RHS, RHSBlock);
5003cdc20ff6SDimitry Andric 
50040b57cec5SDimitry Andric   return PN;
50050b57cec5SDimitry Andric }
50060b57cec5SDimitry Andric 
VisitChooseExpr(ChooseExpr * E)50070b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
50080b57cec5SDimitry Andric   return Visit(E->getChosenSubExpr());
50090b57cec5SDimitry Andric }
50100b57cec5SDimitry Andric 
VisitVAArgExpr(VAArgExpr * VE)50110b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
50120b57cec5SDimitry Andric   QualType Ty = VE->getType();
50130b57cec5SDimitry Andric 
50140b57cec5SDimitry Andric   if (Ty->isVariablyModifiedType())
50150b57cec5SDimitry Andric     CGF.EmitVariablyModifiedType(Ty);
50160b57cec5SDimitry Andric 
50170b57cec5SDimitry Andric   Address ArgValue = Address::invalid();
50180b57cec5SDimitry Andric   Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
50190b57cec5SDimitry Andric 
50200b57cec5SDimitry Andric   llvm::Type *ArgTy = ConvertType(VE->getType());
50210b57cec5SDimitry Andric 
50220b57cec5SDimitry Andric   // If EmitVAArg fails, emit an error.
50230b57cec5SDimitry Andric   if (!ArgPtr.isValid()) {
50240b57cec5SDimitry Andric     CGF.ErrorUnsupported(VE, "va_arg expression");
50250b57cec5SDimitry Andric     return llvm::UndefValue::get(ArgTy);
50260b57cec5SDimitry Andric   }
50270b57cec5SDimitry Andric 
50280b57cec5SDimitry Andric   // FIXME Volatility.
50290b57cec5SDimitry Andric   llvm::Value *Val = Builder.CreateLoad(ArgPtr);
50300b57cec5SDimitry Andric 
50310b57cec5SDimitry Andric   // If EmitVAArg promoted the type, we must truncate it.
50320b57cec5SDimitry Andric   if (ArgTy != Val->getType()) {
50330b57cec5SDimitry Andric     if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
50340b57cec5SDimitry Andric       Val = Builder.CreateIntToPtr(Val, ArgTy);
50350b57cec5SDimitry Andric     else
50360b57cec5SDimitry Andric       Val = Builder.CreateTrunc(Val, ArgTy);
50370b57cec5SDimitry Andric   }
50380b57cec5SDimitry Andric 
50390b57cec5SDimitry Andric   return Val;
50400b57cec5SDimitry Andric }
50410b57cec5SDimitry Andric 
VisitBlockExpr(const BlockExpr * block)50420b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
50430b57cec5SDimitry Andric   return CGF.EmitBlockLiteral(block);
50440b57cec5SDimitry Andric }
50450b57cec5SDimitry Andric 
50460b57cec5SDimitry Andric // Convert a vec3 to vec4, or vice versa.
ConvertVec3AndVec4(CGBuilderTy & Builder,CodeGenFunction & CGF,Value * Src,unsigned NumElementsDst)50470b57cec5SDimitry Andric static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF,
50480b57cec5SDimitry Andric                                  Value *Src, unsigned NumElementsDst) {
50495ffd83dbSDimitry Andric   static constexpr int Mask[] = {0, 1, 2, -1};
5050bdd1243dSDimitry Andric   return Builder.CreateShuffleVector(Src, llvm::ArrayRef(Mask, NumElementsDst));
50510b57cec5SDimitry Andric }
50520b57cec5SDimitry Andric 
50530b57cec5SDimitry Andric // Create cast instructions for converting LLVM value \p Src to LLVM type \p
50540b57cec5SDimitry Andric // DstTy. \p Src has the same size as \p DstTy. Both are single value types
50550b57cec5SDimitry Andric // but could be scalar or vectors of different lengths, and either can be
50560b57cec5SDimitry Andric // pointer.
50570b57cec5SDimitry Andric // There are 4 cases:
50580b57cec5SDimitry Andric // 1. non-pointer -> non-pointer  : needs 1 bitcast
50590b57cec5SDimitry Andric // 2. pointer -> pointer          : needs 1 bitcast or addrspacecast
50600b57cec5SDimitry Andric // 3. pointer -> non-pointer
50610b57cec5SDimitry Andric //   a) pointer -> intptr_t       : needs 1 ptrtoint
50620b57cec5SDimitry Andric //   b) pointer -> non-intptr_t   : needs 1 ptrtoint then 1 bitcast
50630b57cec5SDimitry Andric // 4. non-pointer -> pointer
50640b57cec5SDimitry Andric //   a) intptr_t -> pointer       : needs 1 inttoptr
50650b57cec5SDimitry Andric //   b) non-intptr_t -> pointer   : needs 1 bitcast then 1 inttoptr
50660b57cec5SDimitry Andric // Note: for cases 3b and 4b two casts are required since LLVM casts do not
50670b57cec5SDimitry Andric // allow casting directly between pointer types and non-integer non-pointer
50680b57cec5SDimitry Andric // types.
createCastsForTypeOfSameSize(CGBuilderTy & Builder,const llvm::DataLayout & DL,Value * Src,llvm::Type * DstTy,StringRef Name="")50690b57cec5SDimitry Andric static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
50700b57cec5SDimitry Andric                                            const llvm::DataLayout &DL,
50710b57cec5SDimitry Andric                                            Value *Src, llvm::Type *DstTy,
50720b57cec5SDimitry Andric                                            StringRef Name = "") {
50730b57cec5SDimitry Andric   auto SrcTy = Src->getType();
50740b57cec5SDimitry Andric 
50750b57cec5SDimitry Andric   // Case 1.
50760b57cec5SDimitry Andric   if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
50770b57cec5SDimitry Andric     return Builder.CreateBitCast(Src, DstTy, Name);
50780b57cec5SDimitry Andric 
50790b57cec5SDimitry Andric   // Case 2.
50800b57cec5SDimitry Andric   if (SrcTy->isPointerTy() && DstTy->isPointerTy())
50810b57cec5SDimitry Andric     return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
50820b57cec5SDimitry Andric 
50830b57cec5SDimitry Andric   // Case 3.
50840b57cec5SDimitry Andric   if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
50850b57cec5SDimitry Andric     // Case 3b.
50860b57cec5SDimitry Andric     if (!DstTy->isIntegerTy())
50870b57cec5SDimitry Andric       Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
50880b57cec5SDimitry Andric     // Cases 3a and 3b.
50890b57cec5SDimitry Andric     return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
50900b57cec5SDimitry Andric   }
50910b57cec5SDimitry Andric 
50920b57cec5SDimitry Andric   // Case 4b.
50930b57cec5SDimitry Andric   if (!SrcTy->isIntegerTy())
50940b57cec5SDimitry Andric     Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
50950b57cec5SDimitry Andric   // Cases 4a and 4b.
50960b57cec5SDimitry Andric   return Builder.CreateIntToPtr(Src, DstTy, Name);
50970b57cec5SDimitry Andric }
50980b57cec5SDimitry Andric 
VisitAsTypeExpr(AsTypeExpr * E)50990b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
51000b57cec5SDimitry Andric   Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr());
51010b57cec5SDimitry Andric   llvm::Type *DstTy = ConvertType(E->getType());
51020b57cec5SDimitry Andric 
51030b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
5104e8d8bef9SDimitry Andric   unsigned NumElementsSrc =
5105e8d8bef9SDimitry Andric       isa<llvm::VectorType>(SrcTy)
5106e8d8bef9SDimitry Andric           ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5107e8d8bef9SDimitry Andric           : 0;
5108e8d8bef9SDimitry Andric   unsigned NumElementsDst =
5109e8d8bef9SDimitry Andric       isa<llvm::VectorType>(DstTy)
5110e8d8bef9SDimitry Andric           ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5111e8d8bef9SDimitry Andric           : 0;
51120b57cec5SDimitry Andric 
511381ad6265SDimitry Andric   // Use bit vector expansion for ext_vector_type boolean vectors.
511481ad6265SDimitry Andric   if (E->getType()->isExtVectorBoolType())
511581ad6265SDimitry Andric     return CGF.emitBoolVecConversion(Src, NumElementsDst, "astype");
511681ad6265SDimitry Andric 
51170b57cec5SDimitry Andric   // Going from vec3 to non-vec3 is a special case and requires a shuffle
51180b57cec5SDimitry Andric   // vector to get a vec4, then a bitcast if the target type is different.
51190b57cec5SDimitry Andric   if (NumElementsSrc == 3 && NumElementsDst != 3) {
51200b57cec5SDimitry Andric     Src = ConvertVec3AndVec4(Builder, CGF, Src, 4);
51210b57cec5SDimitry Andric     Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
51220b57cec5SDimitry Andric                                        DstTy);
51230b57cec5SDimitry Andric 
51240b57cec5SDimitry Andric     Src->setName("astype");
51250b57cec5SDimitry Andric     return Src;
51260b57cec5SDimitry Andric   }
51270b57cec5SDimitry Andric 
51280b57cec5SDimitry Andric   // Going from non-vec3 to vec3 is a special case and requires a bitcast
51290b57cec5SDimitry Andric   // to vec4 if the original type is not vec4, then a shuffle vector to
51300b57cec5SDimitry Andric   // get a vec3.
51310b57cec5SDimitry Andric   if (NumElementsSrc != 3 && NumElementsDst == 3) {
51325ffd83dbSDimitry Andric     auto *Vec4Ty = llvm::FixedVectorType::get(
51335ffd83dbSDimitry Andric         cast<llvm::VectorType>(DstTy)->getElementType(), 4);
51340b57cec5SDimitry Andric     Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
51350b57cec5SDimitry Andric                                        Vec4Ty);
51360b57cec5SDimitry Andric 
51370b57cec5SDimitry Andric     Src = ConvertVec3AndVec4(Builder, CGF, Src, 3);
51380b57cec5SDimitry Andric     Src->setName("astype");
51390b57cec5SDimitry Andric     return Src;
51400b57cec5SDimitry Andric   }
51410b57cec5SDimitry Andric 
5142a7dea167SDimitry Andric   return createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(),
51430b57cec5SDimitry Andric                                       Src, DstTy, "astype");
51440b57cec5SDimitry Andric }
51450b57cec5SDimitry Andric 
VisitAtomicExpr(AtomicExpr * E)51460b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
51470b57cec5SDimitry Andric   return CGF.EmitAtomicExpr(E).getScalarVal();
51480b57cec5SDimitry Andric }
51490b57cec5SDimitry Andric 
51500b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
51510b57cec5SDimitry Andric //                         Entry Point into this File
51520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
51530b57cec5SDimitry Andric 
51540b57cec5SDimitry Andric /// Emit the computation of the specified expression of scalar type, ignoring
51550b57cec5SDimitry Andric /// the result.
EmitScalarExpr(const Expr * E,bool IgnoreResultAssign)51560b57cec5SDimitry Andric Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
51570b57cec5SDimitry Andric   assert(E && hasScalarEvaluationKind(E->getType()) &&
51580b57cec5SDimitry Andric          "Invalid scalar expression to emit");
51590b57cec5SDimitry Andric 
51600b57cec5SDimitry Andric   return ScalarExprEmitter(*this, IgnoreResultAssign)
51610b57cec5SDimitry Andric       .Visit(const_cast<Expr *>(E));
51620b57cec5SDimitry Andric }
51630b57cec5SDimitry Andric 
51640b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
51650b57cec5SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)51660b57cec5SDimitry Andric Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
51670b57cec5SDimitry Andric                                              QualType DstTy,
51680b57cec5SDimitry Andric                                              SourceLocation Loc) {
51690b57cec5SDimitry Andric   assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
51700b57cec5SDimitry Andric          "Invalid scalar expression to emit");
51710b57cec5SDimitry Andric   return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
51720b57cec5SDimitry Andric }
51730b57cec5SDimitry Andric 
51740b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
51750b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)51760b57cec5SDimitry Andric Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
51770b57cec5SDimitry Andric                                                       QualType SrcTy,
51780b57cec5SDimitry Andric                                                       QualType DstTy,
51790b57cec5SDimitry Andric                                                       SourceLocation Loc) {
51800b57cec5SDimitry Andric   assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) &&
51810b57cec5SDimitry Andric          "Invalid complex -> scalar conversion");
51820b57cec5SDimitry Andric   return ScalarExprEmitter(*this)
51830b57cec5SDimitry Andric       .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
51840b57cec5SDimitry Andric }
51850b57cec5SDimitry Andric 
51860b57cec5SDimitry Andric 
5187bdd1243dSDimitry Andric Value *
EmitPromotedScalarExpr(const Expr * E,QualType PromotionType)5188bdd1243dSDimitry Andric CodeGenFunction::EmitPromotedScalarExpr(const Expr *E,
5189bdd1243dSDimitry Andric                                         QualType PromotionType) {
5190bdd1243dSDimitry Andric   if (!PromotionType.isNull())
5191bdd1243dSDimitry Andric     return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5192bdd1243dSDimitry Andric   else
5193bdd1243dSDimitry Andric     return ScalarExprEmitter(*this).Visit(const_cast<Expr *>(E));
5194bdd1243dSDimitry Andric }
5195bdd1243dSDimitry Andric 
5196bdd1243dSDimitry Andric 
51970b57cec5SDimitry Andric llvm::Value *CodeGenFunction::
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)51980b57cec5SDimitry Andric EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
51990b57cec5SDimitry Andric                         bool isInc, bool isPre) {
52000b57cec5SDimitry Andric   return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
52010b57cec5SDimitry Andric }
52020b57cec5SDimitry Andric 
EmitObjCIsaExpr(const ObjCIsaExpr * E)52030b57cec5SDimitry Andric LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
52040b57cec5SDimitry Andric   // object->isa or (*object).isa
52050b57cec5SDimitry Andric   // Generate code as for: *(Class*)object
52060b57cec5SDimitry Andric 
52070b57cec5SDimitry Andric   Expr *BaseExpr = E->getBase();
52080b57cec5SDimitry Andric   Address Addr = Address::invalid();
5209fe6060f1SDimitry Andric   if (BaseExpr->isPRValue()) {
521081ad6265SDimitry Andric     llvm::Type *BaseTy =
521181ad6265SDimitry Andric         ConvertTypeForMem(BaseExpr->getType()->getPointeeType());
521281ad6265SDimitry Andric     Addr = Address(EmitScalarExpr(BaseExpr), BaseTy, getPointerAlign());
52130b57cec5SDimitry Andric   } else {
5214480093f4SDimitry Andric     Addr = EmitLValue(BaseExpr).getAddress(*this);
52150b57cec5SDimitry Andric   }
52160b57cec5SDimitry Andric 
52170b57cec5SDimitry Andric   // Cast the address to Class*.
5218fe013be4SDimitry Andric   Addr = Addr.withElementType(ConvertType(E->getType()));
52190b57cec5SDimitry Andric   return MakeAddrLValue(Addr, E->getType());
52200b57cec5SDimitry Andric }
52210b57cec5SDimitry Andric 
52220b57cec5SDimitry Andric 
EmitCompoundAssignmentLValue(const CompoundAssignOperator * E)52230b57cec5SDimitry Andric LValue CodeGenFunction::EmitCompoundAssignmentLValue(
52240b57cec5SDimitry Andric                                             const CompoundAssignOperator *E) {
52250b57cec5SDimitry Andric   ScalarExprEmitter Scalar(*this);
52260b57cec5SDimitry Andric   Value *Result = nullptr;
52270b57cec5SDimitry Andric   switch (E->getOpcode()) {
52280b57cec5SDimitry Andric #define COMPOUND_OP(Op)                                                       \
52290b57cec5SDimitry Andric     case BO_##Op##Assign:                                                     \
52300b57cec5SDimitry Andric       return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
52310b57cec5SDimitry Andric                                              Result)
52320b57cec5SDimitry Andric   COMPOUND_OP(Mul);
52330b57cec5SDimitry Andric   COMPOUND_OP(Div);
52340b57cec5SDimitry Andric   COMPOUND_OP(Rem);
52350b57cec5SDimitry Andric   COMPOUND_OP(Add);
52360b57cec5SDimitry Andric   COMPOUND_OP(Sub);
52370b57cec5SDimitry Andric   COMPOUND_OP(Shl);
52380b57cec5SDimitry Andric   COMPOUND_OP(Shr);
52390b57cec5SDimitry Andric   COMPOUND_OP(And);
52400b57cec5SDimitry Andric   COMPOUND_OP(Xor);
52410b57cec5SDimitry Andric   COMPOUND_OP(Or);
52420b57cec5SDimitry Andric #undef COMPOUND_OP
52430b57cec5SDimitry Andric 
52440b57cec5SDimitry Andric   case BO_PtrMemD:
52450b57cec5SDimitry Andric   case BO_PtrMemI:
52460b57cec5SDimitry Andric   case BO_Mul:
52470b57cec5SDimitry Andric   case BO_Div:
52480b57cec5SDimitry Andric   case BO_Rem:
52490b57cec5SDimitry Andric   case BO_Add:
52500b57cec5SDimitry Andric   case BO_Sub:
52510b57cec5SDimitry Andric   case BO_Shl:
52520b57cec5SDimitry Andric   case BO_Shr:
52530b57cec5SDimitry Andric   case BO_LT:
52540b57cec5SDimitry Andric   case BO_GT:
52550b57cec5SDimitry Andric   case BO_LE:
52560b57cec5SDimitry Andric   case BO_GE:
52570b57cec5SDimitry Andric   case BO_EQ:
52580b57cec5SDimitry Andric   case BO_NE:
52590b57cec5SDimitry Andric   case BO_Cmp:
52600b57cec5SDimitry Andric   case BO_And:
52610b57cec5SDimitry Andric   case BO_Xor:
52620b57cec5SDimitry Andric   case BO_Or:
52630b57cec5SDimitry Andric   case BO_LAnd:
52640b57cec5SDimitry Andric   case BO_LOr:
52650b57cec5SDimitry Andric   case BO_Assign:
52660b57cec5SDimitry Andric   case BO_Comma:
52670b57cec5SDimitry Andric     llvm_unreachable("Not valid compound assignment operators");
52680b57cec5SDimitry Andric   }
52690b57cec5SDimitry Andric 
52700b57cec5SDimitry Andric   llvm_unreachable("Unhandled compound assignment operator");
52710b57cec5SDimitry Andric }
52720b57cec5SDimitry Andric 
5273a7dea167SDimitry Andric struct GEPOffsetAndOverflow {
5274a7dea167SDimitry Andric   // The total (signed) byte offset for the GEP.
5275a7dea167SDimitry Andric   llvm::Value *TotalOffset;
5276a7dea167SDimitry Andric   // The offset overflow flag - true if the total offset overflows.
5277a7dea167SDimitry Andric   llvm::Value *OffsetOverflows;
5278a7dea167SDimitry Andric };
52790b57cec5SDimitry Andric 
5280a7dea167SDimitry Andric /// Evaluate given GEPVal, which is either an inbounds GEP, or a constant,
5281a7dea167SDimitry Andric /// and compute the total offset it applies from it's base pointer BasePtr.
5282a7dea167SDimitry Andric /// Returns offset in bytes and a boolean flag whether an overflow happened
5283a7dea167SDimitry Andric /// during evaluation.
EmitGEPOffsetInBytes(Value * BasePtr,Value * GEPVal,llvm::LLVMContext & VMContext,CodeGenModule & CGM,CGBuilderTy & Builder)5284a7dea167SDimitry Andric static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal,
5285a7dea167SDimitry Andric                                                  llvm::LLVMContext &VMContext,
5286a7dea167SDimitry Andric                                                  CodeGenModule &CGM,
52875ffd83dbSDimitry Andric                                                  CGBuilderTy &Builder) {
5288a7dea167SDimitry Andric   const auto &DL = CGM.getDataLayout();
52890b57cec5SDimitry Andric 
5290a7dea167SDimitry Andric   // The total (signed) byte offset for the GEP.
5291a7dea167SDimitry Andric   llvm::Value *TotalOffset = nullptr;
52920b57cec5SDimitry Andric 
5293a7dea167SDimitry Andric   // Was the GEP already reduced to a constant?
5294a7dea167SDimitry Andric   if (isa<llvm::Constant>(GEPVal)) {
5295a7dea167SDimitry Andric     // Compute the offset by casting both pointers to integers and subtracting:
5296a7dea167SDimitry Andric     // GEPVal = BasePtr + ptr(Offset) <--> Offset = int(GEPVal) - int(BasePtr)
5297a7dea167SDimitry Andric     Value *BasePtr_int =
5298a7dea167SDimitry Andric         Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType()));
5299a7dea167SDimitry Andric     Value *GEPVal_int =
5300a7dea167SDimitry Andric         Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType()));
5301a7dea167SDimitry Andric     TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5302a7dea167SDimitry Andric     return {TotalOffset, /*OffsetOverflows=*/Builder.getFalse()};
5303a7dea167SDimitry Andric   }
53040b57cec5SDimitry Andric 
53050b57cec5SDimitry Andric   auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5306a7dea167SDimitry Andric   assert(GEP->getPointerOperand() == BasePtr &&
5307349cc55cSDimitry Andric          "BasePtr must be the base of the GEP.");
53080b57cec5SDimitry Andric   assert(GEP->isInBounds() && "Expected inbounds GEP");
53090b57cec5SDimitry Andric 
53100b57cec5SDimitry Andric   auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
53110b57cec5SDimitry Andric 
53120b57cec5SDimitry Andric   // Grab references to the signed add/mul overflow intrinsics for intptr_t.
53130b57cec5SDimitry Andric   auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
53140b57cec5SDimitry Andric   auto *SAddIntrinsic =
53150b57cec5SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
53160b57cec5SDimitry Andric   auto *SMulIntrinsic =
53170b57cec5SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
53180b57cec5SDimitry Andric 
53190b57cec5SDimitry Andric   // The offset overflow flag - true if the total offset overflows.
53200b57cec5SDimitry Andric   llvm::Value *OffsetOverflows = Builder.getFalse();
53210b57cec5SDimitry Andric 
53220b57cec5SDimitry Andric   /// Return the result of the given binary operation.
53230b57cec5SDimitry Andric   auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
53240b57cec5SDimitry Andric                   llvm::Value *RHS) -> llvm::Value * {
53250b57cec5SDimitry Andric     assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop");
53260b57cec5SDimitry Andric 
53270b57cec5SDimitry Andric     // If the operands are constants, return a constant result.
53280b57cec5SDimitry Andric     if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
53290b57cec5SDimitry Andric       if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
53300b57cec5SDimitry Andric         llvm::APInt N;
53310b57cec5SDimitry Andric         bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
53320b57cec5SDimitry Andric                                                   /*Signed=*/true, N);
53330b57cec5SDimitry Andric         if (HasOverflow)
53340b57cec5SDimitry Andric           OffsetOverflows = Builder.getTrue();
53350b57cec5SDimitry Andric         return llvm::ConstantInt::get(VMContext, N);
53360b57cec5SDimitry Andric       }
53370b57cec5SDimitry Andric     }
53380b57cec5SDimitry Andric 
53390b57cec5SDimitry Andric     // Otherwise, compute the result with checked arithmetic.
53400b57cec5SDimitry Andric     auto *ResultAndOverflow = Builder.CreateCall(
53410b57cec5SDimitry Andric         (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
53420b57cec5SDimitry Andric     OffsetOverflows = Builder.CreateOr(
53430b57cec5SDimitry Andric         Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
53440b57cec5SDimitry Andric     return Builder.CreateExtractValue(ResultAndOverflow, 0);
53450b57cec5SDimitry Andric   };
53460b57cec5SDimitry Andric 
53470b57cec5SDimitry Andric   // Determine the total byte offset by looking at each GEP operand.
53480b57cec5SDimitry Andric   for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
53490b57cec5SDimitry Andric        GTI != GTE; ++GTI) {
53500b57cec5SDimitry Andric     llvm::Value *LocalOffset;
53510b57cec5SDimitry Andric     auto *Index = GTI.getOperand();
53520b57cec5SDimitry Andric     // Compute the local offset contributed by this indexing step:
53530b57cec5SDimitry Andric     if (auto *STy = GTI.getStructTypeOrNull()) {
53540b57cec5SDimitry Andric       // For struct indexing, the local offset is the byte position of the
53550b57cec5SDimitry Andric       // specified field.
53560b57cec5SDimitry Andric       unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
53570b57cec5SDimitry Andric       LocalOffset = llvm::ConstantInt::get(
53580b57cec5SDimitry Andric           IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
53590b57cec5SDimitry Andric     } else {
53600b57cec5SDimitry Andric       // Otherwise this is array-like indexing. The local offset is the index
53610b57cec5SDimitry Andric       // multiplied by the element size.
5362cdc20ff6SDimitry Andric       auto *ElementSize =
5363cdc20ff6SDimitry Andric           llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
53640b57cec5SDimitry Andric       auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
53650b57cec5SDimitry Andric       LocalOffset = eval(BO_Mul, ElementSize, IndexS);
53660b57cec5SDimitry Andric     }
53670b57cec5SDimitry Andric 
53680b57cec5SDimitry Andric     // If this is the first offset, set it as the total offset. Otherwise, add
53690b57cec5SDimitry Andric     // the local offset into the running total.
53700b57cec5SDimitry Andric     if (!TotalOffset || TotalOffset == Zero)
53710b57cec5SDimitry Andric       TotalOffset = LocalOffset;
53720b57cec5SDimitry Andric     else
53730b57cec5SDimitry Andric       TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
53740b57cec5SDimitry Andric   }
53750b57cec5SDimitry Andric 
5376a7dea167SDimitry Andric   return {TotalOffset, OffsetOverflows};
5377a7dea167SDimitry Andric }
5378a7dea167SDimitry Andric 
5379a7dea167SDimitry Andric Value *
EmitCheckedInBoundsGEP(llvm::Type * ElemTy,Value * Ptr,ArrayRef<Value * > IdxList,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,const Twine & Name)53800eae32dcSDimitry Andric CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
53810eae32dcSDimitry Andric                                         ArrayRef<Value *> IdxList,
5382a7dea167SDimitry Andric                                         bool SignedIndices, bool IsSubtraction,
5383a7dea167SDimitry Andric                                         SourceLocation Loc, const Twine &Name) {
5384fe6060f1SDimitry Andric   llvm::Type *PtrTy = Ptr->getType();
53850eae32dcSDimitry Andric   Value *GEPVal = Builder.CreateInBoundsGEP(ElemTy, Ptr, IdxList, Name);
5386a7dea167SDimitry Andric 
5387a7dea167SDimitry Andric   // If the pointer overflow sanitizer isn't enabled, do nothing.
5388a7dea167SDimitry Andric   if (!SanOpts.has(SanitizerKind::PointerOverflow))
5389a7dea167SDimitry Andric     return GEPVal;
5390a7dea167SDimitry Andric 
5391a7dea167SDimitry Andric   // Perform nullptr-and-offset check unless the nullptr is defined.
5392a7dea167SDimitry Andric   bool PerformNullCheck = !NullPointerIsDefined(
5393a7dea167SDimitry Andric       Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5394a7dea167SDimitry Andric   // Check for overflows unless the GEP got constant-folded,
5395a7dea167SDimitry Andric   // and only in the default address space
5396a7dea167SDimitry Andric   bool PerformOverflowCheck =
5397a7dea167SDimitry Andric       !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5398a7dea167SDimitry Andric 
5399a7dea167SDimitry Andric   if (!(PerformNullCheck || PerformOverflowCheck))
5400a7dea167SDimitry Andric     return GEPVal;
5401a7dea167SDimitry Andric 
5402a7dea167SDimitry Andric   const auto &DL = CGM.getDataLayout();
5403a7dea167SDimitry Andric 
5404a7dea167SDimitry Andric   SanitizerScope SanScope(this);
5405a7dea167SDimitry Andric   llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
5406a7dea167SDimitry Andric 
5407a7dea167SDimitry Andric   GEPOffsetAndOverflow EvaluatedGEP =
5408a7dea167SDimitry Andric       EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder);
5409a7dea167SDimitry Andric 
5410a7dea167SDimitry Andric   assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
5411a7dea167SDimitry Andric           EvaluatedGEP.OffsetOverflows == Builder.getFalse()) &&
5412a7dea167SDimitry Andric          "If the offset got constant-folded, we don't expect that there was an "
5413a7dea167SDimitry Andric          "overflow.");
5414a7dea167SDimitry Andric 
5415a7dea167SDimitry Andric   auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5416a7dea167SDimitry Andric 
5417a7dea167SDimitry Andric   // Common case: if the total offset is zero, and we are using C++ semantics,
5418a7dea167SDimitry Andric   // where nullptr+0 is defined, don't emit a check.
5419a7dea167SDimitry Andric   if (EvaluatedGEP.TotalOffset == Zero && CGM.getLangOpts().CPlusPlus)
54200b57cec5SDimitry Andric     return GEPVal;
54210b57cec5SDimitry Andric 
54220b57cec5SDimitry Andric   // Now that we've computed the total offset, add it to the base pointer (with
54230b57cec5SDimitry Andric   // wrapping semantics).
5424a7dea167SDimitry Andric   auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
5425a7dea167SDimitry Andric   auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset);
54260b57cec5SDimitry Andric 
5427a7dea167SDimitry Andric   llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
5428a7dea167SDimitry Andric 
5429a7dea167SDimitry Andric   if (PerformNullCheck) {
5430a7dea167SDimitry Andric     // In C++, if the base pointer evaluates to a null pointer value,
5431a7dea167SDimitry Andric     // the only valid  pointer this inbounds GEP can produce is also
5432a7dea167SDimitry Andric     // a null pointer, so the offset must also evaluate to zero.
5433a7dea167SDimitry Andric     // Likewise, if we have non-zero base pointer, we can not get null pointer
5434a7dea167SDimitry Andric     // as a result, so the offset can not be -intptr_t(BasePtr).
5435a7dea167SDimitry Andric     // In other words, both pointers are either null, or both are non-null,
5436a7dea167SDimitry Andric     // or the behaviour is undefined.
5437a7dea167SDimitry Andric     //
5438a7dea167SDimitry Andric     // C, however, is more strict in this regard, and gives more
5439a7dea167SDimitry Andric     // optimization opportunities: in C, additionally, nullptr+0 is undefined.
5440a7dea167SDimitry Andric     // So both the input to the 'gep inbounds' AND the output must not be null.
5441a7dea167SDimitry Andric     auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
5442a7dea167SDimitry Andric     auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
5443a7dea167SDimitry Andric     auto *Valid =
5444a7dea167SDimitry Andric         CGM.getLangOpts().CPlusPlus
5445a7dea167SDimitry Andric             ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5446a7dea167SDimitry Andric             : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5447a7dea167SDimitry Andric     Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5448a7dea167SDimitry Andric   }
5449a7dea167SDimitry Andric 
5450a7dea167SDimitry Andric   if (PerformOverflowCheck) {
54510b57cec5SDimitry Andric     // The GEP is valid if:
54520b57cec5SDimitry Andric     // 1) The total offset doesn't overflow, and
54530b57cec5SDimitry Andric     // 2) The sign of the difference between the computed address and the base
54540b57cec5SDimitry Andric     // pointer matches the sign of the total offset.
54550b57cec5SDimitry Andric     llvm::Value *ValidGEP;
5456a7dea167SDimitry Andric     auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.OffsetOverflows);
54570b57cec5SDimitry Andric     if (SignedIndices) {
5458a7dea167SDimitry Andric       // GEP is computed as `unsigned base + signed offset`, therefore:
5459a7dea167SDimitry Andric       // * If offset was positive, then the computed pointer can not be
5460a7dea167SDimitry Andric       //   [unsigned] less than the base pointer, unless it overflowed.
5461a7dea167SDimitry Andric       // * If offset was negative, then the computed pointer can not be
5462a7dea167SDimitry Andric       //   [unsigned] greater than the bas pointere, unless it overflowed.
54630b57cec5SDimitry Andric       auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5464a7dea167SDimitry Andric       auto *PosOrZeroOffset =
5465a7dea167SDimitry Andric           Builder.CreateICmpSGE(EvaluatedGEP.TotalOffset, Zero);
54660b57cec5SDimitry Andric       llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
5467a7dea167SDimitry Andric       ValidGEP =
5468a7dea167SDimitry Andric           Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5469a7dea167SDimitry Andric     } else if (!IsSubtraction) {
5470a7dea167SDimitry Andric       // GEP is computed as `unsigned base + unsigned offset`,  therefore the
5471a7dea167SDimitry Andric       // computed pointer can not be [unsigned] less than base pointer,
5472a7dea167SDimitry Andric       // unless there was an overflow.
5473a7dea167SDimitry Andric       // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`.
5474a7dea167SDimitry Andric       ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
54750b57cec5SDimitry Andric     } else {
5476a7dea167SDimitry Andric       // GEP is computed as `unsigned base - unsigned offset`, therefore the
5477a7dea167SDimitry Andric       // computed pointer can not be [unsigned] greater than base pointer,
5478a7dea167SDimitry Andric       // unless there was an overflow.
5479a7dea167SDimitry Andric       // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`.
5480a7dea167SDimitry Andric       ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
54810b57cec5SDimitry Andric     }
5482a7dea167SDimitry Andric     ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5483a7dea167SDimitry Andric     Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5484a7dea167SDimitry Andric   }
5485a7dea167SDimitry Andric 
5486a7dea167SDimitry Andric   assert(!Checks.empty() && "Should have produced some checks.");
54870b57cec5SDimitry Andric 
54880b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
54890b57cec5SDimitry Andric   // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
54900b57cec5SDimitry Andric   llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5491a7dea167SDimitry Andric   EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
54920b57cec5SDimitry Andric 
54930b57cec5SDimitry Andric   return GEPVal;
54940b57cec5SDimitry Andric }
5495