diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 4766 | 
1 files changed, 4766 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp new file mode 100644 index 0000000000000..55a413a2a7179 --- /dev/null +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -0,0 +1,4766 @@ +//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This contains code to emit Expr nodes with scalar LLVM types as LLVM code. +// +//===----------------------------------------------------------------------===// + +#include "CGCXXABI.h" +#include "CGCleanup.h" +#include "CGDebugInfo.h" +#include "CGObjCRuntime.h" +#include "CodeGenFunction.h" +#include "CodeGenModule.h" +#include "ConstantEmitter.h" +#include "TargetInfo.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/FixedPoint.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/Optional.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" +#include <cstdarg> + +using namespace clang; +using namespace CodeGen; +using llvm::Value; + +//===----------------------------------------------------------------------===// +//                         Scalar Expression Emitter +//===----------------------------------------------------------------------===// + +namespace { + +/// Determine whether the given binary operation may overflow. +/// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul, +/// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem}, +/// the returned overflow check is precise. The returned value is 'true' for +/// all other opcodes, to be conservative. +bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS, +                             BinaryOperator::Opcode Opcode, bool Signed, +                             llvm::APInt &Result) { +  // Assume overflow is possible, unless we can prove otherwise. +  bool Overflow = true; +  const auto &LHSAP = LHS->getValue(); +  const auto &RHSAP = RHS->getValue(); +  if (Opcode == BO_Add) { +    if (Signed) +      Result = LHSAP.sadd_ov(RHSAP, Overflow); +    else +      Result = LHSAP.uadd_ov(RHSAP, Overflow); +  } else if (Opcode == BO_Sub) { +    if (Signed) +      Result = LHSAP.ssub_ov(RHSAP, Overflow); +    else +      Result = LHSAP.usub_ov(RHSAP, Overflow); +  } else if (Opcode == BO_Mul) { +    if (Signed) +      Result = LHSAP.smul_ov(RHSAP, Overflow); +    else +      Result = LHSAP.umul_ov(RHSAP, Overflow); +  } else if (Opcode == BO_Div || Opcode == BO_Rem) { +    if (Signed && !RHS->isZero()) +      Result = LHSAP.sdiv_ov(RHSAP, Overflow); +    else +      return false; +  } +  return Overflow; +} + +struct BinOpInfo { +  Value *LHS; +  Value *RHS; +  QualType Ty;  // Computation Type. +  BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform +  FPOptions FPFeatures; +  const Expr *E;      // Entire expr, for error unsupported.  May not be binop. + +  /// Check if the binop can result in integer overflow. +  bool mayHaveIntegerOverflow() const { +    // Without constant input, we can't rule out overflow. +    auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS); +    auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS); +    if (!LHSCI || !RHSCI) +      return true; + +    llvm::APInt Result; +    return ::mayHaveIntegerOverflow( +        LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result); +  } + +  /// Check if the binop computes a division or a remainder. +  bool isDivremOp() const { +    return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign || +           Opcode == BO_RemAssign; +  } + +  /// Check if the binop can result in an integer division by zero. +  bool mayHaveIntegerDivisionByZero() const { +    if (isDivremOp()) +      if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS)) +        return CI->isZero(); +    return true; +  } + +  /// Check if the binop can result in a float division by zero. +  bool mayHaveFloatDivisionByZero() const { +    if (isDivremOp()) +      if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS)) +        return CFP->isZero(); +    return true; +  } + +  /// Check if either operand is a fixed point type or integer type, with at +  /// least one being a fixed point type. In any case, this +  /// operation did not follow usual arithmetic conversion and both operands may +  /// not be the same. +  bool isFixedPointBinOp() const { +    // We cannot simply check the result type since comparison operations return +    // an int. +    if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) { +      QualType LHSType = BinOp->getLHS()->getType(); +      QualType RHSType = BinOp->getRHS()->getType(); +      return LHSType->isFixedPointType() || RHSType->isFixedPointType(); +    } +    return false; +  } +}; + +static bool MustVisitNullValue(const Expr *E) { +  // If a null pointer expression's type is the C++0x nullptr_t, then +  // it's not necessarily a simple constant and it must be evaluated +  // for its potential side effects. +  return E->getType()->isNullPtrType(); +} + +/// If \p E is a widened promoted integer, get its base (unpromoted) type. +static llvm::Optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx, +                                                        const Expr *E) { +  const Expr *Base = E->IgnoreImpCasts(); +  if (E == Base) +    return llvm::None; + +  QualType BaseTy = Base->getType(); +  if (!BaseTy->isPromotableIntegerType() || +      Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType())) +    return llvm::None; + +  return BaseTy; +} + +/// Check if \p E is a widened promoted integer. +static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) { +  return getUnwidenedIntegerType(Ctx, E).hasValue(); +} + +/// Check if we can skip the overflow check for \p Op. +static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) { +  assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) && +         "Expected a unary or binary operator"); + +  // If the binop has constant inputs and we can prove there is no overflow, +  // we can elide the overflow check. +  if (!Op.mayHaveIntegerOverflow()) +    return true; + +  // If a unary op has a widened operand, the op cannot overflow. +  if (const auto *UO = dyn_cast<UnaryOperator>(Op.E)) +    return !UO->canOverflow(); + +  // We usually don't need overflow checks for binops with widened operands. +  // Multiplication with promoted unsigned operands is a special case. +  const auto *BO = cast<BinaryOperator>(Op.E); +  auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS()); +  if (!OptionalLHSTy) +    return false; + +  auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS()); +  if (!OptionalRHSTy) +    return false; + +  QualType LHSTy = *OptionalLHSTy; +  QualType RHSTy = *OptionalRHSTy; + +  // This is the simple case: binops without unsigned multiplication, and with +  // widened operands. No overflow check is needed here. +  if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) || +      !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType()) +    return true; + +  // For unsigned multiplication the overflow check can be elided if either one +  // of the unpromoted types are less than half the size of the promoted type. +  unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType()); +  return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize || +         (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize; +} + +/// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions. +static void updateFastMathFlags(llvm::FastMathFlags &FMF, +                                FPOptions FPFeatures) { +  FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement()); +} + +/// Propagate fast-math flags from \p Op to the instruction in \p V. +static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) { +  if (auto *I = dyn_cast<llvm::Instruction>(V)) { +    llvm::FastMathFlags FMF = I->getFastMathFlags(); +    updateFastMathFlags(FMF, Op.FPFeatures); +    I->setFastMathFlags(FMF); +  } +  return V; +} + +class ScalarExprEmitter +  : public StmtVisitor<ScalarExprEmitter, Value*> { +  CodeGenFunction &CGF; +  CGBuilderTy &Builder; +  bool IgnoreResultAssign; +  llvm::LLVMContext &VMContext; +public: + +  ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false) +    : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira), +      VMContext(cgf.getLLVMContext()) { +  } + +  //===--------------------------------------------------------------------===// +  //                               Utilities +  //===--------------------------------------------------------------------===// + +  bool TestAndClearIgnoreResultAssign() { +    bool I = IgnoreResultAssign; +    IgnoreResultAssign = false; +    return I; +  } + +  llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); } +  LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); } +  LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) { +    return CGF.EmitCheckedLValue(E, TCK); +  } + +  void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks, +                      const BinOpInfo &Info); + +  Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) { +    return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal(); +  } + +  void EmitLValueAlignmentAssumption(const Expr *E, Value *V) { +    const AlignValueAttr *AVAttr = nullptr; +    if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { +      const ValueDecl *VD = DRE->getDecl(); + +      if (VD->getType()->isReferenceType()) { +        if (const auto *TTy = +            dyn_cast<TypedefType>(VD->getType().getNonReferenceType())) +          AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>(); +      } else { +        // Assumptions for function parameters are emitted at the start of the +        // function, so there is no need to repeat that here, +        // unless the alignment-assumption sanitizer is enabled, +        // then we prefer the assumption over alignment attribute +        // on IR function param. +        if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment)) +          return; + +        AVAttr = VD->getAttr<AlignValueAttr>(); +      } +    } + +    if (!AVAttr) +      if (const auto *TTy = +          dyn_cast<TypedefType>(E->getType())) +        AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>(); + +    if (!AVAttr) +      return; + +    Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment()); +    llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue); +    CGF.EmitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI); +  } + +  /// EmitLoadOfLValue - Given an expression with complex type that represents a +  /// value l-value, this method emits the address of the l-value, then loads +  /// and returns the result. +  Value *EmitLoadOfLValue(const Expr *E) { +    Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load), +                                E->getExprLoc()); + +    EmitLValueAlignmentAssumption(E, V); +    return V; +  } + +  /// EmitConversionToBool - Convert the specified expression value to a +  /// boolean (i1) truth value.  This is equivalent to "Val != 0". +  Value *EmitConversionToBool(Value *Src, QualType DstTy); + +  /// Emit a check that a conversion from a floating-point type does not +  /// overflow. +  void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType, +                                Value *Src, QualType SrcType, QualType DstType, +                                llvm::Type *DstTy, SourceLocation Loc); + +  /// Known implicit conversion check kinds. +  /// Keep in sync with the enum of the same name in ubsan_handlers.h +  enum ImplicitConversionCheckKind : unsigned char { +    ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. +    ICCK_UnsignedIntegerTruncation = 1, +    ICCK_SignedIntegerTruncation = 2, +    ICCK_IntegerSignChange = 3, +    ICCK_SignedIntegerTruncationOrSignChange = 4, +  }; + +  /// Emit a check that an [implicit] truncation of an integer  does not +  /// discard any bits. It is not UB, so we use the value after truncation. +  void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst, +                                  QualType DstType, SourceLocation Loc); + +  /// Emit a check that an [implicit] conversion of an integer does not change +  /// the sign of the value. It is not UB, so we use the value after conversion. +  /// NOTE: Src and Dst may be the exact same value! (point to the same thing) +  void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst, +                                  QualType DstType, SourceLocation Loc); + +  /// Emit a conversion from the specified type to the specified destination +  /// type, both of which are LLVM scalar types. +  struct ScalarConversionOpts { +    bool TreatBooleanAsSigned; +    bool EmitImplicitIntegerTruncationChecks; +    bool EmitImplicitIntegerSignChangeChecks; + +    ScalarConversionOpts() +        : TreatBooleanAsSigned(false), +          EmitImplicitIntegerTruncationChecks(false), +          EmitImplicitIntegerSignChangeChecks(false) {} + +    ScalarConversionOpts(clang::SanitizerSet SanOpts) +        : TreatBooleanAsSigned(false), +          EmitImplicitIntegerTruncationChecks( +              SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)), +          EmitImplicitIntegerSignChangeChecks( +              SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {} +  }; +  Value * +  EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy, +                       SourceLocation Loc, +                       ScalarConversionOpts Opts = ScalarConversionOpts()); + +  /// Convert between either a fixed point and other fixed point or fixed point +  /// and an integer. +  Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy, +                                  SourceLocation Loc); +  Value *EmitFixedPointConversion(Value *Src, FixedPointSemantics &SrcFixedSema, +                                  FixedPointSemantics &DstFixedSema, +                                  SourceLocation Loc, +                                  bool DstIsInteger = false); + +  /// Emit a conversion from the specified complex type to the specified +  /// destination type, where the destination type is an LLVM scalar type. +  Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, +                                       QualType SrcTy, QualType DstTy, +                                       SourceLocation Loc); + +  /// EmitNullValue - Emit a value that corresponds to null for the given type. +  Value *EmitNullValue(QualType Ty); + +  /// EmitFloatToBoolConversion - Perform an FP to boolean conversion. +  Value *EmitFloatToBoolConversion(Value *V) { +    // Compare against 0.0 for fp scalars. +    llvm::Value *Zero = llvm::Constant::getNullValue(V->getType()); +    return Builder.CreateFCmpUNE(V, Zero, "tobool"); +  } + +  /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion. +  Value *EmitPointerToBoolConversion(Value *V, QualType QT) { +    Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT); + +    return Builder.CreateICmpNE(V, Zero, "tobool"); +  } + +  Value *EmitIntToBoolConversion(Value *V) { +    // Because of the type rules of C, we often end up computing a +    // logical value, then zero extending it to int, then wanting it +    // as a logical value again.  Optimize this common case. +    if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) { +      if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) { +        Value *Result = ZI->getOperand(0); +        // If there aren't any more uses, zap the instruction to save space. +        // Note that there can be more uses, for example if this +        // is the result of an assignment. +        if (ZI->use_empty()) +          ZI->eraseFromParent(); +        return Result; +      } +    } + +    return Builder.CreateIsNotNull(V, "tobool"); +  } + +  //===--------------------------------------------------------------------===// +  //                            Visitor Methods +  //===--------------------------------------------------------------------===// + +  Value *Visit(Expr *E) { +    ApplyDebugLocation DL(CGF, E); +    return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E); +  } + +  Value *VisitStmt(Stmt *S) { +    S->dump(CGF.getContext().getSourceManager()); +    llvm_unreachable("Stmt can't have complex result type!"); +  } +  Value *VisitExpr(Expr *S); + +  Value *VisitConstantExpr(ConstantExpr *E) { +    return Visit(E->getSubExpr()); +  } +  Value *VisitParenExpr(ParenExpr *PE) { +    return Visit(PE->getSubExpr()); +  } +  Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) { +    return Visit(E->getReplacement()); +  } +  Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) { +    return Visit(GE->getResultExpr()); +  } +  Value *VisitCoawaitExpr(CoawaitExpr *S) { +    return CGF.EmitCoawaitExpr(*S).getScalarVal(); +  } +  Value *VisitCoyieldExpr(CoyieldExpr *S) { +    return CGF.EmitCoyieldExpr(*S).getScalarVal(); +  } +  Value *VisitUnaryCoawait(const UnaryOperator *E) { +    return Visit(E->getSubExpr()); +  } + +  // Leaves. +  Value *VisitIntegerLiteral(const IntegerLiteral *E) { +    return Builder.getInt(E->getValue()); +  } +  Value *VisitFixedPointLiteral(const FixedPointLiteral *E) { +    return Builder.getInt(E->getValue()); +  } +  Value *VisitFloatingLiteral(const FloatingLiteral *E) { +    return llvm::ConstantFP::get(VMContext, E->getValue()); +  } +  Value *VisitCharacterLiteral(const CharacterLiteral *E) { +    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); +  } +  Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) { +    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); +  } +  Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { +    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); +  } +  Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) { +    return EmitNullValue(E->getType()); +  } +  Value *VisitGNUNullExpr(const GNUNullExpr *E) { +    return EmitNullValue(E->getType()); +  } +  Value *VisitOffsetOfExpr(OffsetOfExpr *E); +  Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); +  Value *VisitAddrLabelExpr(const AddrLabelExpr *E) { +    llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel()); +    return Builder.CreateBitCast(V, ConvertType(E->getType())); +  } + +  Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) { +    return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength()); +  } + +  Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) { +    return CGF.EmitPseudoObjectRValue(E).getScalarVal(); +  } + +  Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) { +    if (E->isGLValue()) +      return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), +                              E->getExprLoc()); + +    // Otherwise, assume the mapping is the scalar directly. +    return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal(); +  } + +  // l-values. +  Value *VisitDeclRefExpr(DeclRefExpr *E) { +    if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) +      return CGF.emitScalarConstant(Constant, E); +    return EmitLoadOfLValue(E); +  } + +  Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) { +    return CGF.EmitObjCSelectorExpr(E); +  } +  Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) { +    return CGF.EmitObjCProtocolExpr(E); +  } +  Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { +    return EmitLoadOfLValue(E); +  } +  Value *VisitObjCMessageExpr(ObjCMessageExpr *E) { +    if (E->getMethodDecl() && +        E->getMethodDecl()->getReturnType()->isReferenceType()) +      return EmitLoadOfLValue(E); +    return CGF.EmitObjCMessageExpr(E).getScalarVal(); +  } + +  Value *VisitObjCIsaExpr(ObjCIsaExpr *E) { +    LValue LV = CGF.EmitObjCIsaExpr(E); +    Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal(); +    return V; +  } + +  Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) { +    VersionTuple Version = E->getVersion(); + +    // If we're checking for a platform older than our minimum deployment +    // target, we can fold the check away. +    if (Version <= CGF.CGM.getTarget().getPlatformMinVersion()) +      return llvm::ConstantInt::get(Builder.getInt1Ty(), 1); + +    Optional<unsigned> Min = Version.getMinor(), SMin = Version.getSubminor(); +    llvm::Value *Args[] = { +        llvm::ConstantInt::get(CGF.CGM.Int32Ty, Version.getMajor()), +        llvm::ConstantInt::get(CGF.CGM.Int32Ty, Min ? *Min : 0), +        llvm::ConstantInt::get(CGF.CGM.Int32Ty, SMin ? *SMin : 0), +    }; + +    return CGF.EmitBuiltinAvailable(Args); +  } + +  Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E); +  Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E); +  Value *VisitConvertVectorExpr(ConvertVectorExpr *E); +  Value *VisitMemberExpr(MemberExpr *E); +  Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); } +  Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { +    return EmitLoadOfLValue(E); +  } + +  Value *VisitInitListExpr(InitListExpr *E); + +  Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) { +    assert(CGF.getArrayInitIndex() && +           "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?"); +    return CGF.getArrayInitIndex(); +  } + +  Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { +    return EmitNullValue(E->getType()); +  } +  Value *VisitExplicitCastExpr(ExplicitCastExpr *E) { +    CGF.CGM.EmitExplicitCastExprType(E, &CGF); +    return VisitCastExpr(E); +  } +  Value *VisitCastExpr(CastExpr *E); + +  Value *VisitCallExpr(const CallExpr *E) { +    if (E->getCallReturnType(CGF.getContext())->isReferenceType()) +      return EmitLoadOfLValue(E); + +    Value *V = CGF.EmitCallExpr(E).getScalarVal(); + +    EmitLValueAlignmentAssumption(E, V); +    return V; +  } + +  Value *VisitStmtExpr(const StmtExpr *E); + +  // Unary Operators. +  Value *VisitUnaryPostDec(const UnaryOperator *E) { +    LValue LV = EmitLValue(E->getSubExpr()); +    return EmitScalarPrePostIncDec(E, LV, false, false); +  } +  Value *VisitUnaryPostInc(const UnaryOperator *E) { +    LValue LV = EmitLValue(E->getSubExpr()); +    return EmitScalarPrePostIncDec(E, LV, true, false); +  } +  Value *VisitUnaryPreDec(const UnaryOperator *E) { +    LValue LV = EmitLValue(E->getSubExpr()); +    return EmitScalarPrePostIncDec(E, LV, false, true); +  } +  Value *VisitUnaryPreInc(const UnaryOperator *E) { +    LValue LV = EmitLValue(E->getSubExpr()); +    return EmitScalarPrePostIncDec(E, LV, true, true); +  } + +  llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E, +                                                  llvm::Value *InVal, +                                                  bool IsInc); + +  llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, +                                       bool isInc, bool isPre); + + +  Value *VisitUnaryAddrOf(const UnaryOperator *E) { +    if (isa<MemberPointerType>(E->getType())) // never sugared +      return CGF.CGM.getMemberPointerConstant(E); + +    return EmitLValue(E->getSubExpr()).getPointer(); +  } +  Value *VisitUnaryDeref(const UnaryOperator *E) { +    if (E->getType()->isVoidType()) +      return Visit(E->getSubExpr()); // the actual value should be unused +    return EmitLoadOfLValue(E); +  } +  Value *VisitUnaryPlus(const UnaryOperator *E) { +    // This differs from gcc, though, most likely due to a bug in gcc. +    TestAndClearIgnoreResultAssign(); +    return Visit(E->getSubExpr()); +  } +  Value *VisitUnaryMinus    (const UnaryOperator *E); +  Value *VisitUnaryNot      (const UnaryOperator *E); +  Value *VisitUnaryLNot     (const UnaryOperator *E); +  Value *VisitUnaryReal     (const UnaryOperator *E); +  Value *VisitUnaryImag     (const UnaryOperator *E); +  Value *VisitUnaryExtension(const UnaryOperator *E) { +    return Visit(E->getSubExpr()); +  } + +  // C++ +  Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) { +    return EmitLoadOfLValue(E); +  } +  Value *VisitSourceLocExpr(SourceLocExpr *SLE) { +    auto &Ctx = CGF.getContext(); +    APValue Evaluated = +        SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr()); +    return ConstantEmitter(CGF.CGM, &CGF) +        .emitAbstract(SLE->getLocation(), Evaluated, SLE->getType()); +  } + +  Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { +    CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); +    return Visit(DAE->getExpr()); +  } +  Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { +    CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE); +    return Visit(DIE->getExpr()); +  } +  Value *VisitCXXThisExpr(CXXThisExpr *TE) { +    return CGF.LoadCXXThis(); +  } + +  Value *VisitExprWithCleanups(ExprWithCleanups *E); +  Value *VisitCXXNewExpr(const CXXNewExpr *E) { +    return CGF.EmitCXXNewExpr(E); +  } +  Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) { +    CGF.EmitCXXDeleteExpr(E); +    return nullptr; +  } + +  Value *VisitTypeTraitExpr(const TypeTraitExpr *E) { +    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); +  } + +  Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) { +    return Builder.getInt1(E->isSatisfied()); +  } + +  Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) { +    return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue()); +  } + +  Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) { +    return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue()); +  } + +  Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) { +    // C++ [expr.pseudo]p1: +    //   The result shall only be used as the operand for the function call +    //   operator (), and the result of such a call has type void. The only +    //   effect is the evaluation of the postfix-expression before the dot or +    //   arrow. +    CGF.EmitScalarExpr(E->getBase()); +    return nullptr; +  } + +  Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) { +    return EmitNullValue(E->getType()); +  } + +  Value *VisitCXXThrowExpr(const CXXThrowExpr *E) { +    CGF.EmitCXXThrowExpr(E); +    return nullptr; +  } + +  Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { +    return Builder.getInt1(E->getValue()); +  } + +  // Binary Operators. +  Value *EmitMul(const BinOpInfo &Ops) { +    if (Ops.Ty->isSignedIntegerOrEnumerationType()) { +      switch (CGF.getLangOpts().getSignedOverflowBehavior()) { +      case LangOptions::SOB_Defined: +        return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); +      case LangOptions::SOB_Undefined: +        if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) +          return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); +        LLVM_FALLTHROUGH; +      case LangOptions::SOB_Trapping: +        if (CanElideOverflowCheck(CGF.getContext(), Ops)) +          return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); +        return EmitOverflowCheckedBinOp(Ops); +      } +    } + +    if (Ops.Ty->isUnsignedIntegerType() && +        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && +        !CanElideOverflowCheck(CGF.getContext(), Ops)) +      return EmitOverflowCheckedBinOp(Ops); + +    if (Ops.LHS->getType()->isFPOrFPVectorTy()) { +      Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); +      return propagateFMFlags(V, Ops); +    } +    return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); +  } +  /// Create a binary op that checks for overflow. +  /// Currently only supports +, - and *. +  Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops); + +  // Check for undefined division and modulus behaviors. +  void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops, +                                                  llvm::Value *Zero,bool isDiv); +  // Common helper for getting how wide LHS of shift is. +  static Value *GetWidthMinusOneValue(Value* LHS,Value* RHS); +  Value *EmitDiv(const BinOpInfo &Ops); +  Value *EmitRem(const BinOpInfo &Ops); +  Value *EmitAdd(const BinOpInfo &Ops); +  Value *EmitSub(const BinOpInfo &Ops); +  Value *EmitShl(const BinOpInfo &Ops); +  Value *EmitShr(const BinOpInfo &Ops); +  Value *EmitAnd(const BinOpInfo &Ops) { +    return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and"); +  } +  Value *EmitXor(const BinOpInfo &Ops) { +    return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor"); +  } +  Value *EmitOr (const BinOpInfo &Ops) { +    return Builder.CreateOr(Ops.LHS, Ops.RHS, "or"); +  } + +  // Helper functions for fixed point binary operations. +  Value *EmitFixedPointBinOp(const BinOpInfo &Ops); + +  BinOpInfo EmitBinOps(const BinaryOperator *E); +  LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, +                            Value *(ScalarExprEmitter::*F)(const BinOpInfo &), +                                  Value *&Result); + +  Value *EmitCompoundAssign(const CompoundAssignOperator *E, +                            Value *(ScalarExprEmitter::*F)(const BinOpInfo &)); + +  // Binary operators and binary compound assignment operators. +#define HANDLEBINOP(OP) \ +  Value *VisitBin ## OP(const BinaryOperator *E) {                         \ +    return Emit ## OP(EmitBinOps(E));                                      \ +  }                                                                        \ +  Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) {       \ +    return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP);          \ +  } +  HANDLEBINOP(Mul) +  HANDLEBINOP(Div) +  HANDLEBINOP(Rem) +  HANDLEBINOP(Add) +  HANDLEBINOP(Sub) +  HANDLEBINOP(Shl) +  HANDLEBINOP(Shr) +  HANDLEBINOP(And) +  HANDLEBINOP(Xor) +  HANDLEBINOP(Or) +#undef HANDLEBINOP + +  // Comparisons. +  Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc, +                     llvm::CmpInst::Predicate SICmpOpc, +                     llvm::CmpInst::Predicate FCmpOpc); +#define VISITCOMP(CODE, UI, SI, FP) \ +    Value *VisitBin##CODE(const BinaryOperator *E) { \ +      return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \ +                         llvm::FCmpInst::FP); } +  VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT) +  VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT) +  VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE) +  VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE) +  VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ) +  VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE) +#undef VISITCOMP + +  Value *VisitBinAssign     (const BinaryOperator *E); + +  Value *VisitBinLAnd       (const BinaryOperator *E); +  Value *VisitBinLOr        (const BinaryOperator *E); +  Value *VisitBinComma      (const BinaryOperator *E); + +  Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); } +  Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); } + +  Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) { +    return Visit(E->getSemanticForm()); +  } + +  // Other Operators. +  Value *VisitBlockExpr(const BlockExpr *BE); +  Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *); +  Value *VisitChooseExpr(ChooseExpr *CE); +  Value *VisitVAArgExpr(VAArgExpr *VE); +  Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) { +    return CGF.EmitObjCStringLiteral(E); +  } +  Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) { +    return CGF.EmitObjCBoxedExpr(E); +  } +  Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) { +    return CGF.EmitObjCArrayLiteral(E); +  } +  Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { +    return CGF.EmitObjCDictionaryLiteral(E); +  } +  Value *VisitAsTypeExpr(AsTypeExpr *CE); +  Value *VisitAtomicExpr(AtomicExpr *AE); +}; +}  // end anonymous namespace. + +//===----------------------------------------------------------------------===// +//                                Utilities +//===----------------------------------------------------------------------===// + +/// EmitConversionToBool - Convert the specified expression value to a +/// boolean (i1) truth value.  This is equivalent to "Val != 0". +Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) { +  assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs"); + +  if (SrcType->isRealFloatingType()) +    return EmitFloatToBoolConversion(Src); + +  if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType)) +    return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT); + +  assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) && +         "Unknown scalar type to convert"); + +  if (isa<llvm::IntegerType>(Src->getType())) +    return EmitIntToBoolConversion(Src); + +  assert(isa<llvm::PointerType>(Src->getType())); +  return EmitPointerToBoolConversion(Src, SrcType); +} + +void ScalarExprEmitter::EmitFloatConversionCheck( +    Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType, +    QualType DstType, llvm::Type *DstTy, SourceLocation Loc) { +  assert(SrcType->isFloatingType() && "not a conversion from floating point"); +  if (!isa<llvm::IntegerType>(DstTy)) +    return; + +  CodeGenFunction::SanitizerScope SanScope(&CGF); +  using llvm::APFloat; +  using llvm::APSInt; + +  llvm::Value *Check = nullptr; +  const llvm::fltSemantics &SrcSema = +    CGF.getContext().getFloatTypeSemantics(OrigSrcType); + +  // Floating-point to integer. This has undefined behavior if the source is +  // +-Inf, NaN, or doesn't fit into the destination type (after truncation +  // to an integer). +  unsigned Width = CGF.getContext().getIntWidth(DstType); +  bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType(); + +  APSInt Min = APSInt::getMinValue(Width, Unsigned); +  APFloat MinSrc(SrcSema, APFloat::uninitialized); +  if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) & +      APFloat::opOverflow) +    // Don't need an overflow check for lower bound. Just check for +    // -Inf/NaN. +    MinSrc = APFloat::getInf(SrcSema, true); +  else +    // Find the largest value which is too small to represent (before +    // truncation toward zero). +    MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative); + +  APSInt Max = APSInt::getMaxValue(Width, Unsigned); +  APFloat MaxSrc(SrcSema, APFloat::uninitialized); +  if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) & +      APFloat::opOverflow) +    // Don't need an overflow check for upper bound. Just check for +    // +Inf/NaN. +    MaxSrc = APFloat::getInf(SrcSema, false); +  else +    // Find the smallest value which is too large to represent (before +    // truncation toward zero). +    MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive); + +  // If we're converting from __half, convert the range to float to match +  // the type of src. +  if (OrigSrcType->isHalfType()) { +    const llvm::fltSemantics &Sema = +      CGF.getContext().getFloatTypeSemantics(SrcType); +    bool IsInexact; +    MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact); +    MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact); +  } + +  llvm::Value *GE = +    Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc)); +  llvm::Value *LE = +    Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc)); +  Check = Builder.CreateAnd(GE, LE); + +  llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc), +                                  CGF.EmitCheckTypeDescriptor(OrigSrcType), +                                  CGF.EmitCheckTypeDescriptor(DstType)}; +  CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow), +                SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc); +} + +// Should be called within CodeGenFunction::SanitizerScope RAII scope. +// Returns 'i1 false' when the truncation Src -> Dst was lossy. +static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, +                 std::pair<llvm::Value *, SanitizerMask>> +EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, +                                 QualType DstType, CGBuilderTy &Builder) { +  llvm::Type *SrcTy = Src->getType(); +  llvm::Type *DstTy = Dst->getType(); +  (void)DstTy; // Only used in assert() + +  // This should be truncation of integral types. +  assert(Src != Dst); +  assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits()); +  assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && +         "non-integer llvm type"); + +  bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); +  bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); + +  // If both (src and dst) types are unsigned, then it's an unsigned truncation. +  // Else, it is a signed truncation. +  ScalarExprEmitter::ImplicitConversionCheckKind Kind; +  SanitizerMask Mask; +  if (!SrcSigned && !DstSigned) { +    Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation; +    Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation; +  } else { +    Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation; +    Mask = SanitizerKind::ImplicitSignedIntegerTruncation; +  } + +  llvm::Value *Check = nullptr; +  // 1. Extend the truncated value back to the same width as the Src. +  Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext"); +  // 2. Equality-compare with the original source value +  Check = Builder.CreateICmpEQ(Check, Src, "truncheck"); +  // If the comparison result is 'i1 false', then the truncation was lossy. +  return std::make_pair(Kind, std::make_pair(Check, Mask)); +} + +void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, +                                                   Value *Dst, QualType DstType, +                                                   SourceLocation Loc) { +  if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)) +    return; + +  // We only care about int->int conversions here. +  // We ignore conversions to/from pointer and/or bool. +  if (!(SrcType->isIntegerType() && DstType->isIntegerType())) +    return; + +  unsigned SrcBits = Src->getType()->getScalarSizeInBits(); +  unsigned DstBits = Dst->getType()->getScalarSizeInBits(); +  // This must be truncation. Else we do not care. +  if (SrcBits <= DstBits) +    return; + +  assert(!DstType->isBooleanType() && "we should not get here with booleans."); + +  // If the integer sign change sanitizer is enabled, +  // and we are truncating from larger unsigned type to smaller signed type, +  // let that next sanitizer deal with it. +  bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); +  bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); +  if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) && +      (!SrcSigned && DstSigned)) +    return; + +  CodeGenFunction::SanitizerScope SanScope(&CGF); + +  std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, +            std::pair<llvm::Value *, SanitizerMask>> +      Check = +          EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); +  // If the comparison result is 'i1 false', then the truncation was lossy. + +  // Do we care about this type of truncation? +  if (!CGF.SanOpts.has(Check.second.second)) +    return; + +  llvm::Constant *StaticArgs[] = { +      CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), +      CGF.EmitCheckTypeDescriptor(DstType), +      llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)}; +  CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs, +                {Src, Dst}); +} + +// Should be called within CodeGenFunction::SanitizerScope RAII scope. +// Returns 'i1 false' when the conversion Src -> Dst changed the sign. +static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, +                 std::pair<llvm::Value *, SanitizerMask>> +EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, +                                 QualType DstType, CGBuilderTy &Builder) { +  llvm::Type *SrcTy = Src->getType(); +  llvm::Type *DstTy = Dst->getType(); + +  assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && +         "non-integer llvm type"); + +  bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); +  bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); +  (void)SrcSigned; // Only used in assert() +  (void)DstSigned; // Only used in assert() +  unsigned SrcBits = SrcTy->getScalarSizeInBits(); +  unsigned DstBits = DstTy->getScalarSizeInBits(); +  (void)SrcBits; // Only used in assert() +  (void)DstBits; // Only used in assert() + +  assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) && +         "either the widths should be different, or the signednesses."); + +  // NOTE: zero value is considered to be non-negative. +  auto EmitIsNegativeTest = [&Builder](Value *V, QualType VType, +                                       const char *Name) -> Value * { +    // Is this value a signed type? +    bool VSigned = VType->isSignedIntegerOrEnumerationType(); +    llvm::Type *VTy = V->getType(); +    if (!VSigned) { +      // If the value is unsigned, then it is never negative. +      // FIXME: can we encounter non-scalar VTy here? +      return llvm::ConstantInt::getFalse(VTy->getContext()); +    } +    // Get the zero of the same type with which we will be comparing. +    llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0); +    // %V.isnegative = icmp slt %V, 0 +    // I.e is %V *strictly* less than zero, does it have negative value? +    return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero, +                              llvm::Twine(Name) + "." + V->getName() + +                                  ".negativitycheck"); +  }; + +  // 1. Was the old Value negative? +  llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType, "src"); +  // 2. Is the new Value negative? +  llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst"); +  // 3. Now, was the 'negativity status' preserved during the conversion? +  //    NOTE: conversion from negative to zero is considered to change the sign. +  //    (We want to get 'false' when the conversion changed the sign) +  //    So we should just equality-compare the negativity statuses. +  llvm::Value *Check = nullptr; +  Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck"); +  // If the comparison result is 'false', then the conversion changed the sign. +  return std::make_pair( +      ScalarExprEmitter::ICCK_IntegerSignChange, +      std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange)); +} + +void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, +                                                   Value *Dst, QualType DstType, +                                                   SourceLocation Loc) { +  if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) +    return; + +  llvm::Type *SrcTy = Src->getType(); +  llvm::Type *DstTy = Dst->getType(); + +  // We only care about int->int conversions here. +  // We ignore conversions to/from pointer and/or bool. +  if (!(SrcType->isIntegerType() && DstType->isIntegerType())) +    return; + +  bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); +  bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); +  unsigned SrcBits = SrcTy->getScalarSizeInBits(); +  unsigned DstBits = DstTy->getScalarSizeInBits(); + +  // Now, we do not need to emit the check in *all* of the cases. +  // We can avoid emitting it in some obvious cases where it would have been +  // dropped by the opt passes (instcombine) always anyways. +  // If it's a cast between effectively the same type, no check. +  // NOTE: this is *not* equivalent to checking the canonical types. +  if (SrcSigned == DstSigned && SrcBits == DstBits) +    return; +  // At least one of the values needs to have signed type. +  // If both are unsigned, then obviously, neither of them can be negative. +  if (!SrcSigned && !DstSigned) +    return; +  // If the conversion is to *larger* *signed* type, then no check is needed. +  // Because either sign-extension happens (so the sign will remain), +  // or zero-extension will happen (the sign bit will be zero.) +  if ((DstBits > SrcBits) && DstSigned) +    return; +  if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) && +      (SrcBits > DstBits) && SrcSigned) { +    // If the signed integer truncation sanitizer is enabled, +    // and this is a truncation from signed type, then no check is needed. +    // Because here sign change check is interchangeable with truncation check. +    return; +  } +  // That's it. We can't rule out any more cases with the data we have. + +  CodeGenFunction::SanitizerScope SanScope(&CGF); + +  std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, +            std::pair<llvm::Value *, SanitizerMask>> +      Check; + +  // Each of these checks needs to return 'false' when an issue was detected. +  ImplicitConversionCheckKind CheckKind; +  llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; +  // So we can 'and' all the checks together, and still get 'false', +  // if at least one of the checks detected an issue. + +  Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder); +  CheckKind = Check.first; +  Checks.emplace_back(Check.second); + +  if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) && +      (SrcBits > DstBits) && !SrcSigned && DstSigned) { +    // If the signed integer truncation sanitizer was enabled, +    // and we are truncating from larger unsigned type to smaller signed type, +    // let's handle the case we skipped in that check. +    Check = +        EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); +    CheckKind = ICCK_SignedIntegerTruncationOrSignChange; +    Checks.emplace_back(Check.second); +    // If the comparison result is 'i1 false', then the truncation was lossy. +  } + +  llvm::Constant *StaticArgs[] = { +      CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), +      CGF.EmitCheckTypeDescriptor(DstType), +      llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind)}; +  // EmitCheck() will 'and' all the checks together. +  CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs, +                {Src, Dst}); +} + +/// Emit a conversion from the specified type to the specified destination type, +/// both of which are LLVM scalar types. +Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, +                                               QualType DstType, +                                               SourceLocation Loc, +                                               ScalarConversionOpts Opts) { +  // All conversions involving fixed point types should be handled by the +  // EmitFixedPoint family functions. This is done to prevent bloating up this +  // function more, and although fixed point numbers are represented by +  // integers, we do not want to follow any logic that assumes they should be +  // treated as integers. +  // TODO(leonardchan): When necessary, add another if statement checking for +  // conversions to fixed point types from other types. +  if (SrcType->isFixedPointType()) { +    if (DstType->isBooleanType()) +      // It is important that we check this before checking if the dest type is +      // an integer because booleans are technically integer types. +      // We do not need to check the padding bit on unsigned types if unsigned +      // padding is enabled because overflow into this bit is undefined +      // behavior. +      return Builder.CreateIsNotNull(Src, "tobool"); +    if (DstType->isFixedPointType() || DstType->isIntegerType()) +      return EmitFixedPointConversion(Src, SrcType, DstType, Loc); + +    llvm_unreachable( +        "Unhandled scalar conversion from a fixed point type to another type."); +  } else if (DstType->isFixedPointType()) { +    if (SrcType->isIntegerType()) +      // This also includes converting booleans and enums to fixed point types. +      return EmitFixedPointConversion(Src, SrcType, DstType, Loc); + +    llvm_unreachable( +        "Unhandled scalar conversion to a fixed point type from another type."); +  } + +  QualType NoncanonicalSrcType = SrcType; +  QualType NoncanonicalDstType = DstType; + +  SrcType = CGF.getContext().getCanonicalType(SrcType); +  DstType = CGF.getContext().getCanonicalType(DstType); +  if (SrcType == DstType) return Src; + +  if (DstType->isVoidType()) return nullptr; + +  llvm::Value *OrigSrc = Src; +  QualType OrigSrcType = SrcType; +  llvm::Type *SrcTy = Src->getType(); + +  // Handle conversions to bool first, they are special: comparisons against 0. +  if (DstType->isBooleanType()) +    return EmitConversionToBool(Src, SrcType); + +  llvm::Type *DstTy = ConvertType(DstType); + +  // Cast from half through float if half isn't a native type. +  if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { +    // Cast to FP using the intrinsic if the half type itself isn't supported. +    if (DstTy->isFloatingPointTy()) { +      if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) +        return Builder.CreateCall( +            CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy), +            Src); +    } else { +      // Cast to other types through float, using either the intrinsic or FPExt, +      // depending on whether the half type itself is supported +      // (as opposed to operations on half, available with NativeHalfType). +      if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { +        Src = Builder.CreateCall( +            CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, +                                 CGF.CGM.FloatTy), +            Src); +      } else { +        Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv"); +      } +      SrcType = CGF.getContext().FloatTy; +      SrcTy = CGF.FloatTy; +    } +  } + +  // Ignore conversions like int -> uint. +  if (SrcTy == DstTy) { +    if (Opts.EmitImplicitIntegerSignChangeChecks) +      EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src, +                                 NoncanonicalDstType, Loc); + +    return Src; +  } + +  // Handle pointer conversions next: pointers can only be converted to/from +  // other pointers and integers. Check for pointer types in terms of LLVM, as +  // some native types (like Obj-C id) may map to a pointer type. +  if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) { +    // The source value may be an integer, or a pointer. +    if (isa<llvm::PointerType>(SrcTy)) +      return Builder.CreateBitCast(Src, DstTy, "conv"); + +    assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?"); +    // First, convert to the correct width so that we control the kind of +    // extension. +    llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT); +    bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); +    llvm::Value* IntResult = +        Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); +    // Then, cast to pointer. +    return Builder.CreateIntToPtr(IntResult, DstTy, "conv"); +  } + +  if (isa<llvm::PointerType>(SrcTy)) { +    // Must be an ptr to int cast. +    assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?"); +    return Builder.CreatePtrToInt(Src, DstTy, "conv"); +  } + +  // A scalar can be splatted to an extended vector of the same element type +  if (DstType->isExtVectorType() && !SrcType->isVectorType()) { +    // Sema should add casts to make sure that the source expression's type is +    // the same as the vector's element type (sans qualifiers) +    assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() == +               SrcType.getTypePtr() && +           "Splatted expr doesn't match with vector element type?"); + +    // Splat the element across to all elements +    unsigned NumElements = DstTy->getVectorNumElements(); +    return Builder.CreateVectorSplat(NumElements, Src, "splat"); +  } + +  if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) { +    // Allow bitcast from vector to integer/fp of the same size. +    unsigned SrcSize = SrcTy->getPrimitiveSizeInBits(); +    unsigned DstSize = DstTy->getPrimitiveSizeInBits(); +    if (SrcSize == DstSize) +      return Builder.CreateBitCast(Src, DstTy, "conv"); + +    // Conversions between vectors of different sizes are not allowed except +    // when vectors of half are involved. Operations on storage-only half +    // vectors require promoting half vector operands to float vectors and +    // truncating the result, which is either an int or float vector, to a +    // short or half vector. + +    // Source and destination are both expected to be vectors. +    llvm::Type *SrcElementTy = SrcTy->getVectorElementType(); +    llvm::Type *DstElementTy = DstTy->getVectorElementType(); +    (void)DstElementTy; + +    assert(((SrcElementTy->isIntegerTy() && +             DstElementTy->isIntegerTy()) || +            (SrcElementTy->isFloatingPointTy() && +             DstElementTy->isFloatingPointTy())) && +           "unexpected conversion between a floating-point vector and an " +           "integer vector"); + +    // Truncate an i32 vector to an i16 vector. +    if (SrcElementTy->isIntegerTy()) +      return Builder.CreateIntCast(Src, DstTy, false, "conv"); + +    // Truncate a float vector to a half vector. +    if (SrcSize > DstSize) +      return Builder.CreateFPTrunc(Src, DstTy, "conv"); + +    // Promote a half vector to a float vector. +    return Builder.CreateFPExt(Src, DstTy, "conv"); +  } + +  // Finally, we have the arithmetic types: real int/float. +  Value *Res = nullptr; +  llvm::Type *ResTy = DstTy; + +  // An overflowing conversion has undefined behavior if either the source type +  // or the destination type is a floating-point type. However, we consider the +  // range of representable values for all floating-point types to be +  // [-inf,+inf], so no overflow can ever happen when the destination type is a +  // floating-point type. +  if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) && +      OrigSrcType->isFloatingType()) +    EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy, +                             Loc); + +  // Cast to half through float if half isn't a native type. +  if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { +    // Make sure we cast in a single step if from another FP type. +    if (SrcTy->isFloatingPointTy()) { +      // Use the intrinsic if the half type itself isn't supported +      // (as opposed to operations on half, available with NativeHalfType). +      if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) +        return Builder.CreateCall( +            CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src); +      // If the half type is supported, just use an fptrunc. +      return Builder.CreateFPTrunc(Src, DstTy); +    } +    DstTy = CGF.FloatTy; +  } + +  if (isa<llvm::IntegerType>(SrcTy)) { +    bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); +    if (SrcType->isBooleanType() && Opts.TreatBooleanAsSigned) { +      InputSigned = true; +    } +    if (isa<llvm::IntegerType>(DstTy)) +      Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); +    else if (InputSigned) +      Res = Builder.CreateSIToFP(Src, DstTy, "conv"); +    else +      Res = Builder.CreateUIToFP(Src, DstTy, "conv"); +  } else if (isa<llvm::IntegerType>(DstTy)) { +    assert(SrcTy->isFloatingPointTy() && "Unknown real conversion"); +    if (DstType->isSignedIntegerOrEnumerationType()) +      Res = Builder.CreateFPToSI(Src, DstTy, "conv"); +    else +      Res = Builder.CreateFPToUI(Src, DstTy, "conv"); +  } else { +    assert(SrcTy->isFloatingPointTy() && DstTy->isFloatingPointTy() && +           "Unknown real conversion"); +    if (DstTy->getTypeID() < SrcTy->getTypeID()) +      Res = Builder.CreateFPTrunc(Src, DstTy, "conv"); +    else +      Res = Builder.CreateFPExt(Src, DstTy, "conv"); +  } + +  if (DstTy != ResTy) { +    if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { +      assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion"); +      Res = Builder.CreateCall( +        CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy), +        Res); +    } else { +      Res = Builder.CreateFPTrunc(Res, ResTy, "conv"); +    } +  } + +  if (Opts.EmitImplicitIntegerTruncationChecks) +    EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res, +                               NoncanonicalDstType, Loc); + +  if (Opts.EmitImplicitIntegerSignChangeChecks) +    EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res, +                               NoncanonicalDstType, Loc); + +  return Res; +} + +Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy, +                                                   QualType DstTy, +                                                   SourceLocation Loc) { +  FixedPointSemantics SrcFPSema = +      CGF.getContext().getFixedPointSemantics(SrcTy); +  FixedPointSemantics DstFPSema = +      CGF.getContext().getFixedPointSemantics(DstTy); +  return EmitFixedPointConversion(Src, SrcFPSema, DstFPSema, Loc, +                                  DstTy->isIntegerType()); +} + +Value *ScalarExprEmitter::EmitFixedPointConversion( +    Value *Src, FixedPointSemantics &SrcFPSema, FixedPointSemantics &DstFPSema, +    SourceLocation Loc, bool DstIsInteger) { +  using llvm::APInt; +  using llvm::ConstantInt; +  using llvm::Value; + +  unsigned SrcWidth = SrcFPSema.getWidth(); +  unsigned DstWidth = DstFPSema.getWidth(); +  unsigned SrcScale = SrcFPSema.getScale(); +  unsigned DstScale = DstFPSema.getScale(); +  bool SrcIsSigned = SrcFPSema.isSigned(); +  bool DstIsSigned = DstFPSema.isSigned(); + +  llvm::Type *DstIntTy = Builder.getIntNTy(DstWidth); + +  Value *Result = Src; +  unsigned ResultWidth = SrcWidth; + +  // Downscale. +  if (DstScale < SrcScale) { +    // When converting to integers, we round towards zero. For negative numbers, +    // right shifting rounds towards negative infinity. In this case, we can +    // just round up before shifting. +    if (DstIsInteger && SrcIsSigned) { +      Value *Zero = llvm::Constant::getNullValue(Result->getType()); +      Value *IsNegative = Builder.CreateICmpSLT(Result, Zero); +      Value *LowBits = ConstantInt::get( +          CGF.getLLVMContext(), APInt::getLowBitsSet(ResultWidth, SrcScale)); +      Value *Rounded = Builder.CreateAdd(Result, LowBits); +      Result = Builder.CreateSelect(IsNegative, Rounded, Result); +    } + +    Result = SrcIsSigned +                 ? Builder.CreateAShr(Result, SrcScale - DstScale, "downscale") +                 : Builder.CreateLShr(Result, SrcScale - DstScale, "downscale"); +  } + +  if (!DstFPSema.isSaturated()) { +    // Resize. +    Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize"); + +    // Upscale. +    if (DstScale > SrcScale) +      Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale"); +  } else { +    // Adjust the number of fractional bits. +    if (DstScale > SrcScale) { +      // Compare to DstWidth to prevent resizing twice. +      ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth); +      llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth); +      Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize"); +      Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale"); +    } + +    // Handle saturation. +    bool LessIntBits = DstFPSema.getIntegralBits() < SrcFPSema.getIntegralBits(); +    if (LessIntBits) { +      Value *Max = ConstantInt::get( +          CGF.getLLVMContext(), +          APFixedPoint::getMax(DstFPSema).getValue().extOrTrunc(ResultWidth)); +      Value *TooHigh = SrcIsSigned ? Builder.CreateICmpSGT(Result, Max) +                                   : Builder.CreateICmpUGT(Result, Max); +      Result = Builder.CreateSelect(TooHigh, Max, Result, "satmax"); +    } +    // Cannot overflow min to dest type if src is unsigned since all fixed +    // point types can cover the unsigned min of 0. +    if (SrcIsSigned && (LessIntBits || !DstIsSigned)) { +      Value *Min = ConstantInt::get( +          CGF.getLLVMContext(), +          APFixedPoint::getMin(DstFPSema).getValue().extOrTrunc(ResultWidth)); +      Value *TooLow = Builder.CreateICmpSLT(Result, Min); +      Result = Builder.CreateSelect(TooLow, Min, Result, "satmin"); +    } + +    // Resize the integer part to get the final destination size. +    if (ResultWidth != DstWidth) +      Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize"); +  } +  return Result; +} + +/// Emit a conversion from the specified complex type to the specified +/// destination type, where the destination type is an LLVM scalar type. +Value *ScalarExprEmitter::EmitComplexToScalarConversion( +    CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy, +    SourceLocation Loc) { +  // Get the source element type. +  SrcTy = SrcTy->castAs<ComplexType>()->getElementType(); + +  // Handle conversions to bool first, they are special: comparisons against 0. +  if (DstTy->isBooleanType()) { +    //  Complex != 0  -> (Real != 0) | (Imag != 0) +    Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc); +    Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc); +    return Builder.CreateOr(Src.first, Src.second, "tobool"); +  } + +  // C99 6.3.1.7p2: "When a value of complex type is converted to a real type, +  // the imaginary part of the complex value is discarded and the value of the +  // real part is converted according to the conversion rules for the +  // corresponding real type. +  return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc); +} + +Value *ScalarExprEmitter::EmitNullValue(QualType Ty) { +  return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty); +} + +/// Emit a sanitization check for the given "binary" operation (which +/// might actually be a unary increment which has been lowered to a binary +/// operation). The check passes if all values in \p Checks (which are \c i1), +/// are \c true. +void ScalarExprEmitter::EmitBinOpCheck( +    ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) { +  assert(CGF.IsSanitizerScope); +  SanitizerHandler Check; +  SmallVector<llvm::Constant *, 4> StaticData; +  SmallVector<llvm::Value *, 2> DynamicData; + +  BinaryOperatorKind Opcode = Info.Opcode; +  if (BinaryOperator::isCompoundAssignmentOp(Opcode)) +    Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode); + +  StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc())); +  const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E); +  if (UO && UO->getOpcode() == UO_Minus) { +    Check = SanitizerHandler::NegateOverflow; +    StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType())); +    DynamicData.push_back(Info.RHS); +  } else { +    if (BinaryOperator::isShiftOp(Opcode)) { +      // Shift LHS negative or too large, or RHS out of bounds. +      Check = SanitizerHandler::ShiftOutOfBounds; +      const BinaryOperator *BO = cast<BinaryOperator>(Info.E); +      StaticData.push_back( +        CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType())); +      StaticData.push_back( +        CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType())); +    } else if (Opcode == BO_Div || Opcode == BO_Rem) { +      // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1). +      Check = SanitizerHandler::DivremOverflow; +      StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty)); +    } else { +      // Arithmetic overflow (+, -, *). +      switch (Opcode) { +      case BO_Add: Check = SanitizerHandler::AddOverflow; break; +      case BO_Sub: Check = SanitizerHandler::SubOverflow; break; +      case BO_Mul: Check = SanitizerHandler::MulOverflow; break; +      default: llvm_unreachable("unexpected opcode for bin op check"); +      } +      StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty)); +    } +    DynamicData.push_back(Info.LHS); +    DynamicData.push_back(Info.RHS); +  } + +  CGF.EmitCheck(Checks, Check, StaticData, DynamicData); +} + +//===----------------------------------------------------------------------===// +//                            Visitor Methods +//===----------------------------------------------------------------------===// + +Value *ScalarExprEmitter::VisitExpr(Expr *E) { +  CGF.ErrorUnsupported(E, "scalar expression"); +  if (E->getType()->isVoidType()) +    return nullptr; +  return llvm::UndefValue::get(CGF.ConvertType(E->getType())); +} + +Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { +  // Vector Mask Case +  if (E->getNumSubExprs() == 2) { +    Value *LHS = CGF.EmitScalarExpr(E->getExpr(0)); +    Value *RHS = CGF.EmitScalarExpr(E->getExpr(1)); +    Value *Mask; + +    llvm::VectorType *LTy = cast<llvm::VectorType>(LHS->getType()); +    unsigned LHSElts = LTy->getNumElements(); + +    Mask = RHS; + +    llvm::VectorType *MTy = cast<llvm::VectorType>(Mask->getType()); + +    // Mask off the high bits of each shuffle index. +    Value *MaskBits = +        llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1); +    Mask = Builder.CreateAnd(Mask, MaskBits, "mask"); + +    // newv = undef +    // mask = mask & maskbits +    // for each elt +    //   n = extract mask i +    //   x = extract val n +    //   newv = insert newv, x, i +    llvm::VectorType *RTy = llvm::VectorType::get(LTy->getElementType(), +                                                  MTy->getNumElements()); +    Value* NewV = llvm::UndefValue::get(RTy); +    for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) { +      Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i); +      Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx"); + +      Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt"); +      NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins"); +    } +    return NewV; +  } + +  Value* V1 = CGF.EmitScalarExpr(E->getExpr(0)); +  Value* V2 = CGF.EmitScalarExpr(E->getExpr(1)); + +  SmallVector<llvm::Constant*, 32> indices; +  for (unsigned i = 2; i < E->getNumSubExprs(); ++i) { +    llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2); +    // Check for -1 and output it as undef in the IR. +    if (Idx.isSigned() && Idx.isAllOnesValue()) +      indices.push_back(llvm::UndefValue::get(CGF.Int32Ty)); +    else +      indices.push_back(Builder.getInt32(Idx.getZExtValue())); +  } + +  Value *SV = llvm::ConstantVector::get(indices); +  return Builder.CreateShuffleVector(V1, V2, SV, "shuffle"); +} + +Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) { +  QualType SrcType = E->getSrcExpr()->getType(), +           DstType = E->getType(); + +  Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr()); + +  SrcType = CGF.getContext().getCanonicalType(SrcType); +  DstType = CGF.getContext().getCanonicalType(DstType); +  if (SrcType == DstType) return Src; + +  assert(SrcType->isVectorType() && +         "ConvertVector source type must be a vector"); +  assert(DstType->isVectorType() && +         "ConvertVector destination type must be a vector"); + +  llvm::Type *SrcTy = Src->getType(); +  llvm::Type *DstTy = ConvertType(DstType); + +  // Ignore conversions like int -> uint. +  if (SrcTy == DstTy) +    return Src; + +  QualType SrcEltType = SrcType->castAs<VectorType>()->getElementType(), +           DstEltType = DstType->castAs<VectorType>()->getElementType(); + +  assert(SrcTy->isVectorTy() && +         "ConvertVector source IR type must be a vector"); +  assert(DstTy->isVectorTy() && +         "ConvertVector destination IR type must be a vector"); + +  llvm::Type *SrcEltTy = SrcTy->getVectorElementType(), +             *DstEltTy = DstTy->getVectorElementType(); + +  if (DstEltType->isBooleanType()) { +    assert((SrcEltTy->isFloatingPointTy() || +            isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion"); + +    llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy); +    if (SrcEltTy->isFloatingPointTy()) { +      return Builder.CreateFCmpUNE(Src, Zero, "tobool"); +    } else { +      return Builder.CreateICmpNE(Src, Zero, "tobool"); +    } +  } + +  // We have the arithmetic types: real int/float. +  Value *Res = nullptr; + +  if (isa<llvm::IntegerType>(SrcEltTy)) { +    bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType(); +    if (isa<llvm::IntegerType>(DstEltTy)) +      Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv"); +    else if (InputSigned) +      Res = Builder.CreateSIToFP(Src, DstTy, "conv"); +    else +      Res = Builder.CreateUIToFP(Src, DstTy, "conv"); +  } else if (isa<llvm::IntegerType>(DstEltTy)) { +    assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion"); +    if (DstEltType->isSignedIntegerOrEnumerationType()) +      Res = Builder.CreateFPToSI(Src, DstTy, "conv"); +    else +      Res = Builder.CreateFPToUI(Src, DstTy, "conv"); +  } else { +    assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() && +           "Unknown real conversion"); +    if (DstEltTy->getTypeID() < SrcEltTy->getTypeID()) +      Res = Builder.CreateFPTrunc(Src, DstTy, "conv"); +    else +      Res = Builder.CreateFPExt(Src, DstTy, "conv"); +  } + +  return Res; +} + +Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) { +  if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) { +    CGF.EmitIgnoredExpr(E->getBase()); +    return CGF.emitScalarConstant(Constant, E); +  } else { +    Expr::EvalResult Result; +    if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) { +      llvm::APSInt Value = Result.Val.getInt(); +      CGF.EmitIgnoredExpr(E->getBase()); +      return Builder.getInt(Value); +    } +  } + +  return EmitLoadOfLValue(E); +} + +Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { +  TestAndClearIgnoreResultAssign(); + +  // Emit subscript expressions in rvalue context's.  For most cases, this just +  // loads the lvalue formed by the subscript expr.  However, we have to be +  // careful, because the base of a vector subscript is occasionally an rvalue, +  // so we can't get it as an lvalue. +  if (!E->getBase()->getType()->isVectorType()) +    return EmitLoadOfLValue(E); + +  // Handle the vector case.  The base must be a vector, the index must be an +  // integer value. +  Value *Base = Visit(E->getBase()); +  Value *Idx  = Visit(E->getIdx()); +  QualType IdxTy = E->getIdx()->getType(); + +  if (CGF.SanOpts.has(SanitizerKind::ArrayBounds)) +    CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true); + +  return Builder.CreateExtractElement(Base, Idx, "vecext"); +} + +static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, +                                  unsigned Off, llvm::Type *I32Ty) { +  int MV = SVI->getMaskValue(Idx); +  if (MV == -1) +    return llvm::UndefValue::get(I32Ty); +  return llvm::ConstantInt::get(I32Ty, Off+MV); +} + +static llvm::Constant *getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) { +  if (C->getBitWidth() != 32) { +      assert(llvm::ConstantInt::isValueValidForType(I32Ty, +                                                    C->getZExtValue()) && +             "Index operand too large for shufflevector mask!"); +      return llvm::ConstantInt::get(I32Ty, C->getZExtValue()); +  } +  return C; +} + +Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { +  bool Ignore = TestAndClearIgnoreResultAssign(); +  (void)Ignore; +  assert (Ignore == false && "init list ignored"); +  unsigned NumInitElements = E->getNumInits(); + +  if (E->hadArrayRangeDesignator()) +    CGF.ErrorUnsupported(E, "GNU array range designator extension"); + +  llvm::VectorType *VType = +    dyn_cast<llvm::VectorType>(ConvertType(E->getType())); + +  if (!VType) { +    if (NumInitElements == 0) { +      // C++11 value-initialization for the scalar. +      return EmitNullValue(E->getType()); +    } +    // We have a scalar in braces. Just use the first element. +    return Visit(E->getInit(0)); +  } + +  unsigned ResElts = VType->getNumElements(); + +  // Loop over initializers collecting the Value for each, and remembering +  // whether the source was swizzle (ExtVectorElementExpr).  This will allow +  // us to fold the shuffle for the swizzle into the shuffle for the vector +  // initializer, since LLVM optimizers generally do not want to touch +  // shuffles. +  unsigned CurIdx = 0; +  bool VIsUndefShuffle = false; +  llvm::Value *V = llvm::UndefValue::get(VType); +  for (unsigned i = 0; i != NumInitElements; ++i) { +    Expr *IE = E->getInit(i); +    Value *Init = Visit(IE); +    SmallVector<llvm::Constant*, 16> Args; + +    llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType()); + +    // Handle scalar elements.  If the scalar initializer is actually one +    // element of a different vector of the same width, use shuffle instead of +    // extract+insert. +    if (!VVT) { +      if (isa<ExtVectorElementExpr>(IE)) { +        llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init); + +        if (EI->getVectorOperandType()->getNumElements() == ResElts) { +          llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand()); +          Value *LHS = nullptr, *RHS = nullptr; +          if (CurIdx == 0) { +            // insert into undef -> shuffle (src, undef) +            // shufflemask must use an i32 +            Args.push_back(getAsInt32(C, CGF.Int32Ty)); +            Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + +            LHS = EI->getVectorOperand(); +            RHS = V; +            VIsUndefShuffle = true; +          } else if (VIsUndefShuffle) { +            // insert into undefshuffle && size match -> shuffle (v, src) +            llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V); +            for (unsigned j = 0; j != CurIdx; ++j) +              Args.push_back(getMaskElt(SVV, j, 0, CGF.Int32Ty)); +            Args.push_back(Builder.getInt32(ResElts + C->getZExtValue())); +            Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + +            LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0); +            RHS = EI->getVectorOperand(); +            VIsUndefShuffle = false; +          } +          if (!Args.empty()) { +            llvm::Constant *Mask = llvm::ConstantVector::get(Args); +            V = Builder.CreateShuffleVector(LHS, RHS, Mask); +            ++CurIdx; +            continue; +          } +        } +      } +      V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx), +                                      "vecinit"); +      VIsUndefShuffle = false; +      ++CurIdx; +      continue; +    } + +    unsigned InitElts = VVT->getNumElements(); + +    // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's +    // input is the same width as the vector being constructed, generate an +    // optimized shuffle of the swizzle input into the result. +    unsigned Offset = (CurIdx == 0) ? 0 : ResElts; +    if (isa<ExtVectorElementExpr>(IE)) { +      llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init); +      Value *SVOp = SVI->getOperand(0); +      llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType()); + +      if (OpTy->getNumElements() == ResElts) { +        for (unsigned j = 0; j != CurIdx; ++j) { +          // If the current vector initializer is a shuffle with undef, merge +          // this shuffle directly into it. +          if (VIsUndefShuffle) { +            Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0, +                                      CGF.Int32Ty)); +          } else { +            Args.push_back(Builder.getInt32(j)); +          } +        } +        for (unsigned j = 0, je = InitElts; j != je; ++j) +          Args.push_back(getMaskElt(SVI, j, Offset, CGF.Int32Ty)); +        Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); + +        if (VIsUndefShuffle) +          V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0); + +        Init = SVOp; +      } +    } + +    // Extend init to result vector length, and then shuffle its contribution +    // to the vector initializer into V. +    if (Args.empty()) { +      for (unsigned j = 0; j != InitElts; ++j) +        Args.push_back(Builder.getInt32(j)); +      Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); +      llvm::Constant *Mask = llvm::ConstantVector::get(Args); +      Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT), +                                         Mask, "vext"); + +      Args.clear(); +      for (unsigned j = 0; j != CurIdx; ++j) +        Args.push_back(Builder.getInt32(j)); +      for (unsigned j = 0; j != InitElts; ++j) +        Args.push_back(Builder.getInt32(j+Offset)); +      Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty)); +    } + +    // If V is undef, make sure it ends up on the RHS of the shuffle to aid +    // merging subsequent shuffles into this one. +    if (CurIdx == 0) +      std::swap(V, Init); +    llvm::Constant *Mask = llvm::ConstantVector::get(Args); +    V = Builder.CreateShuffleVector(V, Init, Mask, "vecinit"); +    VIsUndefShuffle = isa<llvm::UndefValue>(Init); +    CurIdx += InitElts; +  } + +  // FIXME: evaluate codegen vs. shuffling against constant null vector. +  // Emit remaining default initializers. +  llvm::Type *EltTy = VType->getElementType(); + +  // Emit remaining default initializers +  for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) { +    Value *Idx = Builder.getInt32(CurIdx); +    llvm::Value *Init = llvm::Constant::getNullValue(EltTy); +    V = Builder.CreateInsertElement(V, Init, Idx, "vecinit"); +  } +  return V; +} + +bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) { +  const Expr *E = CE->getSubExpr(); + +  if (CE->getCastKind() == CK_UncheckedDerivedToBase) +    return false; + +  if (isa<CXXThisExpr>(E->IgnoreParens())) { +    // We always assume that 'this' is never null. +    return false; +  } + +  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) { +    // And that glvalue casts are never null. +    if (ICE->getValueKind() != VK_RValue) +      return false; +  } + +  return true; +} + +// VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts +// have to handle a more broad range of conversions than explicit casts, as they +// handle things like function to ptr-to-function decay etc. +Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { +  Expr *E = CE->getSubExpr(); +  QualType DestTy = CE->getType(); +  CastKind Kind = CE->getCastKind(); + +  // These cases are generally not written to ignore the result of +  // evaluating their sub-expressions, so we clear this now. +  bool Ignored = TestAndClearIgnoreResultAssign(); + +  // Since almost all cast kinds apply to scalars, this switch doesn't have +  // a default case, so the compiler will warn on a missing case.  The cases +  // are in the same order as in the CastKind enum. +  switch (Kind) { +  case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); +  case CK_BuiltinFnToFnPtr: +    llvm_unreachable("builtin functions are handled elsewhere"); + +  case CK_LValueBitCast: +  case CK_ObjCObjectLValueCast: { +    Address Addr = EmitLValue(E).getAddress(); +    Addr = Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(DestTy)); +    LValue LV = CGF.MakeAddrLValue(Addr, DestTy); +    return EmitLoadOfLValue(LV, CE->getExprLoc()); +  } + +  case CK_LValueToRValueBitCast: { +    LValue SourceLVal = CGF.EmitLValue(E); +    Address Addr = Builder.CreateElementBitCast(SourceLVal.getAddress(), +                                                CGF.ConvertTypeForMem(DestTy)); +    LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy); +    DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); +    return EmitLoadOfLValue(DestLV, CE->getExprLoc()); +  } + +  case CK_CPointerToObjCPointerCast: +  case CK_BlockPointerToObjCPointerCast: +  case CK_AnyPointerToBlockPointerCast: +  case CK_BitCast: { +    Value *Src = Visit(const_cast<Expr*>(E)); +    llvm::Type *SrcTy = Src->getType(); +    llvm::Type *DstTy = ConvertType(DestTy); +    if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() && +        SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) { +      llvm_unreachable("wrong cast for pointers in different address spaces" +                       "(must be an address space cast)!"); +    } + +    if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) { +      if (auto PT = DestTy->getAs<PointerType>()) +        CGF.EmitVTablePtrCheckForCast(PT->getPointeeType(), Src, +                                      /*MayBeNull=*/true, +                                      CodeGenFunction::CFITCK_UnrelatedCast, +                                      CE->getBeginLoc()); +    } + +    if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) { +      const QualType SrcType = E->getType(); + +      if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) { +        // Casting to pointer that could carry dynamic information (provided by +        // invariant.group) requires launder. +        Src = Builder.CreateLaunderInvariantGroup(Src); +      } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) { +        // Casting to pointer that does not carry dynamic information (provided +        // by invariant.group) requires stripping it.  Note that we don't do it +        // if the source could not be dynamic type and destination could be +        // dynamic because dynamic information is already laundered.  It is +        // because launder(strip(src)) == launder(src), so there is no need to +        // add extra strip before launder. +        Src = Builder.CreateStripInvariantGroup(Src); +      } +    } + +    // Update heapallocsite metadata when there is an explicit cast. +    if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(Src)) +      if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE)) +          CGF.getDebugInfo()-> +              addHeapAllocSiteMetadata(CI, CE->getType(), CE->getExprLoc()); + +    return Builder.CreateBitCast(Src, DstTy); +  } +  case CK_AddressSpaceConversion: { +    Expr::EvalResult Result; +    if (E->EvaluateAsRValue(Result, CGF.getContext()) && +        Result.Val.isNullPointer()) { +      // If E has side effect, it is emitted even if its final result is a +      // null pointer. In that case, a DCE pass should be able to +      // eliminate the useless instructions emitted during translating E. +      if (Result.HasSideEffects) +        Visit(E); +      return CGF.CGM.getNullPointer(cast<llvm::PointerType>( +          ConvertType(DestTy)), DestTy); +    } +    // Since target may map different address spaces in AST to the same address +    // space, an address space conversion may end up as a bitcast. +    return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast( +        CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(), +        DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy)); +  } +  case CK_AtomicToNonAtomic: +  case CK_NonAtomicToAtomic: +  case CK_NoOp: +  case CK_UserDefinedConversion: +    return Visit(const_cast<Expr*>(E)); + +  case CK_BaseToDerived: { +    const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl(); +    assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!"); + +    Address Base = CGF.EmitPointerWithAlignment(E); +    Address Derived = +      CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl, +                                   CE->path_begin(), CE->path_end(), +                                   CGF.ShouldNullCheckClassCastValue(CE)); + +    // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is +    // performed and the object is not of the derived type. +    if (CGF.sanitizePerformTypeCheck()) +      CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(), +                        Derived.getPointer(), DestTy->getPointeeType()); + +    if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast)) +      CGF.EmitVTablePtrCheckForCast( +          DestTy->getPointeeType(), Derived.getPointer(), +          /*MayBeNull=*/true, CodeGenFunction::CFITCK_DerivedCast, +          CE->getBeginLoc()); + +    return Derived.getPointer(); +  } +  case CK_UncheckedDerivedToBase: +  case CK_DerivedToBase: { +    // The EmitPointerWithAlignment path does this fine; just discard +    // the alignment. +    return CGF.EmitPointerWithAlignment(CE).getPointer(); +  } + +  case CK_Dynamic: { +    Address V = CGF.EmitPointerWithAlignment(E); +    const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE); +    return CGF.EmitDynamicCast(V, DCE); +  } + +  case CK_ArrayToPointerDecay: +    return CGF.EmitArrayToPointerDecay(E).getPointer(); +  case CK_FunctionToPointerDecay: +    return EmitLValue(E).getPointer(); + +  case CK_NullToPointer: +    if (MustVisitNullValue(E)) +      CGF.EmitIgnoredExpr(E); + +    return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)), +                              DestTy); + +  case CK_NullToMemberPointer: { +    if (MustVisitNullValue(E)) +      CGF.EmitIgnoredExpr(E); + +    const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>(); +    return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT); +  } + +  case CK_ReinterpretMemberPointer: +  case CK_BaseToDerivedMemberPointer: +  case CK_DerivedToBaseMemberPointer: { +    Value *Src = Visit(E); + +    // Note that the AST doesn't distinguish between checked and +    // unchecked member pointer conversions, so we always have to +    // implement checked conversions here.  This is inefficient when +    // actual control flow may be required in order to perform the +    // check, which it is for data member pointers (but not member +    // function pointers on Itanium and ARM). +    return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src); +  } + +  case CK_ARCProduceObject: +    return CGF.EmitARCRetainScalarExpr(E); +  case CK_ARCConsumeObject: +    return CGF.EmitObjCConsumeObject(E->getType(), Visit(E)); +  case CK_ARCReclaimReturnedObject: +    return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored); +  case CK_ARCExtendBlockObject: +    return CGF.EmitARCExtendBlockObject(E); + +  case CK_CopyAndAutoreleaseBlockObject: +    return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType()); + +  case CK_FloatingRealToComplex: +  case CK_FloatingComplexCast: +  case CK_IntegralRealToComplex: +  case CK_IntegralComplexCast: +  case CK_IntegralComplexToFloatingComplex: +  case CK_FloatingComplexToIntegralComplex: +  case CK_ConstructorConversion: +  case CK_ToUnion: +    llvm_unreachable("scalar cast to non-scalar value"); + +  case CK_LValueToRValue: +    assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy)); +    assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!"); +    return Visit(const_cast<Expr*>(E)); + +  case CK_IntegralToPointer: { +    Value *Src = Visit(const_cast<Expr*>(E)); + +    // First, convert to the correct width so that we control the kind of +    // extension. +    auto DestLLVMTy = ConvertType(DestTy); +    llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy); +    bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType(); +    llvm::Value* IntResult = +      Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); + +    auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy); + +    if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) { +      // Going from integer to pointer that could be dynamic requires reloading +      // dynamic information from invariant.group. +      if (DestTy.mayBeDynamicClass()) +        IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr); +    } +    return IntToPtr; +  } +  case CK_PointerToIntegral: { +    assert(!DestTy->isBooleanType() && "bool should use PointerToBool"); +    auto *PtrExpr = Visit(E); + +    if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) { +      const QualType SrcType = E->getType(); + +      // Casting to integer requires stripping dynamic information as it does +      // not carries it. +      if (SrcType.mayBeDynamicClass()) +        PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr); +    } + +    return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy)); +  } +  case CK_ToVoid: { +    CGF.EmitIgnoredExpr(E); +    return nullptr; +  } +  case CK_VectorSplat: { +    llvm::Type *DstTy = ConvertType(DestTy); +    Value *Elt = Visit(const_cast<Expr*>(E)); +    // Splat the element across to all elements +    unsigned NumElements = DstTy->getVectorNumElements(); +    return Builder.CreateVectorSplat(NumElements, Elt, "splat"); +  } + +  case CK_FixedPointCast: +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc()); + +  case CK_FixedPointToBoolean: +    assert(E->getType()->isFixedPointType() && +           "Expected src type to be fixed point type"); +    assert(DestTy->isBooleanType() && "Expected dest type to be boolean type"); +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc()); + +  case CK_FixedPointToIntegral: +    assert(E->getType()->isFixedPointType() && +           "Expected src type to be fixed point type"); +    assert(DestTy->isIntegerType() && "Expected dest type to be an integer"); +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc()); + +  case CK_IntegralToFixedPoint: +    assert(E->getType()->isIntegerType() && +           "Expected src type to be an integer"); +    assert(DestTy->isFixedPointType() && +           "Expected dest type to be fixed point type"); +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc()); + +  case CK_IntegralCast: { +    ScalarConversionOpts Opts; +    if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) { +      if (!ICE->isPartOfExplicitCast()) +        Opts = ScalarConversionOpts(CGF.SanOpts); +    } +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc(), Opts); +  } +  case CK_IntegralToFloating: +  case CK_FloatingToIntegral: +  case CK_FloatingCast: +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc()); +  case CK_BooleanToSignedIntegral: { +    ScalarConversionOpts Opts; +    Opts.TreatBooleanAsSigned = true; +    return EmitScalarConversion(Visit(E), E->getType(), DestTy, +                                CE->getExprLoc(), Opts); +  } +  case CK_IntegralToBoolean: +    return EmitIntToBoolConversion(Visit(E)); +  case CK_PointerToBoolean: +    return EmitPointerToBoolConversion(Visit(E), E->getType()); +  case CK_FloatingToBoolean: +    return EmitFloatToBoolConversion(Visit(E)); +  case CK_MemberPointerToBoolean: { +    llvm::Value *MemPtr = Visit(E); +    const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); +    return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT); +  } + +  case CK_FloatingComplexToReal: +  case CK_IntegralComplexToReal: +    return CGF.EmitComplexExpr(E, false, true).first; + +  case CK_FloatingComplexToBoolean: +  case CK_IntegralComplexToBoolean: { +    CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E); + +    // TODO: kill this function off, inline appropriate case here +    return EmitComplexToScalarConversion(V, E->getType(), DestTy, +                                         CE->getExprLoc()); +  } + +  case CK_ZeroToOCLOpaqueType: { +    assert((DestTy->isEventT() || DestTy->isQueueT() || +            DestTy->isOCLIntelSubgroupAVCType()) && +           "CK_ZeroToOCLEvent cast on non-event type"); +    return llvm::Constant::getNullValue(ConvertType(DestTy)); +  } + +  case CK_IntToOCLSampler: +    return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF); + +  } // end of switch + +  llvm_unreachable("unknown scalar cast"); +} + +Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) { +  CodeGenFunction::StmtExprEvaluation eval(CGF); +  Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), +                                           !E->getType()->isVoidType()); +  if (!RetAlloca.isValid()) +    return nullptr; +  return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()), +                              E->getExprLoc()); +} + +Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { +  CGF.enterFullExpression(E); +  CodeGenFunction::RunCleanupsScope Scope(CGF); +  Value *V = Visit(E->getSubExpr()); +  // Defend against dominance problems caused by jumps out of expression +  // evaluation through the shared cleanup block. +  Scope.ForceCleanup({&V}); +  return V; +} + +//===----------------------------------------------------------------------===// +//                             Unary Operators +//===----------------------------------------------------------------------===// + +static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, +                                           llvm::Value *InVal, bool IsInc) { +  BinOpInfo BinOp; +  BinOp.LHS = InVal; +  BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false); +  BinOp.Ty = E->getType(); +  BinOp.Opcode = IsInc ? BO_Add : BO_Sub; +  // FIXME: once UnaryOperator carries FPFeatures, copy it here. +  BinOp.E = E; +  return BinOp; +} + +llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior( +    const UnaryOperator *E, llvm::Value *InVal, bool IsInc) { +  llvm::Value *Amount = +      llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true); +  StringRef Name = IsInc ? "inc" : "dec"; +  switch (CGF.getLangOpts().getSignedOverflowBehavior()) { +  case LangOptions::SOB_Defined: +    return Builder.CreateAdd(InVal, Amount, Name); +  case LangOptions::SOB_Undefined: +    if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) +      return Builder.CreateNSWAdd(InVal, Amount, Name); +    LLVM_FALLTHROUGH; +  case LangOptions::SOB_Trapping: +    if (!E->canOverflow()) +      return Builder.CreateNSWAdd(InVal, Amount, Name); +    return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc)); +  } +  llvm_unreachable("Unknown SignedOverflowBehaviorTy"); +} + +llvm::Value * +ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, +                                           bool isInc, bool isPre) { + +  QualType type = E->getSubExpr()->getType(); +  llvm::PHINode *atomicPHI = nullptr; +  llvm::Value *value; +  llvm::Value *input; + +  int amount = (isInc ? 1 : -1); +  bool isSubtraction = !isInc; + +  if (const AtomicType *atomicTy = type->getAs<AtomicType>()) { +    type = atomicTy->getValueType(); +    if (isInc && type->isBooleanType()) { +      llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type); +      if (isPre) { +        Builder.CreateStore(True, LV.getAddress(), LV.isVolatileQualified()) +          ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent); +        return Builder.getTrue(); +      } +      // For atomic bool increment, we just store true and return it for +      // preincrement, do an atomic swap with true for postincrement +      return Builder.CreateAtomicRMW( +          llvm::AtomicRMWInst::Xchg, LV.getPointer(), True, +          llvm::AtomicOrdering::SequentiallyConsistent); +    } +    // Special case for atomic increment / decrement on integers, emit +    // atomicrmw instructions.  We skip this if we want to be doing overflow +    // checking, and fall into the slow path with the atomic cmpxchg loop. +    if (!type->isBooleanType() && type->isIntegerType() && +        !(type->isUnsignedIntegerType() && +          CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) && +        CGF.getLangOpts().getSignedOverflowBehavior() != +            LangOptions::SOB_Trapping) { +      llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add : +        llvm::AtomicRMWInst::Sub; +      llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add : +        llvm::Instruction::Sub; +      llvm::Value *amt = CGF.EmitToMemory( +          llvm::ConstantInt::get(ConvertType(type), 1, true), type); +      llvm::Value *old = Builder.CreateAtomicRMW(aop, +          LV.getPointer(), amt, llvm::AtomicOrdering::SequentiallyConsistent); +      return isPre ? Builder.CreateBinOp(op, old, amt) : old; +    } +    value = EmitLoadOfLValue(LV, E->getExprLoc()); +    input = value; +    // For every other atomic operation, we need to emit a load-op-cmpxchg loop +    llvm::BasicBlock *startBB = Builder.GetInsertBlock(); +    llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn); +    value = CGF.EmitToMemory(value, type); +    Builder.CreateBr(opBB); +    Builder.SetInsertPoint(opBB); +    atomicPHI = Builder.CreatePHI(value->getType(), 2); +    atomicPHI->addIncoming(value, startBB); +    value = atomicPHI; +  } else { +    value = EmitLoadOfLValue(LV, E->getExprLoc()); +    input = value; +  } + +  // Special case of integer increment that we have to check first: bool++. +  // Due to promotion rules, we get: +  //   bool++ -> bool = bool + 1 +  //          -> bool = (int)bool + 1 +  //          -> bool = ((int)bool + 1 != 0) +  // An interesting aspect of this is that increment is always true. +  // Decrement does not have this property. +  if (isInc && type->isBooleanType()) { +    value = Builder.getTrue(); + +  // Most common case by far: integer increment. +  } else if (type->isIntegerType()) { +    // Note that signed integer inc/dec with width less than int can't +    // overflow because of promotion rules; we're just eliding a few steps here. +    if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) { +      value = EmitIncDecConsiderOverflowBehavior(E, value, isInc); +    } else if (E->canOverflow() && type->isUnsignedIntegerType() && +               CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) { +      value = +          EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc)); +    } else { +      llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true); +      value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); +    } + +  // Next most common: pointer increment. +  } else if (const PointerType *ptr = type->getAs<PointerType>()) { +    QualType type = ptr->getPointeeType(); + +    // VLA types don't have constant size. +    if (const VariableArrayType *vla +          = CGF.getContext().getAsVariableArrayType(type)) { +      llvm::Value *numElts = CGF.getVLASize(vla).NumElts; +      if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize"); +      if (CGF.getLangOpts().isSignedOverflowDefined()) +        value = Builder.CreateGEP(value, numElts, "vla.inc"); +      else +        value = CGF.EmitCheckedInBoundsGEP( +            value, numElts, /*SignedIndices=*/false, isSubtraction, +            E->getExprLoc(), "vla.inc"); + +    // Arithmetic on function pointers (!) is just +-1. +    } else if (type->isFunctionType()) { +      llvm::Value *amt = Builder.getInt32(amount); + +      value = CGF.EmitCastToVoidPtr(value); +      if (CGF.getLangOpts().isSignedOverflowDefined()) +        value = Builder.CreateGEP(value, amt, "incdec.funcptr"); +      else +        value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false, +                                           isSubtraction, E->getExprLoc(), +                                           "incdec.funcptr"); +      value = Builder.CreateBitCast(value, input->getType()); + +    // For everything else, we can just do a simple increment. +    } else { +      llvm::Value *amt = Builder.getInt32(amount); +      if (CGF.getLangOpts().isSignedOverflowDefined()) +        value = Builder.CreateGEP(value, amt, "incdec.ptr"); +      else +        value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false, +                                           isSubtraction, E->getExprLoc(), +                                           "incdec.ptr"); +    } + +  // Vector increment/decrement. +  } else if (type->isVectorType()) { +    if (type->hasIntegerRepresentation()) { +      llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount); + +      value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); +    } else { +      value = Builder.CreateFAdd( +                  value, +                  llvm::ConstantFP::get(value->getType(), amount), +                  isInc ? "inc" : "dec"); +    } + +  // Floating point. +  } else if (type->isRealFloatingType()) { +    // Add the inc/dec to the real part. +    llvm::Value *amt; + +    if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { +      // Another special case: half FP increment should be done via float +      if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { +        value = Builder.CreateCall( +            CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, +                                 CGF.CGM.FloatTy), +            input, "incdec.conv"); +      } else { +        value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv"); +      } +    } + +    if (value->getType()->isFloatTy()) +      amt = llvm::ConstantFP::get(VMContext, +                                  llvm::APFloat(static_cast<float>(amount))); +    else if (value->getType()->isDoubleTy()) +      amt = llvm::ConstantFP::get(VMContext, +                                  llvm::APFloat(static_cast<double>(amount))); +    else { +      // Remaining types are Half, LongDouble or __float128. Convert from float. +      llvm::APFloat F(static_cast<float>(amount)); +      bool ignored; +      const llvm::fltSemantics *FS; +      // Don't use getFloatTypeSemantics because Half isn't +      // necessarily represented using the "half" LLVM type. +      if (value->getType()->isFP128Ty()) +        FS = &CGF.getTarget().getFloat128Format(); +      else if (value->getType()->isHalfTy()) +        FS = &CGF.getTarget().getHalfFormat(); +      else +        FS = &CGF.getTarget().getLongDoubleFormat(); +      F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored); +      amt = llvm::ConstantFP::get(VMContext, F); +    } +    value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec"); + +    if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { +      if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) { +        value = Builder.CreateCall( +            CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, +                                 CGF.CGM.FloatTy), +            value, "incdec.conv"); +      } else { +        value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv"); +      } +    } + +  // Objective-C pointer types. +  } else { +    const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>(); +    value = CGF.EmitCastToVoidPtr(value); + +    CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType()); +    if (!isInc) size = -size; +    llvm::Value *sizeValue = +      llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity()); + +    if (CGF.getLangOpts().isSignedOverflowDefined()) +      value = Builder.CreateGEP(value, sizeValue, "incdec.objptr"); +    else +      value = CGF.EmitCheckedInBoundsGEP(value, sizeValue, +                                         /*SignedIndices=*/false, isSubtraction, +                                         E->getExprLoc(), "incdec.objptr"); +    value = Builder.CreateBitCast(value, input->getType()); +  } + +  if (atomicPHI) { +    llvm::BasicBlock *curBlock = Builder.GetInsertBlock(); +    llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); +    auto Pair = CGF.EmitAtomicCompareExchange( +        LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc()); +    llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type); +    llvm::Value *success = Pair.second; +    atomicPHI->addIncoming(old, curBlock); +    Builder.CreateCondBr(success, contBB, atomicPHI->getParent()); +    Builder.SetInsertPoint(contBB); +    return isPre ? value : input; +  } + +  // Store the updated result through the lvalue. +  if (LV.isBitField()) +    CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value); +  else +    CGF.EmitStoreThroughLValue(RValue::get(value), LV); + +  // If this is a postinc, return the value read from memory, otherwise use the +  // updated value. +  return isPre ? value : input; +} + + + +Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { +  TestAndClearIgnoreResultAssign(); +  Value *Op = Visit(E->getSubExpr()); + +  // Generate a unary FNeg for FP ops. +  if (Op->getType()->isFPOrFPVectorTy()) +    return Builder.CreateFNeg(Op, "fneg"); + +  // Emit unary minus with EmitSub so we handle overflow cases etc. +  BinOpInfo BinOp; +  BinOp.RHS = Op; +  BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType()); +  BinOp.Ty = E->getType(); +  BinOp.Opcode = BO_Sub; +  // FIXME: once UnaryOperator carries FPFeatures, copy it here. +  BinOp.E = E; +  return EmitSub(BinOp); +} + +Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) { +  TestAndClearIgnoreResultAssign(); +  Value *Op = Visit(E->getSubExpr()); +  return Builder.CreateNot(Op, "neg"); +} + +Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { +  // Perform vector logical not on comparison with zero vector. +  if (E->getType()->isExtVectorType()) { +    Value *Oper = Visit(E->getSubExpr()); +    Value *Zero = llvm::Constant::getNullValue(Oper->getType()); +    Value *Result; +    if (Oper->getType()->isFPOrFPVectorTy()) +      Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp"); +    else +      Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp"); +    return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext"); +  } + +  // Compare operand to zero. +  Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr()); + +  // Invert value. +  // TODO: Could dynamically modify easy computations here.  For example, if +  // the operand is an icmp ne, turn into icmp eq. +  BoolVal = Builder.CreateNot(BoolVal, "lnot"); + +  // ZExt result to the expr type. +  return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext"); +} + +Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { +  // Try folding the offsetof to a constant. +  Expr::EvalResult EVResult; +  if (E->EvaluateAsInt(EVResult, CGF.getContext())) { +    llvm::APSInt Value = EVResult.Val.getInt(); +    return Builder.getInt(Value); +  } + +  // Loop over the components of the offsetof to compute the value. +  unsigned n = E->getNumComponents(); +  llvm::Type* ResultType = ConvertType(E->getType()); +  llvm::Value* Result = llvm::Constant::getNullValue(ResultType); +  QualType CurrentType = E->getTypeSourceInfo()->getType(); +  for (unsigned i = 0; i != n; ++i) { +    OffsetOfNode ON = E->getComponent(i); +    llvm::Value *Offset = nullptr; +    switch (ON.getKind()) { +    case OffsetOfNode::Array: { +      // Compute the index +      Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex()); +      llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr); +      bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType(); +      Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv"); + +      // Save the element type +      CurrentType = +          CGF.getContext().getAsArrayType(CurrentType)->getElementType(); + +      // Compute the element size +      llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType, +          CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity()); + +      // Multiply out to compute the result +      Offset = Builder.CreateMul(Idx, ElemSize); +      break; +    } + +    case OffsetOfNode::Field: { +      FieldDecl *MemberDecl = ON.getField(); +      RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl(); +      const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); + +      // Compute the index of the field in its parent. +      unsigned i = 0; +      // FIXME: It would be nice if we didn't have to loop here! +      for (RecordDecl::field_iterator Field = RD->field_begin(), +                                      FieldEnd = RD->field_end(); +           Field != FieldEnd; ++Field, ++i) { +        if (*Field == MemberDecl) +          break; +      } +      assert(i < RL.getFieldCount() && "offsetof field in wrong type"); + +      // Compute the offset to the field +      int64_t OffsetInt = RL.getFieldOffset(i) / +                          CGF.getContext().getCharWidth(); +      Offset = llvm::ConstantInt::get(ResultType, OffsetInt); + +      // Save the element type. +      CurrentType = MemberDecl->getType(); +      break; +    } + +    case OffsetOfNode::Identifier: +      llvm_unreachable("dependent __builtin_offsetof"); + +    case OffsetOfNode::Base: { +      if (ON.getBase()->isVirtual()) { +        CGF.ErrorUnsupported(E, "virtual base in offsetof"); +        continue; +      } + +      RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl(); +      const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); + +      // Save the element type. +      CurrentType = ON.getBase()->getType(); + +      // Compute the offset to the base. +      const RecordType *BaseRT = CurrentType->getAs<RecordType>(); +      CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl()); +      CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD); +      Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity()); +      break; +    } +    } +    Result = Builder.CreateAdd(Result, Offset); +  } +  return Result; +} + +/// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of +/// argument of the sizeof expression as an integer. +Value * +ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( +                              const UnaryExprOrTypeTraitExpr *E) { +  QualType TypeToSize = E->getTypeOfArgument(); +  if (E->getKind() == UETT_SizeOf) { +    if (const VariableArrayType *VAT = +          CGF.getContext().getAsVariableArrayType(TypeToSize)) { +      if (E->isArgumentType()) { +        // sizeof(type) - make sure to emit the VLA size. +        CGF.EmitVariablyModifiedType(TypeToSize); +      } else { +        // C99 6.5.3.4p2: If the argument is an expression of type +        // VLA, it is evaluated. +        CGF.EmitIgnoredExpr(E->getArgumentExpr()); +      } + +      auto VlaSize = CGF.getVLASize(VAT); +      llvm::Value *size = VlaSize.NumElts; + +      // Scale the number of non-VLA elements by the non-VLA element size. +      CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type); +      if (!eltSize.isOne()) +        size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size); + +      return size; +    } +  } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) { +    auto Alignment = +        CGF.getContext() +            .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( +                E->getTypeOfArgument()->getPointeeType())) +            .getQuantity(); +    return llvm::ConstantInt::get(CGF.SizeTy, Alignment); +  } + +  // If this isn't sizeof(vla), the result must be constant; use the constant +  // folding logic so we don't have to duplicate it here. +  return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext())); +} + +Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) { +  Expr *Op = E->getSubExpr(); +  if (Op->getType()->isAnyComplexType()) { +    // If it's an l-value, load through the appropriate subobject l-value. +    // Note that we have to ask E because Op might be an l-value that +    // this won't work for, e.g. an Obj-C property. +    if (E->isGLValue()) +      return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), +                                  E->getExprLoc()).getScalarVal(); + +    // Otherwise, calculate and project. +    return CGF.EmitComplexExpr(Op, false, true).first; +  } + +  return Visit(Op); +} + +Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) { +  Expr *Op = E->getSubExpr(); +  if (Op->getType()->isAnyComplexType()) { +    // If it's an l-value, load through the appropriate subobject l-value. +    // Note that we have to ask E because Op might be an l-value that +    // this won't work for, e.g. an Obj-C property. +    if (Op->isGLValue()) +      return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), +                                  E->getExprLoc()).getScalarVal(); + +    // Otherwise, calculate and project. +    return CGF.EmitComplexExpr(Op, true, false).second; +  } + +  // __imag on a scalar returns zero.  Emit the subexpr to ensure side +  // effects are evaluated, but not the actual value. +  if (Op->isGLValue()) +    CGF.EmitLValue(Op); +  else +    CGF.EmitScalarExpr(Op, true); +  return llvm::Constant::getNullValue(ConvertType(E->getType())); +} + +//===----------------------------------------------------------------------===// +//                           Binary Operators +//===----------------------------------------------------------------------===// + +BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) { +  TestAndClearIgnoreResultAssign(); +  BinOpInfo Result; +  Result.LHS = Visit(E->getLHS()); +  Result.RHS = Visit(E->getRHS()); +  Result.Ty  = E->getType(); +  Result.Opcode = E->getOpcode(); +  Result.FPFeatures = E->getFPFeatures(); +  Result.E = E; +  return Result; +} + +LValue ScalarExprEmitter::EmitCompoundAssignLValue( +                                              const CompoundAssignOperator *E, +                        Value *(ScalarExprEmitter::*Func)(const BinOpInfo &), +                                                   Value *&Result) { +  QualType LHSTy = E->getLHS()->getType(); +  BinOpInfo OpInfo; + +  if (E->getComputationResultType()->isAnyComplexType()) +    return CGF.EmitScalarCompoundAssignWithComplex(E, Result); + +  // Emit the RHS first.  __block variables need to have the rhs evaluated +  // first, plus this should improve codegen a little. +  OpInfo.RHS = Visit(E->getRHS()); +  OpInfo.Ty = E->getComputationResultType(); +  OpInfo.Opcode = E->getOpcode(); +  OpInfo.FPFeatures = E->getFPFeatures(); +  OpInfo.E = E; +  // Load/convert the LHS. +  LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); + +  llvm::PHINode *atomicPHI = nullptr; +  if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) { +    QualType type = atomicTy->getValueType(); +    if (!type->isBooleanType() && type->isIntegerType() && +        !(type->isUnsignedIntegerType() && +          CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) && +        CGF.getLangOpts().getSignedOverflowBehavior() != +            LangOptions::SOB_Trapping) { +      llvm::AtomicRMWInst::BinOp aop = llvm::AtomicRMWInst::BAD_BINOP; +      switch (OpInfo.Opcode) { +        // We don't have atomicrmw operands for *, %, /, <<, >> +        case BO_MulAssign: case BO_DivAssign: +        case BO_RemAssign: +        case BO_ShlAssign: +        case BO_ShrAssign: +          break; +        case BO_AddAssign: +          aop = llvm::AtomicRMWInst::Add; +          break; +        case BO_SubAssign: +          aop = llvm::AtomicRMWInst::Sub; +          break; +        case BO_AndAssign: +          aop = llvm::AtomicRMWInst::And; +          break; +        case BO_XorAssign: +          aop = llvm::AtomicRMWInst::Xor; +          break; +        case BO_OrAssign: +          aop = llvm::AtomicRMWInst::Or; +          break; +        default: +          llvm_unreachable("Invalid compound assignment type"); +      } +      if (aop != llvm::AtomicRMWInst::BAD_BINOP) { +        llvm::Value *amt = CGF.EmitToMemory( +            EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy, +                                 E->getExprLoc()), +            LHSTy); +        Builder.CreateAtomicRMW(aop, LHSLV.getPointer(), amt, +            llvm::AtomicOrdering::SequentiallyConsistent); +        return LHSLV; +      } +    } +    // FIXME: For floating point types, we should be saving and restoring the +    // floating point environment in the loop. +    llvm::BasicBlock *startBB = Builder.GetInsertBlock(); +    llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn); +    OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc()); +    OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type); +    Builder.CreateBr(opBB); +    Builder.SetInsertPoint(opBB); +    atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2); +    atomicPHI->addIncoming(OpInfo.LHS, startBB); +    OpInfo.LHS = atomicPHI; +  } +  else +    OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc()); + +  SourceLocation Loc = E->getExprLoc(); +  OpInfo.LHS = +      EmitScalarConversion(OpInfo.LHS, LHSTy, E->getComputationLHSType(), Loc); + +  // Expand the binary operator. +  Result = (this->*Func)(OpInfo); + +  // Convert the result back to the LHS type, +  // potentially with Implicit Conversion sanitizer check. +  Result = EmitScalarConversion(Result, E->getComputationResultType(), LHSTy, +                                Loc, ScalarConversionOpts(CGF.SanOpts)); + +  if (atomicPHI) { +    llvm::BasicBlock *curBlock = Builder.GetInsertBlock(); +    llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn); +    auto Pair = CGF.EmitAtomicCompareExchange( +        LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc()); +    llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy); +    llvm::Value *success = Pair.second; +    atomicPHI->addIncoming(old, curBlock); +    Builder.CreateCondBr(success, contBB, atomicPHI->getParent()); +    Builder.SetInsertPoint(contBB); +    return LHSLV; +  } + +  // Store the result value into the LHS lvalue. Bit-fields are handled +  // specially because the result is altered by the store, i.e., [C99 6.5.16p1] +  // 'An assignment expression has the value of the left operand after the +  // assignment...'. +  if (LHSLV.isBitField()) +    CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result); +  else +    CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV); + +  return LHSLV; +} + +Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, +                      Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) { +  bool Ignore = TestAndClearIgnoreResultAssign(); +  Value *RHS = nullptr; +  LValue LHS = EmitCompoundAssignLValue(E, Func, RHS); + +  // If the result is clearly ignored, return now. +  if (Ignore) +    return nullptr; + +  // The result of an assignment in C is the assigned r-value. +  if (!CGF.getLangOpts().CPlusPlus) +    return RHS; + +  // If the lvalue is non-volatile, return the computed value of the assignment. +  if (!LHS.isVolatileQualified()) +    return RHS; + +  // Otherwise, reload the value. +  return EmitLoadOfLValue(LHS, E->getExprLoc()); +} + +void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( +    const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) { +  SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + +  if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) { +    Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero), +                                    SanitizerKind::IntegerDivideByZero)); +  } + +  const auto *BO = cast<BinaryOperator>(Ops.E); +  if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) && +      Ops.Ty->hasSignedIntegerRepresentation() && +      !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) && +      Ops.mayHaveIntegerOverflow()) { +    llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType()); + +    llvm::Value *IntMin = +      Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth())); +    llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL); + +    llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin); +    llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne); +    llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or"); +    Checks.push_back( +        std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow)); +  } + +  if (Checks.size() > 0) +    EmitBinOpCheck(Checks, Ops); +} + +Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { +  { +    CodeGenFunction::SanitizerScope SanScope(&CGF); +    if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) || +         CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) && +        Ops.Ty->isIntegerType() && +        (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) { +      llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); +      EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true); +    } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) && +               Ops.Ty->isRealFloatingType() && +               Ops.mayHaveFloatDivisionByZero()) { +      llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); +      llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero); +      EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero), +                     Ops); +    } +  } + +  if (Ops.LHS->getType()->isFPOrFPVectorTy()) { +    llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div"); +    if (CGF.getLangOpts().OpenCL && +        !CGF.CGM.getCodeGenOpts().CorrectlyRoundedDivSqrt) { +      // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 2.5ulp +      // OpenCL v1.2 s5.6.4.2: The -cl-fp32-correctly-rounded-divide-sqrt +      // build option allows an application to specify that single precision +      // floating-point divide (x/y and 1/x) and sqrt used in the program +      // source are correctly rounded. +      llvm::Type *ValTy = Val->getType(); +      if (ValTy->isFloatTy() || +          (isa<llvm::VectorType>(ValTy) && +           cast<llvm::VectorType>(ValTy)->getElementType()->isFloatTy())) +        CGF.SetFPAccuracy(Val, 2.5); +    } +    return Val; +  } +  else if (Ops.Ty->hasUnsignedIntegerRepresentation()) +    return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div"); +  else +    return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div"); +} + +Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) { +  // Rem in C can't be a floating point type: C99 6.5.5p2. +  if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) || +       CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) && +      Ops.Ty->isIntegerType() && +      (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) { +    CodeGenFunction::SanitizerScope SanScope(&CGF); +    llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); +    EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false); +  } + +  if (Ops.Ty->hasUnsignedIntegerRepresentation()) +    return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem"); +  else +    return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem"); +} + +Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { +  unsigned IID; +  unsigned OpID = 0; + +  bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType(); +  switch (Ops.Opcode) { +  case BO_Add: +  case BO_AddAssign: +    OpID = 1; +    IID = isSigned ? llvm::Intrinsic::sadd_with_overflow : +                     llvm::Intrinsic::uadd_with_overflow; +    break; +  case BO_Sub: +  case BO_SubAssign: +    OpID = 2; +    IID = isSigned ? llvm::Intrinsic::ssub_with_overflow : +                     llvm::Intrinsic::usub_with_overflow; +    break; +  case BO_Mul: +  case BO_MulAssign: +    OpID = 3; +    IID = isSigned ? llvm::Intrinsic::smul_with_overflow : +                     llvm::Intrinsic::umul_with_overflow; +    break; +  default: +    llvm_unreachable("Unsupported operation for overflow detection"); +  } +  OpID <<= 1; +  if (isSigned) +    OpID |= 1; + +  CodeGenFunction::SanitizerScope SanScope(&CGF); +  llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty); + +  llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy); + +  Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS}); +  Value *result = Builder.CreateExtractValue(resultAndOverflow, 0); +  Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1); + +  // Handle overflow with llvm.trap if no custom handler has been specified. +  const std::string *handlerName = +    &CGF.getLangOpts().OverflowHandler; +  if (handlerName->empty()) { +    // If the signed-integer-overflow sanitizer is enabled, emit a call to its +    // runtime. Otherwise, this is a -ftrapv check, so just emit a trap. +    if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) { +      llvm::Value *NotOverflow = Builder.CreateNot(overflow); +      SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow +                              : SanitizerKind::UnsignedIntegerOverflow; +      EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops); +    } else +      CGF.EmitTrapCheck(Builder.CreateNot(overflow)); +    return result; +  } + +  // Branch in case of overflow. +  llvm::BasicBlock *initialBB = Builder.GetInsertBlock(); +  llvm::BasicBlock *continueBB = +      CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode()); +  llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn); + +  Builder.CreateCondBr(overflow, overflowBB, continueBB); + +  // If an overflow handler is set, then we want to call it and then use its +  // result, if it returns. +  Builder.SetInsertPoint(overflowBB); + +  // Get the overflow handler. +  llvm::Type *Int8Ty = CGF.Int8Ty; +  llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty }; +  llvm::FunctionType *handlerTy = +      llvm::FunctionType::get(CGF.Int64Ty, argTypes, true); +  llvm::FunctionCallee handler = +      CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName); + +  // Sign extend the args to 64-bit, so that we can use the same handler for +  // all types of overflow. +  llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty); +  llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty); + +  // Call the handler with the two arguments, the operation, and the size of +  // the result. +  llvm::Value *handlerArgs[] = { +    lhs, +    rhs, +    Builder.getInt8(OpID), +    Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth()) +  }; +  llvm::Value *handlerResult = +    CGF.EmitNounwindRuntimeCall(handler, handlerArgs); + +  // Truncate the result back to the desired size. +  handlerResult = Builder.CreateTrunc(handlerResult, opTy); +  Builder.CreateBr(continueBB); + +  Builder.SetInsertPoint(continueBB); +  llvm::PHINode *phi = Builder.CreatePHI(opTy, 2); +  phi->addIncoming(result, initialBB); +  phi->addIncoming(handlerResult, overflowBB); + +  return phi; +} + +/// Emit pointer + index arithmetic. +static Value *emitPointerArithmetic(CodeGenFunction &CGF, +                                    const BinOpInfo &op, +                                    bool isSubtraction) { +  // Must have binary (not unary) expr here.  Unary pointer +  // increment/decrement doesn't use this path. +  const BinaryOperator *expr = cast<BinaryOperator>(op.E); + +  Value *pointer = op.LHS; +  Expr *pointerOperand = expr->getLHS(); +  Value *index = op.RHS; +  Expr *indexOperand = expr->getRHS(); + +  // In a subtraction, the LHS is always the pointer. +  if (!isSubtraction && !pointer->getType()->isPointerTy()) { +    std::swap(pointer, index); +    std::swap(pointerOperand, indexOperand); +  } + +  bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType(); + +  unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth(); +  auto &DL = CGF.CGM.getDataLayout(); +  auto PtrTy = cast<llvm::PointerType>(pointer->getType()); + +  // Some versions of glibc and gcc use idioms (particularly in their malloc +  // routines) that add a pointer-sized integer (known to be a pointer value) +  // to a null pointer in order to cast the value back to an integer or as +  // part of a pointer alignment algorithm.  This is undefined behavior, but +  // we'd like to be able to compile programs that use it. +  // +  // Normally, we'd generate a GEP with a null-pointer base here in response +  // to that code, but it's also UB to dereference a pointer created that +  // way.  Instead (as an acknowledged hack to tolerate the idiom) we will +  // generate a direct cast of the integer value to a pointer. +  // +  // The idiom (p = nullptr + N) is not met if any of the following are true: +  // +  //   The operation is subtraction. +  //   The index is not pointer-sized. +  //   The pointer type is not byte-sized. +  // +  if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(), +                                                       op.Opcode, +                                                       expr->getLHS(), +                                                       expr->getRHS())) +    return CGF.Builder.CreateIntToPtr(index, pointer->getType()); + +  if (width != DL.getTypeSizeInBits(PtrTy)) { +    // Zero-extend or sign-extend the pointer value according to +    // whether the index is signed or not. +    index = CGF.Builder.CreateIntCast(index, DL.getIntPtrType(PtrTy), isSigned, +                                      "idx.ext"); +  } + +  // If this is subtraction, negate the index. +  if (isSubtraction) +    index = CGF.Builder.CreateNeg(index, "idx.neg"); + +  if (CGF.SanOpts.has(SanitizerKind::ArrayBounds)) +    CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(), +                        /*Accessed*/ false); + +  const PointerType *pointerType +    = pointerOperand->getType()->getAs<PointerType>(); +  if (!pointerType) { +    QualType objectType = pointerOperand->getType() +                                        ->castAs<ObjCObjectPointerType>() +                                        ->getPointeeType(); +    llvm::Value *objectSize +      = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType)); + +    index = CGF.Builder.CreateMul(index, objectSize); + +    Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy); +    result = CGF.Builder.CreateGEP(result, index, "add.ptr"); +    return CGF.Builder.CreateBitCast(result, pointer->getType()); +  } + +  QualType elementType = pointerType->getPointeeType(); +  if (const VariableArrayType *vla +        = CGF.getContext().getAsVariableArrayType(elementType)) { +    // The element count here is the total number of non-VLA elements. +    llvm::Value *numElements = CGF.getVLASize(vla).NumElts; + +    // Effectively, the multiply by the VLA size is part of the GEP. +    // GEP indexes are signed, and scaling an index isn't permitted to +    // signed-overflow, so we use the same semantics for our explicit +    // multiply.  We suppress this if overflow is not undefined behavior. +    if (CGF.getLangOpts().isSignedOverflowDefined()) { +      index = CGF.Builder.CreateMul(index, numElements, "vla.index"); +      pointer = CGF.Builder.CreateGEP(pointer, index, "add.ptr"); +    } else { +      index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index"); +      pointer = +          CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction, +                                     op.E->getExprLoc(), "add.ptr"); +    } +    return pointer; +  } + +  // Explicitly handle GNU void* and function pointer arithmetic extensions. The +  // GNU void* casts amount to no-ops since our void* type is i8*, but this is +  // future proof. +  if (elementType->isVoidType() || elementType->isFunctionType()) { +    Value *result = CGF.Builder.CreateBitCast(pointer, CGF.VoidPtrTy); +    result = CGF.Builder.CreateGEP(result, index, "add.ptr"); +    return CGF.Builder.CreateBitCast(result, pointer->getType()); +  } + +  if (CGF.getLangOpts().isSignedOverflowDefined()) +    return CGF.Builder.CreateGEP(pointer, index, "add.ptr"); + +  return CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction, +                                    op.E->getExprLoc(), "add.ptr"); +} + +// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and +// Addend. Use negMul and negAdd to negate the first operand of the Mul or +// the add operand respectively. This allows fmuladd to represent a*b-c, or +// c-a*b. Patterns in LLVM should catch the negated forms and translate them to +// efficient operations. +static Value* buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend, +                           const CodeGenFunction &CGF, CGBuilderTy &Builder, +                           bool negMul, bool negAdd) { +  assert(!(negMul && negAdd) && "Only one of negMul and negAdd should be set."); + +  Value *MulOp0 = MulOp->getOperand(0); +  Value *MulOp1 = MulOp->getOperand(1); +  if (negMul) { +    MulOp0 = +      Builder.CreateFSub( +        llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()), MulOp0, +        "neg"); +  } else if (negAdd) { +    Addend = +      Builder.CreateFSub( +        llvm::ConstantFP::getZeroValueForNegation(Addend->getType()), Addend, +        "neg"); +  } + +  Value *FMulAdd = Builder.CreateCall( +      CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()), +      {MulOp0, MulOp1, Addend}); +   MulOp->eraseFromParent(); + +   return FMulAdd; +} + +// Check whether it would be legal to emit an fmuladd intrinsic call to +// represent op and if so, build the fmuladd. +// +// Checks that (a) the operation is fusable, and (b) -ffp-contract=on. +// Does NOT check the type of the operation - it's assumed that this function +// will be called from contexts where it's known that the type is contractable. +static Value* tryEmitFMulAdd(const BinOpInfo &op, +                         const CodeGenFunction &CGF, CGBuilderTy &Builder, +                         bool isSub=false) { + +  assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign || +          op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) && +         "Only fadd/fsub can be the root of an fmuladd."); + +  // Check whether this op is marked as fusable. +  if (!op.FPFeatures.allowFPContractWithinStatement()) +    return nullptr; + +  // We have a potentially fusable op. Look for a mul on one of the operands. +  // Also, make sure that the mul result isn't used directly. In that case, +  // there's no point creating a muladd operation. +  if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) { +    if (LHSBinOp->getOpcode() == llvm::Instruction::FMul && +        LHSBinOp->use_empty()) +      return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub); +  } +  if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) { +    if (RHSBinOp->getOpcode() == llvm::Instruction::FMul && +        RHSBinOp->use_empty()) +      return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false); +  } + +  return nullptr; +} + +Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) { +  if (op.LHS->getType()->isPointerTy() || +      op.RHS->getType()->isPointerTy()) +    return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction); + +  if (op.Ty->isSignedIntegerOrEnumerationType()) { +    switch (CGF.getLangOpts().getSignedOverflowBehavior()) { +    case LangOptions::SOB_Defined: +      return Builder.CreateAdd(op.LHS, op.RHS, "add"); +    case LangOptions::SOB_Undefined: +      if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) +        return Builder.CreateNSWAdd(op.LHS, op.RHS, "add"); +      LLVM_FALLTHROUGH; +    case LangOptions::SOB_Trapping: +      if (CanElideOverflowCheck(CGF.getContext(), op)) +        return Builder.CreateNSWAdd(op.LHS, op.RHS, "add"); +      return EmitOverflowCheckedBinOp(op); +    } +  } + +  if (op.Ty->isUnsignedIntegerType() && +      CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && +      !CanElideOverflowCheck(CGF.getContext(), op)) +    return EmitOverflowCheckedBinOp(op); + +  if (op.LHS->getType()->isFPOrFPVectorTy()) { +    // Try to form an fmuladd. +    if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder)) +      return FMulAdd; + +    Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add"); +    return propagateFMFlags(V, op); +  } + +  if (op.isFixedPointBinOp()) +    return EmitFixedPointBinOp(op); + +  return Builder.CreateAdd(op.LHS, op.RHS, "add"); +} + +/// The resulting value must be calculated with exact precision, so the operands +/// may not be the same type. +Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { +  using llvm::APSInt; +  using llvm::ConstantInt; + +  const auto *BinOp = cast<BinaryOperator>(op.E); + +  // The result is a fixed point type and at least one of the operands is fixed +  // point while the other is either fixed point or an int. This resulting type +  // should be determined by Sema::handleFixedPointConversions(). +  QualType ResultTy = op.Ty; +  QualType LHSTy = BinOp->getLHS()->getType(); +  QualType RHSTy = BinOp->getRHS()->getType(); +  ASTContext &Ctx = CGF.getContext(); +  Value *LHS = op.LHS; +  Value *RHS = op.RHS; + +  auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy); +  auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy); +  auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy); +  auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema); + +  // Convert the operands to the full precision type. +  Value *FullLHS = EmitFixedPointConversion(LHS, LHSFixedSema, CommonFixedSema, +                                            BinOp->getExprLoc()); +  Value *FullRHS = EmitFixedPointConversion(RHS, RHSFixedSema, CommonFixedSema, +                                            BinOp->getExprLoc()); + +  // Perform the actual addition. +  Value *Result; +  switch (BinOp->getOpcode()) { +  case BO_Add: { +    if (ResultFixedSema.isSaturated()) { +      llvm::Intrinsic::ID IID = ResultFixedSema.isSigned() +                                    ? llvm::Intrinsic::sadd_sat +                                    : llvm::Intrinsic::uadd_sat; +      Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS); +    } else { +      Result = Builder.CreateAdd(FullLHS, FullRHS); +    } +    break; +  } +  case BO_Sub: { +    if (ResultFixedSema.isSaturated()) { +      llvm::Intrinsic::ID IID = ResultFixedSema.isSigned() +                                    ? llvm::Intrinsic::ssub_sat +                                    : llvm::Intrinsic::usub_sat; +      Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS); +    } else { +      Result = Builder.CreateSub(FullLHS, FullRHS); +    } +    break; +  } +  case BO_LT: +    return CommonFixedSema.isSigned() ? Builder.CreateICmpSLT(FullLHS, FullRHS) +                                      : Builder.CreateICmpULT(FullLHS, FullRHS); +  case BO_GT: +    return CommonFixedSema.isSigned() ? Builder.CreateICmpSGT(FullLHS, FullRHS) +                                      : Builder.CreateICmpUGT(FullLHS, FullRHS); +  case BO_LE: +    return CommonFixedSema.isSigned() ? Builder.CreateICmpSLE(FullLHS, FullRHS) +                                      : Builder.CreateICmpULE(FullLHS, FullRHS); +  case BO_GE: +    return CommonFixedSema.isSigned() ? Builder.CreateICmpSGE(FullLHS, FullRHS) +                                      : Builder.CreateICmpUGE(FullLHS, FullRHS); +  case BO_EQ: +    // For equality operations, we assume any padding bits on unsigned types are +    // zero'd out. They could be overwritten through non-saturating operations +    // that cause overflow, but this leads to undefined behavior. +    return Builder.CreateICmpEQ(FullLHS, FullRHS); +  case BO_NE: +    return Builder.CreateICmpNE(FullLHS, FullRHS); +  case BO_Mul: +  case BO_Div: +  case BO_Shl: +  case BO_Shr: +  case BO_Cmp: +  case BO_LAnd: +  case BO_LOr: +  case BO_MulAssign: +  case BO_DivAssign: +  case BO_AddAssign: +  case BO_SubAssign: +  case BO_ShlAssign: +  case BO_ShrAssign: +    llvm_unreachable("Found unimplemented fixed point binary operation"); +  case BO_PtrMemD: +  case BO_PtrMemI: +  case BO_Rem: +  case BO_Xor: +  case BO_And: +  case BO_Or: +  case BO_Assign: +  case BO_RemAssign: +  case BO_AndAssign: +  case BO_XorAssign: +  case BO_OrAssign: +  case BO_Comma: +    llvm_unreachable("Found unsupported binary operation for fixed point types."); +  } + +  // Convert to the result type. +  return EmitFixedPointConversion(Result, CommonFixedSema, ResultFixedSema, +                                  BinOp->getExprLoc()); +} + +Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { +  // The LHS is always a pointer if either side is. +  if (!op.LHS->getType()->isPointerTy()) { +    if (op.Ty->isSignedIntegerOrEnumerationType()) { +      switch (CGF.getLangOpts().getSignedOverflowBehavior()) { +      case LangOptions::SOB_Defined: +        return Builder.CreateSub(op.LHS, op.RHS, "sub"); +      case LangOptions::SOB_Undefined: +        if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) +          return Builder.CreateNSWSub(op.LHS, op.RHS, "sub"); +        LLVM_FALLTHROUGH; +      case LangOptions::SOB_Trapping: +        if (CanElideOverflowCheck(CGF.getContext(), op)) +          return Builder.CreateNSWSub(op.LHS, op.RHS, "sub"); +        return EmitOverflowCheckedBinOp(op); +      } +    } + +    if (op.Ty->isUnsignedIntegerType() && +        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && +        !CanElideOverflowCheck(CGF.getContext(), op)) +      return EmitOverflowCheckedBinOp(op); + +    if (op.LHS->getType()->isFPOrFPVectorTy()) { +      // Try to form an fmuladd. +      if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true)) +        return FMulAdd; +      Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub"); +      return propagateFMFlags(V, op); +    } + +    if (op.isFixedPointBinOp()) +      return EmitFixedPointBinOp(op); + +    return Builder.CreateSub(op.LHS, op.RHS, "sub"); +  } + +  // If the RHS is not a pointer, then we have normal pointer +  // arithmetic. +  if (!op.RHS->getType()->isPointerTy()) +    return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction); + +  // Otherwise, this is a pointer subtraction. + +  // Do the raw subtraction part. +  llvm::Value *LHS +    = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast"); +  llvm::Value *RHS +    = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast"); +  Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub"); + +  // Okay, figure out the element size. +  const BinaryOperator *expr = cast<BinaryOperator>(op.E); +  QualType elementType = expr->getLHS()->getType()->getPointeeType(); + +  llvm::Value *divisor = nullptr; + +  // For a variable-length array, this is going to be non-constant. +  if (const VariableArrayType *vla +        = CGF.getContext().getAsVariableArrayType(elementType)) { +    auto VlaSize = CGF.getVLASize(vla); +    elementType = VlaSize.Type; +    divisor = VlaSize.NumElts; + +    // Scale the number of non-VLA elements by the non-VLA element size. +    CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType); +    if (!eltSize.isOne()) +      divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor); + +  // For everything elese, we can just compute it, safe in the +  // assumption that Sema won't let anything through that we can't +  // safely compute the size of. +  } else { +    CharUnits elementSize; +    // Handle GCC extension for pointer arithmetic on void* and +    // function pointer types. +    if (elementType->isVoidType() || elementType->isFunctionType()) +      elementSize = CharUnits::One(); +    else +      elementSize = CGF.getContext().getTypeSizeInChars(elementType); + +    // Don't even emit the divide for element size of 1. +    if (elementSize.isOne()) +      return diffInChars; + +    divisor = CGF.CGM.getSize(elementSize); +  } + +  // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since +  // pointer difference in C is only defined in the case where both operands +  // are pointing to elements of an array. +  return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div"); +} + +Value *ScalarExprEmitter::GetWidthMinusOneValue(Value* LHS,Value* RHS) { +  llvm::IntegerType *Ty; +  if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType())) +    Ty = cast<llvm::IntegerType>(VT->getElementType()); +  else +    Ty = cast<llvm::IntegerType>(LHS->getType()); +  return llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth() - 1); +} + +Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { +  // LLVM requires the LHS and RHS to be the same type: promote or truncate the +  // RHS to the same size as the LHS. +  Value *RHS = Ops.RHS; +  if (Ops.LHS->getType() != RHS->getType()) +    RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + +  bool SanitizeBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) && +                      Ops.Ty->hasSignedIntegerRepresentation() && +                      !CGF.getLangOpts().isSignedOverflowDefined() && +                      !CGF.getLangOpts().CPlusPlus2a; +  bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent); +  // OpenCL 6.3j: shift values are effectively % word size of LHS. +  if (CGF.getLangOpts().OpenCL) +    RHS = +        Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shl.mask"); +  else if ((SanitizeBase || SanitizeExponent) && +           isa<llvm::IntegerType>(Ops.LHS->getType())) { +    CodeGenFunction::SanitizerScope SanScope(&CGF); +    SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks; +    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS); +    llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne); + +    if (SanitizeExponent) { +      Checks.push_back( +          std::make_pair(ValidExponent, SanitizerKind::ShiftExponent)); +    } + +    if (SanitizeBase) { +      // Check whether we are shifting any non-zero bits off the top of the +      // integer. We only emit this check if exponent is valid - otherwise +      // instructions below will have undefined behavior themselves. +      llvm::BasicBlock *Orig = Builder.GetInsertBlock(); +      llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); +      llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check"); +      Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont); +      llvm::Value *PromotedWidthMinusOne = +          (RHS == Ops.RHS) ? WidthMinusOne +                           : GetWidthMinusOneValue(Ops.LHS, RHS); +      CGF.EmitBlock(CheckShiftBase); +      llvm::Value *BitsShiftedOff = Builder.CreateLShr( +          Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros", +                                     /*NUW*/ true, /*NSW*/ true), +          "shl.check"); +      if (CGF.getLangOpts().CPlusPlus) { +        // In C99, we are not permitted to shift a 1 bit into the sign bit. +        // Under C++11's rules, shifting a 1 bit into the sign bit is +        // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't +        // define signed left shifts, so we use the C99 and C++11 rules there). +        llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1); +        BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One); +      } +      llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0); +      llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero); +      CGF.EmitBlock(Cont); +      llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2); +      BaseCheck->addIncoming(Builder.getTrue(), Orig); +      BaseCheck->addIncoming(ValidBase, CheckShiftBase); +      Checks.push_back(std::make_pair(BaseCheck, SanitizerKind::ShiftBase)); +    } + +    assert(!Checks.empty()); +    EmitBinOpCheck(Checks, Ops); +  } + +  return Builder.CreateShl(Ops.LHS, RHS, "shl"); +} + +Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { +  // LLVM requires the LHS and RHS to be the same type: promote or truncate the +  // RHS to the same size as the LHS. +  Value *RHS = Ops.RHS; +  if (Ops.LHS->getType() != RHS->getType()) +    RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); + +  // OpenCL 6.3j: shift values are effectively % word size of LHS. +  if (CGF.getLangOpts().OpenCL) +    RHS = +        Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shr.mask"); +  else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) && +           isa<llvm::IntegerType>(Ops.LHS->getType())) { +    CodeGenFunction::SanitizerScope SanScope(&CGF); +    llvm::Value *Valid = +        Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)); +    EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops); +  } + +  if (Ops.Ty->hasUnsignedIntegerRepresentation()) +    return Builder.CreateLShr(Ops.LHS, RHS, "shr"); +  return Builder.CreateAShr(Ops.LHS, RHS, "shr"); +} + +enum IntrinsicType { VCMPEQ, VCMPGT }; +// return corresponding comparison intrinsic for given vector type +static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, +                                        BuiltinType::Kind ElemKind) { +  switch (ElemKind) { +  default: llvm_unreachable("unexpected element type"); +  case BuiltinType::Char_U: +  case BuiltinType::UChar: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtub_p; +  case BuiltinType::Char_S: +  case BuiltinType::SChar: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtsb_p; +  case BuiltinType::UShort: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtuh_p; +  case BuiltinType::Short: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtsh_p; +  case BuiltinType::UInt: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtuw_p; +  case BuiltinType::Int: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtsw_p; +  case BuiltinType::ULong: +  case BuiltinType::ULongLong: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtud_p; +  case BuiltinType::Long: +  case BuiltinType::LongLong: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtsd_p; +  case BuiltinType::Float: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p : +                            llvm::Intrinsic::ppc_altivec_vcmpgtfp_p; +  case BuiltinType::Double: +    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p : +                            llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p; +  } +} + +Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E, +                                      llvm::CmpInst::Predicate UICmpOpc, +                                      llvm::CmpInst::Predicate SICmpOpc, +                                      llvm::CmpInst::Predicate FCmpOpc) { +  TestAndClearIgnoreResultAssign(); +  Value *Result; +  QualType LHSTy = E->getLHS()->getType(); +  QualType RHSTy = E->getRHS()->getType(); +  if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) { +    assert(E->getOpcode() == BO_EQ || +           E->getOpcode() == BO_NE); +    Value *LHS = CGF.EmitScalarExpr(E->getLHS()); +    Value *RHS = CGF.EmitScalarExpr(E->getRHS()); +    Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison( +                   CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE); +  } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) { +    BinOpInfo BOInfo = EmitBinOps(E); +    Value *LHS = BOInfo.LHS; +    Value *RHS = BOInfo.RHS; + +    // If AltiVec, the comparison results in a numeric type, so we use +    // intrinsics comparing vectors and giving 0 or 1 as a result +    if (LHSTy->isVectorType() && !E->getType()->isVectorType()) { +      // constants for mapping CR6 register bits to predicate result +      enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6; + +      llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic; + +      // in several cases vector arguments order will be reversed +      Value *FirstVecArg = LHS, +            *SecondVecArg = RHS; + +      QualType ElTy = LHSTy->castAs<VectorType>()->getElementType(); +      const BuiltinType *BTy = ElTy->getAs<BuiltinType>(); +      BuiltinType::Kind ElementKind = BTy->getKind(); + +      switch(E->getOpcode()) { +      default: llvm_unreachable("is not a comparison operation"); +      case BO_EQ: +        CR6 = CR6_LT; +        ID = GetIntrinsic(VCMPEQ, ElementKind); +        break; +      case BO_NE: +        CR6 = CR6_EQ; +        ID = GetIntrinsic(VCMPEQ, ElementKind); +        break; +      case BO_LT: +        CR6 = CR6_LT; +        ID = GetIntrinsic(VCMPGT, ElementKind); +        std::swap(FirstVecArg, SecondVecArg); +        break; +      case BO_GT: +        CR6 = CR6_LT; +        ID = GetIntrinsic(VCMPGT, ElementKind); +        break; +      case BO_LE: +        if (ElementKind == BuiltinType::Float) { +          CR6 = CR6_LT; +          ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p; +          std::swap(FirstVecArg, SecondVecArg); +        } +        else { +          CR6 = CR6_EQ; +          ID = GetIntrinsic(VCMPGT, ElementKind); +        } +        break; +      case BO_GE: +        if (ElementKind == BuiltinType::Float) { +          CR6 = CR6_LT; +          ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p; +        } +        else { +          CR6 = CR6_EQ; +          ID = GetIntrinsic(VCMPGT, ElementKind); +          std::swap(FirstVecArg, SecondVecArg); +        } +        break; +      } + +      Value *CR6Param = Builder.getInt32(CR6); +      llvm::Function *F = CGF.CGM.getIntrinsic(ID); +      Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg}); + +      // The result type of intrinsic may not be same as E->getType(). +      // If E->getType() is not BoolTy, EmitScalarConversion will do the +      // conversion work. If E->getType() is BoolTy, EmitScalarConversion will +      // do nothing, if ResultTy is not i1 at the same time, it will cause +      // crash later. +      llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType()); +      if (ResultTy->getBitWidth() > 1 && +          E->getType() == CGF.getContext().BoolTy) +        Result = Builder.CreateTrunc(Result, Builder.getInt1Ty()); +      return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(), +                                  E->getExprLoc()); +    } + +    if (BOInfo.isFixedPointBinOp()) { +      Result = EmitFixedPointBinOp(BOInfo); +    } else if (LHS->getType()->isFPOrFPVectorTy()) { +      Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp"); +    } else if (LHSTy->hasSignedIntegerRepresentation()) { +      Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp"); +    } else { +      // Unsigned integers and pointers. + +      if (CGF.CGM.getCodeGenOpts().StrictVTablePointers && +          !isa<llvm::ConstantPointerNull>(LHS) && +          !isa<llvm::ConstantPointerNull>(RHS)) { + +        // Dynamic information is required to be stripped for comparisons, +        // because it could leak the dynamic information.  Based on comparisons +        // of pointers to dynamic objects, the optimizer can replace one pointer +        // with another, which might be incorrect in presence of invariant +        // groups. Comparison with null is safe because null does not carry any +        // dynamic information. +        if (LHSTy.mayBeDynamicClass()) +          LHS = Builder.CreateStripInvariantGroup(LHS); +        if (RHSTy.mayBeDynamicClass()) +          RHS = Builder.CreateStripInvariantGroup(RHS); +      } + +      Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp"); +    } + +    // If this is a vector comparison, sign extend the result to the appropriate +    // vector integer type and return it (don't convert to bool). +    if (LHSTy->isVectorType()) +      return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext"); + +  } else { +    // Complex Comparison: can only be an equality comparison. +    CodeGenFunction::ComplexPairTy LHS, RHS; +    QualType CETy; +    if (auto *CTy = LHSTy->getAs<ComplexType>()) { +      LHS = CGF.EmitComplexExpr(E->getLHS()); +      CETy = CTy->getElementType(); +    } else { +      LHS.first = Visit(E->getLHS()); +      LHS.second = llvm::Constant::getNullValue(LHS.first->getType()); +      CETy = LHSTy; +    } +    if (auto *CTy = RHSTy->getAs<ComplexType>()) { +      RHS = CGF.EmitComplexExpr(E->getRHS()); +      assert(CGF.getContext().hasSameUnqualifiedType(CETy, +                                                     CTy->getElementType()) && +             "The element types must always match."); +      (void)CTy; +    } else { +      RHS.first = Visit(E->getRHS()); +      RHS.second = llvm::Constant::getNullValue(RHS.first->getType()); +      assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) && +             "The element types must always match."); +    } + +    Value *ResultR, *ResultI; +    if (CETy->isRealFloatingType()) { +      ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r"); +      ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i"); +    } else { +      // Complex comparisons can only be equality comparisons.  As such, signed +      // and unsigned opcodes are the same. +      ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r"); +      ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i"); +    } + +    if (E->getOpcode() == BO_EQ) { +      Result = Builder.CreateAnd(ResultR, ResultI, "and.ri"); +    } else { +      assert(E->getOpcode() == BO_NE && +             "Complex comparison other than == or != ?"); +      Result = Builder.CreateOr(ResultR, ResultI, "or.ri"); +    } +  } + +  return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(), +                              E->getExprLoc()); +} + +Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { +  bool Ignore = TestAndClearIgnoreResultAssign(); + +  Value *RHS; +  LValue LHS; + +  switch (E->getLHS()->getType().getObjCLifetime()) { +  case Qualifiers::OCL_Strong: +    std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore); +    break; + +  case Qualifiers::OCL_Autoreleasing: +    std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E); +    break; + +  case Qualifiers::OCL_ExplicitNone: +    std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore); +    break; + +  case Qualifiers::OCL_Weak: +    RHS = Visit(E->getRHS()); +    LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); +    RHS = CGF.EmitARCStoreWeak(LHS.getAddress(), RHS, Ignore); +    break; + +  case Qualifiers::OCL_None: +    // __block variables need to have the rhs evaluated first, plus +    // this should improve codegen just a little. +    RHS = Visit(E->getRHS()); +    LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store); + +    // Store the value into the LHS.  Bit-fields are handled specially +    // because the result is altered by the store, i.e., [C99 6.5.16p1] +    // 'An assignment expression has the value of the left operand after +    // the assignment...'. +    if (LHS.isBitField()) { +      CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS); +    } else { +      CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc()); +      CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS); +    } +  } + +  // If the result is clearly ignored, return now. +  if (Ignore) +    return nullptr; + +  // The result of an assignment in C is the assigned r-value. +  if (!CGF.getLangOpts().CPlusPlus) +    return RHS; + +  // If the lvalue is non-volatile, return the computed value of the assignment. +  if (!LHS.isVolatileQualified()) +    return RHS; + +  // Otherwise, reload the value. +  return EmitLoadOfLValue(LHS, E->getExprLoc()); +} + +Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { +  // Perform vector logical and on comparisons with zero vectors. +  if (E->getType()->isVectorType()) { +    CGF.incrementProfileCounter(E); + +    Value *LHS = Visit(E->getLHS()); +    Value *RHS = Visit(E->getRHS()); +    Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); +    if (LHS->getType()->isFPOrFPVectorTy()) { +      LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); +      RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); +    } else { +      LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); +      RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); +    } +    Value *And = Builder.CreateAnd(LHS, RHS); +    return Builder.CreateSExt(And, ConvertType(E->getType()), "sext"); +  } + +  llvm::Type *ResTy = ConvertType(E->getType()); + +  // If we have 0 && RHS, see if we can elide RHS, if so, just return 0. +  // If we have 1 && X, just emit X without inserting the control flow. +  bool LHSCondVal; +  if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { +    if (LHSCondVal) { // If we have 1 && X, just emit X. +      CGF.incrementProfileCounter(E); + +      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); +      // ZExt result to int or bool. +      return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext"); +    } + +    // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. +    if (!CGF.ContainsLabel(E->getRHS())) +      return llvm::Constant::getNullValue(ResTy); +  } + +  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end"); +  llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs"); + +  CodeGenFunction::ConditionalEvaluation eval(CGF); + +  // Branch on the LHS first.  If it is false, go to the failure (cont) block. +  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock, +                           CGF.getProfileCount(E->getRHS())); + +  // Any edges into the ContBlock are now from an (indeterminate number of) +  // edges from this first condition.  All of these values will be false.  Start +  // setting up the PHI node in the Cont Block for this. +  llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2, +                                            "", ContBlock); +  for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock); +       PI != PE; ++PI) +    PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI); + +  eval.begin(CGF); +  CGF.EmitBlock(RHSBlock); +  CGF.incrementProfileCounter(E); +  Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); +  eval.end(CGF); + +  // Reaquire the RHS block, as there may be subblocks inserted. +  RHSBlock = Builder.GetInsertBlock(); + +  // Emit an unconditional branch from this block to ContBlock. +  { +    // There is no need to emit line number for unconditional branch. +    auto NL = ApplyDebugLocation::CreateEmpty(CGF); +    CGF.EmitBlock(ContBlock); +  } +  // Insert an entry into the phi node for the edge with the value of RHSCond. +  PN->addIncoming(RHSCond, RHSBlock); + +  // Artificial location to preserve the scope information +  { +    auto NL = ApplyDebugLocation::CreateArtificial(CGF); +    PN->setDebugLoc(Builder.getCurrentDebugLocation()); +  } + +  // ZExt result to int. +  return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext"); +} + +Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { +  // Perform vector logical or on comparisons with zero vectors. +  if (E->getType()->isVectorType()) { +    CGF.incrementProfileCounter(E); + +    Value *LHS = Visit(E->getLHS()); +    Value *RHS = Visit(E->getRHS()); +    Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); +    if (LHS->getType()->isFPOrFPVectorTy()) { +      LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); +      RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); +    } else { +      LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp"); +      RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp"); +    } +    Value *Or = Builder.CreateOr(LHS, RHS); +    return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext"); +  } + +  llvm::Type *ResTy = ConvertType(E->getType()); + +  // If we have 1 || RHS, see if we can elide RHS, if so, just return 1. +  // If we have 0 || X, just emit X without inserting the control flow. +  bool LHSCondVal; +  if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { +    if (!LHSCondVal) { // If we have 0 || X, just emit X. +      CGF.incrementProfileCounter(E); + +      Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); +      // ZExt result to int or bool. +      return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext"); +    } + +    // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. +    if (!CGF.ContainsLabel(E->getRHS())) +      return llvm::ConstantInt::get(ResTy, 1); +  } + +  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end"); +  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs"); + +  CodeGenFunction::ConditionalEvaluation eval(CGF); + +  // Branch on the LHS first.  If it is true, go to the success (cont) block. +  CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock, +                           CGF.getCurrentProfileCount() - +                               CGF.getProfileCount(E->getRHS())); + +  // Any edges into the ContBlock are now from an (indeterminate number of) +  // edges from this first condition.  All of these values will be true.  Start +  // setting up the PHI node in the Cont Block for this. +  llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2, +                                            "", ContBlock); +  for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock); +       PI != PE; ++PI) +    PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI); + +  eval.begin(CGF); + +  // Emit the RHS condition as a bool value. +  CGF.EmitBlock(RHSBlock); +  CGF.incrementProfileCounter(E); +  Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); + +  eval.end(CGF); + +  // Reaquire the RHS block, as there may be subblocks inserted. +  RHSBlock = Builder.GetInsertBlock(); + +  // Emit an unconditional branch from this block to ContBlock.  Insert an entry +  // into the phi node for the edge with the value of RHSCond. +  CGF.EmitBlock(ContBlock); +  PN->addIncoming(RHSCond, RHSBlock); + +  // ZExt result to int. +  return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext"); +} + +Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) { +  CGF.EmitIgnoredExpr(E->getLHS()); +  CGF.EnsureInsertPoint(); +  return Visit(E->getRHS()); +} + +//===----------------------------------------------------------------------===// +//                             Other Operators +//===----------------------------------------------------------------------===// + +/// isCheapEnoughToEvaluateUnconditionally - Return true if the specified +/// expression is cheap enough and side-effect-free enough to evaluate +/// unconditionally instead of conditionally.  This is used to convert control +/// flow into selects in some cases. +static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E, +                                                   CodeGenFunction &CGF) { +  // Anything that is an integer or floating point constant is fine. +  return E->IgnoreParens()->isEvaluatable(CGF.getContext()); + +  // Even non-volatile automatic variables can't be evaluated unconditionally. +  // Referencing a thread_local may cause non-trivial initialization work to +  // occur. If we're inside a lambda and one of the variables is from the scope +  // outside the lambda, that function may have returned already. Reading its +  // locals is a bad idea. Also, these reads may introduce races there didn't +  // exist in the source-level program. +} + + +Value *ScalarExprEmitter:: +VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { +  TestAndClearIgnoreResultAssign(); + +  // Bind the common expression if necessary. +  CodeGenFunction::OpaqueValueMapping binding(CGF, E); + +  Expr *condExpr = E->getCond(); +  Expr *lhsExpr = E->getTrueExpr(); +  Expr *rhsExpr = E->getFalseExpr(); + +  // If the condition constant folds and can be elided, try to avoid emitting +  // the condition and the dead arm. +  bool CondExprBool; +  if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) { +    Expr *live = lhsExpr, *dead = rhsExpr; +    if (!CondExprBool) std::swap(live, dead); + +    // If the dead side doesn't have labels we need, just emit the Live part. +    if (!CGF.ContainsLabel(dead)) { +      if (CondExprBool) +        CGF.incrementProfileCounter(E); +      Value *Result = Visit(live); + +      // If the live part is a throw expression, it acts like it has a void +      // type, so evaluating it returns a null Value*.  However, a conditional +      // with non-void type must return a non-null Value*. +      if (!Result && !E->getType()->isVoidType()) +        Result = llvm::UndefValue::get(CGF.ConvertType(E->getType())); + +      return Result; +    } +  } + +  // OpenCL: If the condition is a vector, we can treat this condition like +  // the select function. +  if (CGF.getLangOpts().OpenCL +      && condExpr->getType()->isVectorType()) { +    CGF.incrementProfileCounter(E); + +    llvm::Value *CondV = CGF.EmitScalarExpr(condExpr); +    llvm::Value *LHS = Visit(lhsExpr); +    llvm::Value *RHS = Visit(rhsExpr); + +    llvm::Type *condType = ConvertType(condExpr->getType()); +    llvm::VectorType *vecTy = cast<llvm::VectorType>(condType); + +    unsigned numElem = vecTy->getNumElements(); +    llvm::Type *elemType = vecTy->getElementType(); + +    llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy); +    llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec); +    llvm::Value *tmp = Builder.CreateSExt(TestMSB, +                                          llvm::VectorType::get(elemType, +                                                                numElem), +                                          "sext"); +    llvm::Value *tmp2 = Builder.CreateNot(tmp); + +    // Cast float to int to perform ANDs if necessary. +    llvm::Value *RHSTmp = RHS; +    llvm::Value *LHSTmp = LHS; +    bool wasCast = false; +    llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType()); +    if (rhsVTy->getElementType()->isFloatingPointTy()) { +      RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType()); +      LHSTmp = Builder.CreateBitCast(LHS, tmp->getType()); +      wasCast = true; +    } + +    llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2); +    llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp); +    llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond"); +    if (wasCast) +      tmp5 = Builder.CreateBitCast(tmp5, RHS->getType()); + +    return tmp5; +  } + +  // If this is a really simple expression (like x ? 4 : 5), emit this as a +  // select instead of as control flow.  We can only do this if it is cheap and +  // safe to evaluate the LHS and RHS unconditionally. +  if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) && +      isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) { +    llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr); +    llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty); + +    CGF.incrementProfileCounter(E, StepV); + +    llvm::Value *LHS = Visit(lhsExpr); +    llvm::Value *RHS = Visit(rhsExpr); +    if (!LHS) { +      // If the conditional has void type, make sure we return a null Value*. +      assert(!RHS && "LHS and RHS types must match"); +      return nullptr; +    } +    return Builder.CreateSelect(CondV, LHS, RHS, "cond"); +  } + +  llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); +  llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); +  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); + +  CodeGenFunction::ConditionalEvaluation eval(CGF); +  CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock, +                           CGF.getProfileCount(lhsExpr)); + +  CGF.EmitBlock(LHSBlock); +  CGF.incrementProfileCounter(E); +  eval.begin(CGF); +  Value *LHS = Visit(lhsExpr); +  eval.end(CGF); + +  LHSBlock = Builder.GetInsertBlock(); +  Builder.CreateBr(ContBlock); + +  CGF.EmitBlock(RHSBlock); +  eval.begin(CGF); +  Value *RHS = Visit(rhsExpr); +  eval.end(CGF); + +  RHSBlock = Builder.GetInsertBlock(); +  CGF.EmitBlock(ContBlock); + +  // If the LHS or RHS is a throw expression, it will be legitimately null. +  if (!LHS) +    return RHS; +  if (!RHS) +    return LHS; + +  // Create a PHI node for the real part. +  llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond"); +  PN->addIncoming(LHS, LHSBlock); +  PN->addIncoming(RHS, RHSBlock); +  return PN; +} + +Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) { +  return Visit(E->getChosenSubExpr()); +} + +Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { +  QualType Ty = VE->getType(); + +  if (Ty->isVariablyModifiedType()) +    CGF.EmitVariablyModifiedType(Ty); + +  Address ArgValue = Address::invalid(); +  Address ArgPtr = CGF.EmitVAArg(VE, ArgValue); + +  llvm::Type *ArgTy = ConvertType(VE->getType()); + +  // If EmitVAArg fails, emit an error. +  if (!ArgPtr.isValid()) { +    CGF.ErrorUnsupported(VE, "va_arg expression"); +    return llvm::UndefValue::get(ArgTy); +  } + +  // FIXME Volatility. +  llvm::Value *Val = Builder.CreateLoad(ArgPtr); + +  // If EmitVAArg promoted the type, we must truncate it. +  if (ArgTy != Val->getType()) { +    if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy()) +      Val = Builder.CreateIntToPtr(Val, ArgTy); +    else +      Val = Builder.CreateTrunc(Val, ArgTy); +  } + +  return Val; +} + +Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) { +  return CGF.EmitBlockLiteral(block); +} + +// Convert a vec3 to vec4, or vice versa. +static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, +                                 Value *Src, unsigned NumElementsDst) { +  llvm::Value *UnV = llvm::UndefValue::get(Src->getType()); +  SmallVector<llvm::Constant*, 4> Args; +  Args.push_back(Builder.getInt32(0)); +  Args.push_back(Builder.getInt32(1)); +  Args.push_back(Builder.getInt32(2)); +  if (NumElementsDst == 4) +    Args.push_back(llvm::UndefValue::get(CGF.Int32Ty)); +  llvm::Constant *Mask = llvm::ConstantVector::get(Args); +  return Builder.CreateShuffleVector(Src, UnV, Mask); +} + +// Create cast instructions for converting LLVM value \p Src to LLVM type \p +// DstTy. \p Src has the same size as \p DstTy. Both are single value types +// but could be scalar or vectors of different lengths, and either can be +// pointer. +// There are 4 cases: +// 1. non-pointer -> non-pointer  : needs 1 bitcast +// 2. pointer -> pointer          : needs 1 bitcast or addrspacecast +// 3. pointer -> non-pointer +//   a) pointer -> intptr_t       : needs 1 ptrtoint +//   b) pointer -> non-intptr_t   : needs 1 ptrtoint then 1 bitcast +// 4. non-pointer -> pointer +//   a) intptr_t -> pointer       : needs 1 inttoptr +//   b) non-intptr_t -> pointer   : needs 1 bitcast then 1 inttoptr +// Note: for cases 3b and 4b two casts are required since LLVM casts do not +// allow casting directly between pointer types and non-integer non-pointer +// types. +static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder, +                                           const llvm::DataLayout &DL, +                                           Value *Src, llvm::Type *DstTy, +                                           StringRef Name = "") { +  auto SrcTy = Src->getType(); + +  // Case 1. +  if (!SrcTy->isPointerTy() && !DstTy->isPointerTy()) +    return Builder.CreateBitCast(Src, DstTy, Name); + +  // Case 2. +  if (SrcTy->isPointerTy() && DstTy->isPointerTy()) +    return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name); + +  // Case 3. +  if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) { +    // Case 3b. +    if (!DstTy->isIntegerTy()) +      Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy)); +    // Cases 3a and 3b. +    return Builder.CreateBitOrPointerCast(Src, DstTy, Name); +  } + +  // Case 4b. +  if (!SrcTy->isIntegerTy()) +    Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy)); +  // Cases 4a and 4b. +  return Builder.CreateIntToPtr(Src, DstTy, Name); +} + +Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) { +  Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr()); +  llvm::Type *DstTy = ConvertType(E->getType()); + +  llvm::Type *SrcTy = Src->getType(); +  unsigned NumElementsSrc = isa<llvm::VectorType>(SrcTy) ? +    cast<llvm::VectorType>(SrcTy)->getNumElements() : 0; +  unsigned NumElementsDst = isa<llvm::VectorType>(DstTy) ? +    cast<llvm::VectorType>(DstTy)->getNumElements() : 0; + +  // Going from vec3 to non-vec3 is a special case and requires a shuffle +  // vector to get a vec4, then a bitcast if the target type is different. +  if (NumElementsSrc == 3 && NumElementsDst != 3) { +    Src = ConvertVec3AndVec4(Builder, CGF, Src, 4); + +    if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) { +      Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, +                                         DstTy); +    } + +    Src->setName("astype"); +    return Src; +  } + +  // Going from non-vec3 to vec3 is a special case and requires a bitcast +  // to vec4 if the original type is not vec4, then a shuffle vector to +  // get a vec3. +  if (NumElementsSrc != 3 && NumElementsDst == 3) { +    if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) { +      auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4); +      Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, +                                         Vec4Ty); +    } + +    Src = ConvertVec3AndVec4(Builder, CGF, Src, 3); +    Src->setName("astype"); +    return Src; +  } + +  return createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), +                                      Src, DstTy, "astype"); +} + +Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) { +  return CGF.EmitAtomicExpr(E).getScalarVal(); +} + +//===----------------------------------------------------------------------===// +//                         Entry Point into this File +//===----------------------------------------------------------------------===// + +/// Emit the computation of the specified expression of scalar type, ignoring +/// the result. +Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) { +  assert(E && hasScalarEvaluationKind(E->getType()) && +         "Invalid scalar expression to emit"); + +  return ScalarExprEmitter(*this, IgnoreResultAssign) +      .Visit(const_cast<Expr *>(E)); +} + +/// Emit a conversion from the specified type to the specified destination type, +/// both of which are LLVM scalar types. +Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy, +                                             QualType DstTy, +                                             SourceLocation Loc) { +  assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) && +         "Invalid scalar expression to emit"); +  return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc); +} + +/// Emit a conversion from the specified complex type to the specified +/// destination type, where the destination type is an LLVM scalar type. +Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src, +                                                      QualType SrcTy, +                                                      QualType DstTy, +                                                      SourceLocation Loc) { +  assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) && +         "Invalid complex -> scalar conversion"); +  return ScalarExprEmitter(*this) +      .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc); +} + + +llvm::Value *CodeGenFunction:: +EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, +                        bool isInc, bool isPre) { +  return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre); +} + +LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) { +  // object->isa or (*object).isa +  // Generate code as for: *(Class*)object + +  Expr *BaseExpr = E->getBase(); +  Address Addr = Address::invalid(); +  if (BaseExpr->isRValue()) { +    Addr = Address(EmitScalarExpr(BaseExpr), getPointerAlign()); +  } else { +    Addr = EmitLValue(BaseExpr).getAddress(); +  } + +  // Cast the address to Class*. +  Addr = Builder.CreateElementBitCast(Addr, ConvertType(E->getType())); +  return MakeAddrLValue(Addr, E->getType()); +} + + +LValue CodeGenFunction::EmitCompoundAssignmentLValue( +                                            const CompoundAssignOperator *E) { +  ScalarExprEmitter Scalar(*this); +  Value *Result = nullptr; +  switch (E->getOpcode()) { +#define COMPOUND_OP(Op)                                                       \ +    case BO_##Op##Assign:                                                     \ +      return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \ +                                             Result) +  COMPOUND_OP(Mul); +  COMPOUND_OP(Div); +  COMPOUND_OP(Rem); +  COMPOUND_OP(Add); +  COMPOUND_OP(Sub); +  COMPOUND_OP(Shl); +  COMPOUND_OP(Shr); +  COMPOUND_OP(And); +  COMPOUND_OP(Xor); +  COMPOUND_OP(Or); +#undef COMPOUND_OP + +  case BO_PtrMemD: +  case BO_PtrMemI: +  case BO_Mul: +  case BO_Div: +  case BO_Rem: +  case BO_Add: +  case BO_Sub: +  case BO_Shl: +  case BO_Shr: +  case BO_LT: +  case BO_GT: +  case BO_LE: +  case BO_GE: +  case BO_EQ: +  case BO_NE: +  case BO_Cmp: +  case BO_And: +  case BO_Xor: +  case BO_Or: +  case BO_LAnd: +  case BO_LOr: +  case BO_Assign: +  case BO_Comma: +    llvm_unreachable("Not valid compound assignment operators"); +  } + +  llvm_unreachable("Unhandled compound assignment operator"); +} + +struct GEPOffsetAndOverflow { +  // The total (signed) byte offset for the GEP. +  llvm::Value *TotalOffset; +  // The offset overflow flag - true if the total offset overflows. +  llvm::Value *OffsetOverflows; +}; + +/// Evaluate given GEPVal, which is either an inbounds GEP, or a constant, +/// and compute the total offset it applies from it's base pointer BasePtr. +/// Returns offset in bytes and a boolean flag whether an overflow happened +/// during evaluation. +static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, +                                                 llvm::LLVMContext &VMContext, +                                                 CodeGenModule &CGM, +                                                 CGBuilderTy Builder) { +  const auto &DL = CGM.getDataLayout(); + +  // The total (signed) byte offset for the GEP. +  llvm::Value *TotalOffset = nullptr; + +  // Was the GEP already reduced to a constant? +  if (isa<llvm::Constant>(GEPVal)) { +    // Compute the offset by casting both pointers to integers and subtracting: +    // GEPVal = BasePtr + ptr(Offset) <--> Offset = int(GEPVal) - int(BasePtr) +    Value *BasePtr_int = +        Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType())); +    Value *GEPVal_int = +        Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType())); +    TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int); +    return {TotalOffset, /*OffsetOverflows=*/Builder.getFalse()}; +  } + +  auto *GEP = cast<llvm::GEPOperator>(GEPVal); +  assert(GEP->getPointerOperand() == BasePtr && +         "BasePtr must be the the base of the GEP."); +  assert(GEP->isInBounds() && "Expected inbounds GEP"); + +  auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType()); + +  // Grab references to the signed add/mul overflow intrinsics for intptr_t. +  auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy); +  auto *SAddIntrinsic = +      CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy); +  auto *SMulIntrinsic = +      CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy); + +  // The offset overflow flag - true if the total offset overflows. +  llvm::Value *OffsetOverflows = Builder.getFalse(); + +  /// Return the result of the given binary operation. +  auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS, +                  llvm::Value *RHS) -> llvm::Value * { +    assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop"); + +    // If the operands are constants, return a constant result. +    if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) { +      if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) { +        llvm::APInt N; +        bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode, +                                                  /*Signed=*/true, N); +        if (HasOverflow) +          OffsetOverflows = Builder.getTrue(); +        return llvm::ConstantInt::get(VMContext, N); +      } +    } + +    // Otherwise, compute the result with checked arithmetic. +    auto *ResultAndOverflow = Builder.CreateCall( +        (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS}); +    OffsetOverflows = Builder.CreateOr( +        Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows); +    return Builder.CreateExtractValue(ResultAndOverflow, 0); +  }; + +  // Determine the total byte offset by looking at each GEP operand. +  for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP); +       GTI != GTE; ++GTI) { +    llvm::Value *LocalOffset; +    auto *Index = GTI.getOperand(); +    // Compute the local offset contributed by this indexing step: +    if (auto *STy = GTI.getStructTypeOrNull()) { +      // For struct indexing, the local offset is the byte position of the +      // specified field. +      unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue(); +      LocalOffset = llvm::ConstantInt::get( +          IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo)); +    } else { +      // Otherwise this is array-like indexing. The local offset is the index +      // multiplied by the element size. +      auto *ElementSize = llvm::ConstantInt::get( +          IntPtrTy, DL.getTypeAllocSize(GTI.getIndexedType())); +      auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true); +      LocalOffset = eval(BO_Mul, ElementSize, IndexS); +    } + +    // If this is the first offset, set it as the total offset. Otherwise, add +    // the local offset into the running total. +    if (!TotalOffset || TotalOffset == Zero) +      TotalOffset = LocalOffset; +    else +      TotalOffset = eval(BO_Add, TotalOffset, LocalOffset); +  } + +  return {TotalOffset, OffsetOverflows}; +} + +Value * +CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList, +                                        bool SignedIndices, bool IsSubtraction, +                                        SourceLocation Loc, const Twine &Name) { +  Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name); + +  // If the pointer overflow sanitizer isn't enabled, do nothing. +  if (!SanOpts.has(SanitizerKind::PointerOverflow)) +    return GEPVal; + +  llvm::Type *PtrTy = Ptr->getType(); + +  // Perform nullptr-and-offset check unless the nullptr is defined. +  bool PerformNullCheck = !NullPointerIsDefined( +      Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace()); +  // Check for overflows unless the GEP got constant-folded, +  // and only in the default address space +  bool PerformOverflowCheck = +      !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0; + +  if (!(PerformNullCheck || PerformOverflowCheck)) +    return GEPVal; + +  const auto &DL = CGM.getDataLayout(); + +  SanitizerScope SanScope(this); +  llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy); + +  GEPOffsetAndOverflow EvaluatedGEP = +      EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder); + +  assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) || +          EvaluatedGEP.OffsetOverflows == Builder.getFalse()) && +         "If the offset got constant-folded, we don't expect that there was an " +         "overflow."); + +  auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy); + +  // Common case: if the total offset is zero, and we are using C++ semantics, +  // where nullptr+0 is defined, don't emit a check. +  if (EvaluatedGEP.TotalOffset == Zero && CGM.getLangOpts().CPlusPlus) +    return GEPVal; + +  // Now that we've computed the total offset, add it to the base pointer (with +  // wrapping semantics). +  auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy); +  auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset); + +  llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; + +  if (PerformNullCheck) { +    // In C++, if the base pointer evaluates to a null pointer value, +    // the only valid  pointer this inbounds GEP can produce is also +    // a null pointer, so the offset must also evaluate to zero. +    // Likewise, if we have non-zero base pointer, we can not get null pointer +    // as a result, so the offset can not be -intptr_t(BasePtr). +    // In other words, both pointers are either null, or both are non-null, +    // or the behaviour is undefined. +    // +    // C, however, is more strict in this regard, and gives more +    // optimization opportunities: in C, additionally, nullptr+0 is undefined. +    // So both the input to the 'gep inbounds' AND the output must not be null. +    auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr); +    auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP); +    auto *Valid = +        CGM.getLangOpts().CPlusPlus +            ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr) +            : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr); +    Checks.emplace_back(Valid, SanitizerKind::PointerOverflow); +  } + +  if (PerformOverflowCheck) { +    // The GEP is valid if: +    // 1) The total offset doesn't overflow, and +    // 2) The sign of the difference between the computed address and the base +    // pointer matches the sign of the total offset. +    llvm::Value *ValidGEP; +    auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.OffsetOverflows); +    if (SignedIndices) { +      // GEP is computed as `unsigned base + signed offset`, therefore: +      // * If offset was positive, then the computed pointer can not be +      //   [unsigned] less than the base pointer, unless it overflowed. +      // * If offset was negative, then the computed pointer can not be +      //   [unsigned] greater than the bas pointere, unless it overflowed. +      auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr); +      auto *PosOrZeroOffset = +          Builder.CreateICmpSGE(EvaluatedGEP.TotalOffset, Zero); +      llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr); +      ValidGEP = +          Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid); +    } else if (!IsSubtraction) { +      // GEP is computed as `unsigned base + unsigned offset`,  therefore the +      // computed pointer can not be [unsigned] less than base pointer, +      // unless there was an overflow. +      // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`. +      ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr); +    } else { +      // GEP is computed as `unsigned base - unsigned offset`, therefore the +      // computed pointer can not be [unsigned] greater than base pointer, +      // unless there was an overflow. +      // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`. +      ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr); +    } +    ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow); +    Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow); +  } + +  assert(!Checks.empty() && "Should have produced some checks."); + +  llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)}; +  // Pass the computed GEP to the runtime to avoid emitting poisoned arguments. +  llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP}; +  EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs); + +  return GEPVal; +}  | 
