xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp (revision 6e516c87b6d779911edde7481d8aef165b837a03)
10b57cec5SDimitry Andric //===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CGCXXABI.h"
140b57cec5SDimitry Andric #include "CGCleanup.h"
150b57cec5SDimitry Andric #include "CGDebugInfo.h"
160b57cec5SDimitry Andric #include "CGObjCRuntime.h"
17480093f4SDimitry Andric #include "CGOpenMPRuntime.h"
180fca6ea1SDimitry Andric #include "CGRecordLayout.h"
190b57cec5SDimitry Andric #include "CodeGenFunction.h"
200b57cec5SDimitry Andric #include "CodeGenModule.h"
210b57cec5SDimitry Andric #include "ConstantEmitter.h"
220b57cec5SDimitry Andric #include "TargetInfo.h"
230b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
24480093f4SDimitry Andric #include "clang/AST/Attr.h"
250b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
260b57cec5SDimitry Andric #include "clang/AST/Expr.h"
270b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
280b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
290b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
300b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
31e8d8bef9SDimitry Andric #include "llvm/ADT/APFixedPoint.h"
320b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
330b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
340b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
3581ad6265SDimitry Andric #include "llvm/IR/DerivedTypes.h"
36e8d8bef9SDimitry Andric #include "llvm/IR/FixedPointBuilder.h"
370b57cec5SDimitry Andric #include "llvm/IR/Function.h"
380b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
390b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
400b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
41480093f4SDimitry Andric #include "llvm/IR/IntrinsicsPowerPC.h"
425ffd83dbSDimitry Andric #include "llvm/IR/MatrixBuilder.h"
430b57cec5SDimitry Andric #include "llvm/IR/Module.h"
4481ad6265SDimitry Andric #include "llvm/Support/TypeSize.h"
450b57cec5SDimitry Andric #include <cstdarg>
46bdd1243dSDimitry Andric #include <optional>
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric using namespace clang;
490b57cec5SDimitry Andric using namespace CodeGen;
500b57cec5SDimitry Andric using llvm::Value;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
530b57cec5SDimitry Andric //                         Scalar Expression Emitter
540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
550b57cec5SDimitry Andric 
560fca6ea1SDimitry Andric namespace llvm {
570fca6ea1SDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage;
580fca6ea1SDimitry Andric } // namespace llvm
590fca6ea1SDimitry Andric 
600b57cec5SDimitry Andric namespace {
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric /// Determine whether the given binary operation may overflow.
630b57cec5SDimitry Andric /// Sets \p Result to the value of the operation for BO_Add, BO_Sub, BO_Mul,
640b57cec5SDimitry Andric /// and signed BO_{Div,Rem}. For these opcodes, and for unsigned BO_{Div,Rem},
650b57cec5SDimitry Andric /// the returned overflow check is precise. The returned value is 'true' for
660b57cec5SDimitry Andric /// all other opcodes, to be conservative.
mayHaveIntegerOverflow(llvm::ConstantInt * LHS,llvm::ConstantInt * RHS,BinaryOperator::Opcode Opcode,bool Signed,llvm::APInt & Result)670b57cec5SDimitry Andric bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
680b57cec5SDimitry Andric                              BinaryOperator::Opcode Opcode, bool Signed,
690b57cec5SDimitry Andric                              llvm::APInt &Result) {
700b57cec5SDimitry Andric   // Assume overflow is possible, unless we can prove otherwise.
710b57cec5SDimitry Andric   bool Overflow = true;
720b57cec5SDimitry Andric   const auto &LHSAP = LHS->getValue();
730b57cec5SDimitry Andric   const auto &RHSAP = RHS->getValue();
740b57cec5SDimitry Andric   if (Opcode == BO_Add) {
7581ad6265SDimitry Andric     Result = Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
7681ad6265SDimitry Andric                     : LHSAP.uadd_ov(RHSAP, Overflow);
770b57cec5SDimitry Andric   } else if (Opcode == BO_Sub) {
7881ad6265SDimitry Andric     Result = Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
7981ad6265SDimitry Andric                     : LHSAP.usub_ov(RHSAP, Overflow);
800b57cec5SDimitry Andric   } else if (Opcode == BO_Mul) {
8181ad6265SDimitry Andric     Result = Signed ? LHSAP.smul_ov(RHSAP, Overflow)
8281ad6265SDimitry Andric                     : LHSAP.umul_ov(RHSAP, Overflow);
830b57cec5SDimitry Andric   } else if (Opcode == BO_Div || Opcode == BO_Rem) {
840b57cec5SDimitry Andric     if (Signed && !RHS->isZero())
850b57cec5SDimitry Andric       Result = LHSAP.sdiv_ov(RHSAP, Overflow);
860b57cec5SDimitry Andric     else
870b57cec5SDimitry Andric       return false;
880b57cec5SDimitry Andric   }
890b57cec5SDimitry Andric   return Overflow;
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric struct BinOpInfo {
930b57cec5SDimitry Andric   Value *LHS;
940b57cec5SDimitry Andric   Value *RHS;
950b57cec5SDimitry Andric   QualType Ty;  // Computation Type.
960b57cec5SDimitry Andric   BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
970b57cec5SDimitry Andric   FPOptions FPFeatures;
980b57cec5SDimitry Andric   const Expr *E;      // Entire expr, for error unsupported.  May not be binop.
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   /// Check if the binop can result in integer overflow.
mayHaveIntegerOverflow__anone7cacfbd0111::BinOpInfo1010b57cec5SDimitry Andric   bool mayHaveIntegerOverflow() const {
1020b57cec5SDimitry Andric     // Without constant input, we can't rule out overflow.
1030b57cec5SDimitry Andric     auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
1040b57cec5SDimitry Andric     auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
1050b57cec5SDimitry Andric     if (!LHSCI || !RHSCI)
1060b57cec5SDimitry Andric       return true;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric     llvm::APInt Result;
1090b57cec5SDimitry Andric     return ::mayHaveIntegerOverflow(
1100b57cec5SDimitry Andric         LHSCI, RHSCI, Opcode, Ty->hasSignedIntegerRepresentation(), Result);
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   /// Check if the binop computes a division or a remainder.
isDivremOp__anone7cacfbd0111::BinOpInfo1140b57cec5SDimitry Andric   bool isDivremOp() const {
1150b57cec5SDimitry Andric     return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
1160b57cec5SDimitry Andric            Opcode == BO_RemAssign;
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   /// Check if the binop can result in an integer division by zero.
mayHaveIntegerDivisionByZero__anone7cacfbd0111::BinOpInfo1200b57cec5SDimitry Andric   bool mayHaveIntegerDivisionByZero() const {
1210b57cec5SDimitry Andric     if (isDivremOp())
1220b57cec5SDimitry Andric       if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
1230b57cec5SDimitry Andric         return CI->isZero();
1240b57cec5SDimitry Andric     return true;
1250b57cec5SDimitry Andric   }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   /// Check if the binop can result in a float division by zero.
mayHaveFloatDivisionByZero__anone7cacfbd0111::BinOpInfo1280b57cec5SDimitry Andric   bool mayHaveFloatDivisionByZero() const {
1290b57cec5SDimitry Andric     if (isDivremOp())
1300b57cec5SDimitry Andric       if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
1310b57cec5SDimitry Andric         return CFP->isZero();
1320b57cec5SDimitry Andric     return true;
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric 
1355ffd83dbSDimitry Andric   /// Check if at least one operand is a fixed point type. In such cases, this
1365ffd83dbSDimitry Andric   /// operation did not follow usual arithmetic conversion and both operands
1375ffd83dbSDimitry Andric   /// might not be of the same type.
isFixedPointOp__anone7cacfbd0111::BinOpInfo1385ffd83dbSDimitry Andric   bool isFixedPointOp() const {
1390b57cec5SDimitry Andric     // We cannot simply check the result type since comparison operations return
1400b57cec5SDimitry Andric     // an int.
1410b57cec5SDimitry Andric     if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
1420b57cec5SDimitry Andric       QualType LHSType = BinOp->getLHS()->getType();
1430b57cec5SDimitry Andric       QualType RHSType = BinOp->getRHS()->getType();
1440b57cec5SDimitry Andric       return LHSType->isFixedPointType() || RHSType->isFixedPointType();
1450b57cec5SDimitry Andric     }
1465ffd83dbSDimitry Andric     if (const auto *UnOp = dyn_cast<UnaryOperator>(E))
1475ffd83dbSDimitry Andric       return UnOp->getSubExpr()->getType()->isFixedPointType();
1480b57cec5SDimitry Andric     return false;
1490b57cec5SDimitry Andric   }
1500fca6ea1SDimitry Andric 
1510fca6ea1SDimitry Andric   /// Check if the RHS has a signed integer representation.
rhsHasSignedIntegerRepresentation__anone7cacfbd0111::BinOpInfo1520fca6ea1SDimitry Andric   bool rhsHasSignedIntegerRepresentation() const {
1530fca6ea1SDimitry Andric     if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
1540fca6ea1SDimitry Andric       QualType RHSType = BinOp->getRHS()->getType();
1550fca6ea1SDimitry Andric       return RHSType->hasSignedIntegerRepresentation();
1560fca6ea1SDimitry Andric     }
1570fca6ea1SDimitry Andric     return false;
1580fca6ea1SDimitry Andric   }
1590b57cec5SDimitry Andric };
1600b57cec5SDimitry Andric 
MustVisitNullValue(const Expr * E)1610b57cec5SDimitry Andric static bool MustVisitNullValue(const Expr *E) {
1620b57cec5SDimitry Andric   // If a null pointer expression's type is the C++0x nullptr_t, then
1630b57cec5SDimitry Andric   // it's not necessarily a simple constant and it must be evaluated
1640b57cec5SDimitry Andric   // for its potential side effects.
1650b57cec5SDimitry Andric   return E->getType()->isNullPtrType();
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric /// If \p E is a widened promoted integer, get its base (unpromoted) type.
getUnwidenedIntegerType(const ASTContext & Ctx,const Expr * E)169bdd1243dSDimitry Andric static std::optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
1700b57cec5SDimitry Andric                                                        const Expr *E) {
1710b57cec5SDimitry Andric   const Expr *Base = E->IgnoreImpCasts();
1720b57cec5SDimitry Andric   if (E == Base)
173bdd1243dSDimitry Andric     return std::nullopt;
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   QualType BaseTy = Base->getType();
176bdd1243dSDimitry Andric   if (!Ctx.isPromotableIntegerType(BaseTy) ||
1770b57cec5SDimitry Andric       Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
178bdd1243dSDimitry Andric     return std::nullopt;
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   return BaseTy;
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric /// Check if \p E is a widened promoted integer.
IsWidenedIntegerOp(const ASTContext & Ctx,const Expr * E)1840b57cec5SDimitry Andric static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
18581ad6265SDimitry Andric   return getUnwidenedIntegerType(Ctx, E).has_value();
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric /// Check if we can skip the overflow check for \p Op.
CanElideOverflowCheck(const ASTContext & Ctx,const BinOpInfo & Op)1890b57cec5SDimitry Andric static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
1900b57cec5SDimitry Andric   assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
1910b57cec5SDimitry Andric          "Expected a unary or binary operator");
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   // If the binop has constant inputs and we can prove there is no overflow,
1940b57cec5SDimitry Andric   // we can elide the overflow check.
1950b57cec5SDimitry Andric   if (!Op.mayHaveIntegerOverflow())
1960b57cec5SDimitry Andric     return true;
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   // If a unary op has a widened operand, the op cannot overflow.
1990b57cec5SDimitry Andric   if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
2000b57cec5SDimitry Andric     return !UO->canOverflow();
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   // We usually don't need overflow checks for binops with widened operands.
2030b57cec5SDimitry Andric   // Multiplication with promoted unsigned operands is a special case.
2040b57cec5SDimitry Andric   const auto *BO = cast<BinaryOperator>(Op.E);
2050b57cec5SDimitry Andric   auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
2060b57cec5SDimitry Andric   if (!OptionalLHSTy)
2070b57cec5SDimitry Andric     return false;
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
2100b57cec5SDimitry Andric   if (!OptionalRHSTy)
2110b57cec5SDimitry Andric     return false;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   QualType LHSTy = *OptionalLHSTy;
2140b57cec5SDimitry Andric   QualType RHSTy = *OptionalRHSTy;
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   // This is the simple case: binops without unsigned multiplication, and with
2170b57cec5SDimitry Andric   // widened operands. No overflow check is needed here.
2180b57cec5SDimitry Andric   if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
2190b57cec5SDimitry Andric       !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
2200b57cec5SDimitry Andric     return true;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   // For unsigned multiplication the overflow check can be elided if either one
2230b57cec5SDimitry Andric   // of the unpromoted types are less than half the size of the promoted type.
2240b57cec5SDimitry Andric   unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
2250b57cec5SDimitry Andric   return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
2260b57cec5SDimitry Andric          (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric class ScalarExprEmitter
2300b57cec5SDimitry Andric   : public StmtVisitor<ScalarExprEmitter, Value*> {
2310b57cec5SDimitry Andric   CodeGenFunction &CGF;
2320b57cec5SDimitry Andric   CGBuilderTy &Builder;
2330b57cec5SDimitry Andric   bool IgnoreResultAssign;
2340b57cec5SDimitry Andric   llvm::LLVMContext &VMContext;
2350b57cec5SDimitry Andric public:
2360b57cec5SDimitry Andric 
ScalarExprEmitter(CodeGenFunction & cgf,bool ira=false)2370b57cec5SDimitry Andric   ScalarExprEmitter(CodeGenFunction &cgf, bool ira=false)
2380b57cec5SDimitry Andric     : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
2390b57cec5SDimitry Andric       VMContext(cgf.getLLVMContext()) {
2400b57cec5SDimitry Andric   }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
2430b57cec5SDimitry Andric   //                               Utilities
2440b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
2450b57cec5SDimitry Andric 
TestAndClearIgnoreResultAssign()2460b57cec5SDimitry Andric   bool TestAndClearIgnoreResultAssign() {
2470b57cec5SDimitry Andric     bool I = IgnoreResultAssign;
2480b57cec5SDimitry Andric     IgnoreResultAssign = false;
2490b57cec5SDimitry Andric     return I;
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
ConvertType(QualType T)2520b57cec5SDimitry Andric   llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
EmitLValue(const Expr * E)2530b57cec5SDimitry Andric   LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
EmitCheckedLValue(const Expr * E,CodeGenFunction::TypeCheckKind TCK)2540b57cec5SDimitry Andric   LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
2550b57cec5SDimitry Andric     return CGF.EmitCheckedLValue(E, TCK);
2560b57cec5SDimitry Andric   }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   void EmitBinOpCheck(ArrayRef<std::pair<Value *, SanitizerMask>> Checks,
2590b57cec5SDimitry Andric                       const BinOpInfo &Info);
2600b57cec5SDimitry Andric 
EmitLoadOfLValue(LValue LV,SourceLocation Loc)2610b57cec5SDimitry Andric   Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
2620b57cec5SDimitry Andric     return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
EmitLValueAlignmentAssumption(const Expr * E,Value * V)2650b57cec5SDimitry Andric   void EmitLValueAlignmentAssumption(const Expr *E, Value *V) {
2660b57cec5SDimitry Andric     const AlignValueAttr *AVAttr = nullptr;
2670b57cec5SDimitry Andric     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
2680b57cec5SDimitry Andric       const ValueDecl *VD = DRE->getDecl();
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric       if (VD->getType()->isReferenceType()) {
2710b57cec5SDimitry Andric         if (const auto *TTy =
272bdd1243dSDimitry Andric                 VD->getType().getNonReferenceType()->getAs<TypedefType>())
2730b57cec5SDimitry Andric           AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
2740b57cec5SDimitry Andric       } else {
2750b57cec5SDimitry Andric         // Assumptions for function parameters are emitted at the start of the
2760b57cec5SDimitry Andric         // function, so there is no need to repeat that here,
2770b57cec5SDimitry Andric         // unless the alignment-assumption sanitizer is enabled,
2780b57cec5SDimitry Andric         // then we prefer the assumption over alignment attribute
2790b57cec5SDimitry Andric         // on IR function param.
2800b57cec5SDimitry Andric         if (isa<ParmVarDecl>(VD) && !CGF.SanOpts.has(SanitizerKind::Alignment))
2810b57cec5SDimitry Andric           return;
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric         AVAttr = VD->getAttr<AlignValueAttr>();
2840b57cec5SDimitry Andric       }
2850b57cec5SDimitry Andric     }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric     if (!AVAttr)
288bdd1243dSDimitry Andric       if (const auto *TTy = E->getType()->getAs<TypedefType>())
2890b57cec5SDimitry Andric         AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric     if (!AVAttr)
2920b57cec5SDimitry Andric       return;
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric     Value *AlignmentValue = CGF.EmitScalarExpr(AVAttr->getAlignment());
2950b57cec5SDimitry Andric     llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(AlignmentValue);
2965ffd83dbSDimitry Andric     CGF.emitAlignmentAssumption(V, E, AVAttr->getLocation(), AlignmentCI);
2970b57cec5SDimitry Andric   }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   /// EmitLoadOfLValue - Given an expression with complex type that represents a
3000b57cec5SDimitry Andric   /// value l-value, this method emits the address of the l-value, then loads
3010b57cec5SDimitry Andric   /// and returns the result.
EmitLoadOfLValue(const Expr * E)3020b57cec5SDimitry Andric   Value *EmitLoadOfLValue(const Expr *E) {
3030b57cec5SDimitry Andric     Value *V = EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load),
3040b57cec5SDimitry Andric                                 E->getExprLoc());
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric     EmitLValueAlignmentAssumption(E, V);
3070b57cec5SDimitry Andric     return V;
3080b57cec5SDimitry Andric   }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   /// EmitConversionToBool - Convert the specified expression value to a
3110b57cec5SDimitry Andric   /// boolean (i1) truth value.  This is equivalent to "Val != 0".
3120b57cec5SDimitry Andric   Value *EmitConversionToBool(Value *Src, QualType DstTy);
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   /// Emit a check that a conversion from a floating-point type does not
3150b57cec5SDimitry Andric   /// overflow.
3160b57cec5SDimitry Andric   void EmitFloatConversionCheck(Value *OrigSrc, QualType OrigSrcType,
3170b57cec5SDimitry Andric                                 Value *Src, QualType SrcType, QualType DstType,
3180b57cec5SDimitry Andric                                 llvm::Type *DstTy, SourceLocation Loc);
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   /// Known implicit conversion check kinds.
3210fca6ea1SDimitry Andric   /// This is used for bitfield conversion checks as well.
3220b57cec5SDimitry Andric   /// Keep in sync with the enum of the same name in ubsan_handlers.h
3230b57cec5SDimitry Andric   enum ImplicitConversionCheckKind : unsigned char {
3240b57cec5SDimitry Andric     ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
3250b57cec5SDimitry Andric     ICCK_UnsignedIntegerTruncation = 1,
3260b57cec5SDimitry Andric     ICCK_SignedIntegerTruncation = 2,
3270b57cec5SDimitry Andric     ICCK_IntegerSignChange = 3,
3280b57cec5SDimitry Andric     ICCK_SignedIntegerTruncationOrSignChange = 4,
3290b57cec5SDimitry Andric   };
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   /// Emit a check that an [implicit] truncation of an integer  does not
3320b57cec5SDimitry Andric   /// discard any bits. It is not UB, so we use the value after truncation.
3330b57cec5SDimitry Andric   void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst,
3340b57cec5SDimitry Andric                                   QualType DstType, SourceLocation Loc);
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   /// Emit a check that an [implicit] conversion of an integer does not change
3370b57cec5SDimitry Andric   /// the sign of the value. It is not UB, so we use the value after conversion.
3380b57cec5SDimitry Andric   /// NOTE: Src and Dst may be the exact same value! (point to the same thing)
3390b57cec5SDimitry Andric   void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
3400b57cec5SDimitry Andric                                   QualType DstType, SourceLocation Loc);
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   /// Emit a conversion from the specified type to the specified destination
3430b57cec5SDimitry Andric   /// type, both of which are LLVM scalar types.
3440b57cec5SDimitry Andric   struct ScalarConversionOpts {
3450b57cec5SDimitry Andric     bool TreatBooleanAsSigned;
3460b57cec5SDimitry Andric     bool EmitImplicitIntegerTruncationChecks;
3470b57cec5SDimitry Andric     bool EmitImplicitIntegerSignChangeChecks;
3480b57cec5SDimitry Andric 
ScalarConversionOpts__anone7cacfbd0111::ScalarExprEmitter::ScalarConversionOpts3490b57cec5SDimitry Andric     ScalarConversionOpts()
3500b57cec5SDimitry Andric         : TreatBooleanAsSigned(false),
3510b57cec5SDimitry Andric           EmitImplicitIntegerTruncationChecks(false),
3520b57cec5SDimitry Andric           EmitImplicitIntegerSignChangeChecks(false) {}
3530b57cec5SDimitry Andric 
ScalarConversionOpts__anone7cacfbd0111::ScalarExprEmitter::ScalarConversionOpts3540b57cec5SDimitry Andric     ScalarConversionOpts(clang::SanitizerSet SanOpts)
3550b57cec5SDimitry Andric         : TreatBooleanAsSigned(false),
3560b57cec5SDimitry Andric           EmitImplicitIntegerTruncationChecks(
3570b57cec5SDimitry Andric               SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
3580b57cec5SDimitry Andric           EmitImplicitIntegerSignChangeChecks(
3590b57cec5SDimitry Andric               SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) {}
3600b57cec5SDimitry Andric   };
361fe6060f1SDimitry Andric   Value *EmitScalarCast(Value *Src, QualType SrcType, QualType DstType,
362fe6060f1SDimitry Andric                         llvm::Type *SrcTy, llvm::Type *DstTy,
363fe6060f1SDimitry Andric                         ScalarConversionOpts Opts);
3640b57cec5SDimitry Andric   Value *
3650b57cec5SDimitry Andric   EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
3660b57cec5SDimitry Andric                        SourceLocation Loc,
3670b57cec5SDimitry Andric                        ScalarConversionOpts Opts = ScalarConversionOpts());
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   /// Convert between either a fixed point and other fixed point or fixed point
3700b57cec5SDimitry Andric   /// and an integer.
3710b57cec5SDimitry Andric   Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy,
3720b57cec5SDimitry Andric                                   SourceLocation Loc);
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric   /// Emit a conversion from the specified complex type to the specified
3750b57cec5SDimitry Andric   /// destination type, where the destination type is an LLVM scalar type.
3760b57cec5SDimitry Andric   Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
3770b57cec5SDimitry Andric                                        QualType SrcTy, QualType DstTy,
3780b57cec5SDimitry Andric                                        SourceLocation Loc);
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   /// EmitNullValue - Emit a value that corresponds to null for the given type.
3810b57cec5SDimitry Andric   Value *EmitNullValue(QualType Ty);
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   /// EmitFloatToBoolConversion - Perform an FP to boolean conversion.
EmitFloatToBoolConversion(Value * V)3840b57cec5SDimitry Andric   Value *EmitFloatToBoolConversion(Value *V) {
3850b57cec5SDimitry Andric     // Compare against 0.0 for fp scalars.
3860b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(V->getType());
3870b57cec5SDimitry Andric     return Builder.CreateFCmpUNE(V, Zero, "tobool");
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   /// EmitPointerToBoolConversion - Perform a pointer to boolean conversion.
EmitPointerToBoolConversion(Value * V,QualType QT)3910b57cec5SDimitry Andric   Value *EmitPointerToBoolConversion(Value *V, QualType QT) {
3920b57cec5SDimitry Andric     Value *Zero = CGF.CGM.getNullPointer(cast<llvm::PointerType>(V->getType()), QT);
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric     return Builder.CreateICmpNE(V, Zero, "tobool");
3950b57cec5SDimitry Andric   }
3960b57cec5SDimitry Andric 
EmitIntToBoolConversion(Value * V)3970b57cec5SDimitry Andric   Value *EmitIntToBoolConversion(Value *V) {
3980b57cec5SDimitry Andric     // Because of the type rules of C, we often end up computing a
3990b57cec5SDimitry Andric     // logical value, then zero extending it to int, then wanting it
4000b57cec5SDimitry Andric     // as a logical value again.  Optimize this common case.
4010b57cec5SDimitry Andric     if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(V)) {
4020b57cec5SDimitry Andric       if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
4030b57cec5SDimitry Andric         Value *Result = ZI->getOperand(0);
4040b57cec5SDimitry Andric         // If there aren't any more uses, zap the instruction to save space.
4050b57cec5SDimitry Andric         // Note that there can be more uses, for example if this
4060b57cec5SDimitry Andric         // is the result of an assignment.
4070b57cec5SDimitry Andric         if (ZI->use_empty())
4080b57cec5SDimitry Andric           ZI->eraseFromParent();
4090b57cec5SDimitry Andric         return Result;
4100b57cec5SDimitry Andric       }
4110b57cec5SDimitry Andric     }
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric     return Builder.CreateIsNotNull(V, "tobool");
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
4170b57cec5SDimitry Andric   //                            Visitor Methods
4180b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
4190b57cec5SDimitry Andric 
Visit(Expr * E)4200b57cec5SDimitry Andric   Value *Visit(Expr *E) {
4210b57cec5SDimitry Andric     ApplyDebugLocation DL(CGF, E);
4220b57cec5SDimitry Andric     return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
4230b57cec5SDimitry Andric   }
4240b57cec5SDimitry Andric 
VisitStmt(Stmt * S)4250b57cec5SDimitry Andric   Value *VisitStmt(Stmt *S) {
4265ffd83dbSDimitry Andric     S->dump(llvm::errs(), CGF.getContext());
4270b57cec5SDimitry Andric     llvm_unreachable("Stmt can't have complex result type!");
4280b57cec5SDimitry Andric   }
4290b57cec5SDimitry Andric   Value *VisitExpr(Expr *S);
4300b57cec5SDimitry Andric 
VisitConstantExpr(ConstantExpr * E)4310b57cec5SDimitry Andric   Value *VisitConstantExpr(ConstantExpr *E) {
432349cc55cSDimitry Andric     // A constant expression of type 'void' generates no code and produces no
433349cc55cSDimitry Andric     // value.
434349cc55cSDimitry Andric     if (E->getType()->isVoidType())
435349cc55cSDimitry Andric       return nullptr;
436349cc55cSDimitry Andric 
4375ffd83dbSDimitry Andric     if (Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
4385ffd83dbSDimitry Andric       if (E->isGLValue())
4390fca6ea1SDimitry Andric         return CGF.EmitLoadOfScalar(
4400fca6ea1SDimitry Andric             Address(Result, CGF.convertTypeForLoadStore(E->getType()),
4410fca6ea1SDimitry Andric                     CGF.getContext().getTypeAlignInChars(E->getType())),
4420fca6ea1SDimitry Andric             /*Volatile*/ false, E->getType(), E->getExprLoc());
4435ffd83dbSDimitry Andric       return Result;
4445ffd83dbSDimitry Andric     }
4450b57cec5SDimitry Andric     return Visit(E->getSubExpr());
4460b57cec5SDimitry Andric   }
VisitParenExpr(ParenExpr * PE)4470b57cec5SDimitry Andric   Value *VisitParenExpr(ParenExpr *PE) {
4480b57cec5SDimitry Andric     return Visit(PE->getSubExpr());
4490b57cec5SDimitry Andric   }
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)4500b57cec5SDimitry Andric   Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
4510b57cec5SDimitry Andric     return Visit(E->getReplacement());
4520b57cec5SDimitry Andric   }
VisitGenericSelectionExpr(GenericSelectionExpr * GE)4530b57cec5SDimitry Andric   Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
4540b57cec5SDimitry Andric     return Visit(GE->getResultExpr());
4550b57cec5SDimitry Andric   }
VisitCoawaitExpr(CoawaitExpr * S)4560b57cec5SDimitry Andric   Value *VisitCoawaitExpr(CoawaitExpr *S) {
4570b57cec5SDimitry Andric     return CGF.EmitCoawaitExpr(*S).getScalarVal();
4580b57cec5SDimitry Andric   }
VisitCoyieldExpr(CoyieldExpr * S)4590b57cec5SDimitry Andric   Value *VisitCoyieldExpr(CoyieldExpr *S) {
4600b57cec5SDimitry Andric     return CGF.EmitCoyieldExpr(*S).getScalarVal();
4610b57cec5SDimitry Andric   }
VisitUnaryCoawait(const UnaryOperator * E)4620b57cec5SDimitry Andric   Value *VisitUnaryCoawait(const UnaryOperator *E) {
4630b57cec5SDimitry Andric     return Visit(E->getSubExpr());
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   // Leaves.
VisitIntegerLiteral(const IntegerLiteral * E)4670b57cec5SDimitry Andric   Value *VisitIntegerLiteral(const IntegerLiteral *E) {
4680b57cec5SDimitry Andric     return Builder.getInt(E->getValue());
4690b57cec5SDimitry Andric   }
VisitFixedPointLiteral(const FixedPointLiteral * E)4700b57cec5SDimitry Andric   Value *VisitFixedPointLiteral(const FixedPointLiteral *E) {
4710b57cec5SDimitry Andric     return Builder.getInt(E->getValue());
4720b57cec5SDimitry Andric   }
VisitFloatingLiteral(const FloatingLiteral * E)4730b57cec5SDimitry Andric   Value *VisitFloatingLiteral(const FloatingLiteral *E) {
4740b57cec5SDimitry Andric     return llvm::ConstantFP::get(VMContext, E->getValue());
4750b57cec5SDimitry Andric   }
VisitCharacterLiteral(const CharacterLiteral * E)4760b57cec5SDimitry Andric   Value *VisitCharacterLiteral(const CharacterLiteral *E) {
4770b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4780b57cec5SDimitry Andric   }
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * E)4790b57cec5SDimitry Andric   Value *VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
4800b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4810b57cec5SDimitry Andric   }
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * E)4820b57cec5SDimitry Andric   Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
4830b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
4840b57cec5SDimitry Andric   }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)4850b57cec5SDimitry Andric   Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
486bdd1243dSDimitry Andric     if (E->getType()->isVoidType())
487bdd1243dSDimitry Andric       return nullptr;
488bdd1243dSDimitry Andric 
4890b57cec5SDimitry Andric     return EmitNullValue(E->getType());
4900b57cec5SDimitry Andric   }
VisitGNUNullExpr(const GNUNullExpr * E)4910b57cec5SDimitry Andric   Value *VisitGNUNullExpr(const GNUNullExpr *E) {
4920b57cec5SDimitry Andric     return EmitNullValue(E->getType());
4930b57cec5SDimitry Andric   }
4940b57cec5SDimitry Andric   Value *VisitOffsetOfExpr(OffsetOfExpr *E);
4950b57cec5SDimitry Andric   Value *VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
VisitAddrLabelExpr(const AddrLabelExpr * E)4960b57cec5SDimitry Andric   Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
4970b57cec5SDimitry Andric     llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
4980b57cec5SDimitry Andric     return Builder.CreateBitCast(V, ConvertType(E->getType()));
4990b57cec5SDimitry Andric   }
5000b57cec5SDimitry Andric 
VisitSizeOfPackExpr(SizeOfPackExpr * E)5010b57cec5SDimitry Andric   Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
5020b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()),E->getPackLength());
5030b57cec5SDimitry Andric   }
5040b57cec5SDimitry Andric 
VisitPseudoObjectExpr(PseudoObjectExpr * E)5050b57cec5SDimitry Andric   Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
5060b57cec5SDimitry Andric     return CGF.EmitPseudoObjectRValue(E).getScalarVal();
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
509fe6060f1SDimitry Andric   Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
5100fca6ea1SDimitry Andric   Value *VisitEmbedExpr(EmbedExpr *E);
511fe6060f1SDimitry Andric 
VisitOpaqueValueExpr(OpaqueValueExpr * E)5120b57cec5SDimitry Andric   Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
5130b57cec5SDimitry Andric     if (E->isGLValue())
5140b57cec5SDimitry Andric       return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E),
5150b57cec5SDimitry Andric                               E->getExprLoc());
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric     // Otherwise, assume the mapping is the scalar directly.
5180b57cec5SDimitry Andric     return CGF.getOrCreateOpaqueRValueMapping(E).getScalarVal();
5190b57cec5SDimitry Andric   }
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   // l-values.
VisitDeclRefExpr(DeclRefExpr * E)5220b57cec5SDimitry Andric   Value *VisitDeclRefExpr(DeclRefExpr *E) {
5230b57cec5SDimitry Andric     if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
5240b57cec5SDimitry Andric       return CGF.emitScalarConstant(Constant, E);
5250b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
5260b57cec5SDimitry Andric   }
5270b57cec5SDimitry Andric 
VisitObjCSelectorExpr(ObjCSelectorExpr * E)5280b57cec5SDimitry Andric   Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
5290b57cec5SDimitry Andric     return CGF.EmitObjCSelectorExpr(E);
5300b57cec5SDimitry Andric   }
VisitObjCProtocolExpr(ObjCProtocolExpr * E)5310b57cec5SDimitry Andric   Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
5320b57cec5SDimitry Andric     return CGF.EmitObjCProtocolExpr(E);
5330b57cec5SDimitry Andric   }
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)5340b57cec5SDimitry Andric   Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
5350b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
5360b57cec5SDimitry Andric   }
VisitObjCMessageExpr(ObjCMessageExpr * E)5370b57cec5SDimitry Andric   Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
5380b57cec5SDimitry Andric     if (E->getMethodDecl() &&
5390b57cec5SDimitry Andric         E->getMethodDecl()->getReturnType()->isReferenceType())
5400b57cec5SDimitry Andric       return EmitLoadOfLValue(E);
5410b57cec5SDimitry Andric     return CGF.EmitObjCMessageExpr(E).getScalarVal();
5420b57cec5SDimitry Andric   }
5430b57cec5SDimitry Andric 
VisitObjCIsaExpr(ObjCIsaExpr * E)5440b57cec5SDimitry Andric   Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
5450b57cec5SDimitry Andric     LValue LV = CGF.EmitObjCIsaExpr(E);
5460b57cec5SDimitry Andric     Value *V = CGF.EmitLoadOfLValue(LV, E->getExprLoc()).getScalarVal();
5470b57cec5SDimitry Andric     return V;
5480b57cec5SDimitry Andric   }
5490b57cec5SDimitry Andric 
VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * E)5500b57cec5SDimitry Andric   Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
5510b57cec5SDimitry Andric     VersionTuple Version = E->getVersion();
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric     // If we're checking for a platform older than our minimum deployment
5540b57cec5SDimitry Andric     // target, we can fold the check away.
5550b57cec5SDimitry Andric     if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
5560b57cec5SDimitry Andric       return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
5570b57cec5SDimitry Andric 
558e8d8bef9SDimitry Andric     return CGF.EmitBuiltinAvailable(Version);
5590b57cec5SDimitry Andric   }
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
5625ffd83dbSDimitry Andric   Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
5630b57cec5SDimitry Andric   Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
5640b57cec5SDimitry Andric   Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
5650b57cec5SDimitry Andric   Value *VisitMemberExpr(MemberExpr *E);
VisitExtVectorElementExpr(Expr * E)5660b57cec5SDimitry Andric   Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)5670b57cec5SDimitry Andric   Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
5685ffd83dbSDimitry Andric     // Strictly speaking, we shouldn't be calling EmitLoadOfLValue, which
5695ffd83dbSDimitry Andric     // transitively calls EmitCompoundLiteralLValue, here in C++ since compound
5705ffd83dbSDimitry Andric     // literals aren't l-values in C++. We do so simply because that's the
5715ffd83dbSDimitry Andric     // cleanest way to handle compound literals in C++.
5725ffd83dbSDimitry Andric     // See the discussion here: https://reviews.llvm.org/D64464
5730b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
5740b57cec5SDimitry Andric   }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   Value *VisitInitListExpr(InitListExpr *E);
5770b57cec5SDimitry Andric 
VisitArrayInitIndexExpr(ArrayInitIndexExpr * E)5780b57cec5SDimitry Andric   Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
5790b57cec5SDimitry Andric     assert(CGF.getArrayInitIndex() &&
5800b57cec5SDimitry Andric            "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
5810b57cec5SDimitry Andric     return CGF.getArrayInitIndex();
5820b57cec5SDimitry Andric   }
5830b57cec5SDimitry Andric 
VisitImplicitValueInitExpr(const ImplicitValueInitExpr * E)5840b57cec5SDimitry Andric   Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
5850b57cec5SDimitry Andric     return EmitNullValue(E->getType());
5860b57cec5SDimitry Andric   }
VisitExplicitCastExpr(ExplicitCastExpr * E)5870b57cec5SDimitry Andric   Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
5880b57cec5SDimitry Andric     CGF.CGM.EmitExplicitCastExprType(E, &CGF);
5890b57cec5SDimitry Andric     return VisitCastExpr(E);
5900b57cec5SDimitry Andric   }
5910b57cec5SDimitry Andric   Value *VisitCastExpr(CastExpr *E);
5920b57cec5SDimitry Andric 
VisitCallExpr(const CallExpr * E)5930b57cec5SDimitry Andric   Value *VisitCallExpr(const CallExpr *E) {
5940b57cec5SDimitry Andric     if (E->getCallReturnType(CGF.getContext())->isReferenceType())
5950b57cec5SDimitry Andric       return EmitLoadOfLValue(E);
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric     Value *V = CGF.EmitCallExpr(E).getScalarVal();
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric     EmitLValueAlignmentAssumption(E, V);
6000b57cec5SDimitry Andric     return V;
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   Value *VisitStmtExpr(const StmtExpr *E);
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric   // Unary Operators.
VisitUnaryPostDec(const UnaryOperator * E)6060b57cec5SDimitry Andric   Value *VisitUnaryPostDec(const UnaryOperator *E) {
6070b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
6080b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, false, false);
6090b57cec5SDimitry Andric   }
VisitUnaryPostInc(const UnaryOperator * E)6100b57cec5SDimitry Andric   Value *VisitUnaryPostInc(const UnaryOperator *E) {
6110b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
6120b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, true, false);
6130b57cec5SDimitry Andric   }
VisitUnaryPreDec(const UnaryOperator * E)6140b57cec5SDimitry Andric   Value *VisitUnaryPreDec(const UnaryOperator *E) {
6150b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
6160b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, false, true);
6170b57cec5SDimitry Andric   }
VisitUnaryPreInc(const UnaryOperator * E)6180b57cec5SDimitry Andric   Value *VisitUnaryPreInc(const UnaryOperator *E) {
6190b57cec5SDimitry Andric     LValue LV = EmitLValue(E->getSubExpr());
6200b57cec5SDimitry Andric     return EmitScalarPrePostIncDec(E, LV, true, true);
6210b57cec5SDimitry Andric   }
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   llvm::Value *EmitIncDecConsiderOverflowBehavior(const UnaryOperator *E,
6240b57cec5SDimitry Andric                                                   llvm::Value *InVal,
6250b57cec5SDimitry Andric                                                   bool IsInc);
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
6280b57cec5SDimitry Andric                                        bool isInc, bool isPre);
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric 
VisitUnaryAddrOf(const UnaryOperator * E)6310b57cec5SDimitry Andric   Value *VisitUnaryAddrOf(const UnaryOperator *E) {
6320b57cec5SDimitry Andric     if (isa<MemberPointerType>(E->getType())) // never sugared
6330b57cec5SDimitry Andric       return CGF.CGM.getMemberPointerConstant(E);
6340b57cec5SDimitry Andric 
635480093f4SDimitry Andric     return EmitLValue(E->getSubExpr()).getPointer(CGF);
6360b57cec5SDimitry Andric   }
VisitUnaryDeref(const UnaryOperator * E)6370b57cec5SDimitry Andric   Value *VisitUnaryDeref(const UnaryOperator *E) {
6380b57cec5SDimitry Andric     if (E->getType()->isVoidType())
6390b57cec5SDimitry Andric       return Visit(E->getSubExpr()); // the actual value should be unused
6400b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
6410b57cec5SDimitry Andric   }
642bdd1243dSDimitry Andric 
643bdd1243dSDimitry Andric   Value *VisitUnaryPlus(const UnaryOperator *E,
644bdd1243dSDimitry Andric                         QualType PromotionType = QualType());
645bdd1243dSDimitry Andric   Value *VisitPlus(const UnaryOperator *E, QualType PromotionType);
646bdd1243dSDimitry Andric   Value *VisitUnaryMinus(const UnaryOperator *E,
647bdd1243dSDimitry Andric                          QualType PromotionType = QualType());
648bdd1243dSDimitry Andric   Value *VisitMinus(const UnaryOperator *E, QualType PromotionType);
649bdd1243dSDimitry Andric 
6500b57cec5SDimitry Andric   Value *VisitUnaryNot      (const UnaryOperator *E);
6510b57cec5SDimitry Andric   Value *VisitUnaryLNot     (const UnaryOperator *E);
652bdd1243dSDimitry Andric   Value *VisitUnaryReal(const UnaryOperator *E,
653bdd1243dSDimitry Andric                         QualType PromotionType = QualType());
654bdd1243dSDimitry Andric   Value *VisitReal(const UnaryOperator *E, QualType PromotionType);
655bdd1243dSDimitry Andric   Value *VisitUnaryImag(const UnaryOperator *E,
656bdd1243dSDimitry Andric                         QualType PromotionType = QualType());
657bdd1243dSDimitry Andric   Value *VisitImag(const UnaryOperator *E, QualType PromotionType);
VisitUnaryExtension(const UnaryOperator * E)6580b57cec5SDimitry Andric   Value *VisitUnaryExtension(const UnaryOperator *E) {
6590b57cec5SDimitry Andric     return Visit(E->getSubExpr());
6600b57cec5SDimitry Andric   }
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   // C++
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * E)6630b57cec5SDimitry Andric   Value *VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E) {
6640b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
6650b57cec5SDimitry Andric   }
VisitSourceLocExpr(SourceLocExpr * SLE)6660b57cec5SDimitry Andric   Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
6670b57cec5SDimitry Andric     auto &Ctx = CGF.getContext();
6680b57cec5SDimitry Andric     APValue Evaluated =
6690b57cec5SDimitry Andric         SLE->EvaluateInContext(Ctx, CGF.CurSourceLocExprScope.getDefaultExpr());
670480093f4SDimitry Andric     return ConstantEmitter(CGF).emitAbstract(SLE->getLocation(), Evaluated,
671480093f4SDimitry Andric                                              SLE->getType());
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)6740b57cec5SDimitry Andric   Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
6750b57cec5SDimitry Andric     CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
6760b57cec5SDimitry Andric     return Visit(DAE->getExpr());
6770b57cec5SDimitry Andric   }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)6780b57cec5SDimitry Andric   Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
6790b57cec5SDimitry Andric     CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
6800b57cec5SDimitry Andric     return Visit(DIE->getExpr());
6810b57cec5SDimitry Andric   }
VisitCXXThisExpr(CXXThisExpr * TE)6820b57cec5SDimitry Andric   Value *VisitCXXThisExpr(CXXThisExpr *TE) {
6830b57cec5SDimitry Andric     return CGF.LoadCXXThis();
6840b57cec5SDimitry Andric   }
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric   Value *VisitExprWithCleanups(ExprWithCleanups *E);
VisitCXXNewExpr(const CXXNewExpr * E)6870b57cec5SDimitry Andric   Value *VisitCXXNewExpr(const CXXNewExpr *E) {
6880b57cec5SDimitry Andric     return CGF.EmitCXXNewExpr(E);
6890b57cec5SDimitry Andric   }
VisitCXXDeleteExpr(const CXXDeleteExpr * E)6900b57cec5SDimitry Andric   Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
6910b57cec5SDimitry Andric     CGF.EmitCXXDeleteExpr(E);
6920b57cec5SDimitry Andric     return nullptr;
6930b57cec5SDimitry Andric   }
6940b57cec5SDimitry Andric 
VisitTypeTraitExpr(const TypeTraitExpr * E)6950b57cec5SDimitry Andric   Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
6960b57cec5SDimitry Andric     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
6970b57cec5SDimitry Andric   }
6980b57cec5SDimitry Andric 
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * E)699a7dea167SDimitry Andric   Value *VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) {
700a7dea167SDimitry Andric     return Builder.getInt1(E->isSatisfied());
701a7dea167SDimitry Andric   }
702a7dea167SDimitry Andric 
VisitRequiresExpr(const RequiresExpr * E)70355e4f9d5SDimitry Andric   Value *VisitRequiresExpr(const RequiresExpr *E) {
70455e4f9d5SDimitry Andric     return Builder.getInt1(E->isSatisfied());
70555e4f9d5SDimitry Andric   }
70655e4f9d5SDimitry Andric 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)7070b57cec5SDimitry Andric   Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
7080b57cec5SDimitry Andric     return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
7090b57cec5SDimitry Andric   }
7100b57cec5SDimitry Andric 
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)7110b57cec5SDimitry Andric   Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
7120b57cec5SDimitry Andric     return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
7130b57cec5SDimitry Andric   }
7140b57cec5SDimitry Andric 
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)7150b57cec5SDimitry Andric   Value *VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E) {
7160b57cec5SDimitry Andric     // C++ [expr.pseudo]p1:
7170b57cec5SDimitry Andric     //   The result shall only be used as the operand for the function call
7180b57cec5SDimitry Andric     //   operator (), and the result of such a call has type void. The only
7190b57cec5SDimitry Andric     //   effect is the evaluation of the postfix-expression before the dot or
7200b57cec5SDimitry Andric     //   arrow.
7210b57cec5SDimitry Andric     CGF.EmitScalarExpr(E->getBase());
7220b57cec5SDimitry Andric     return nullptr;
7230b57cec5SDimitry Andric   }
7240b57cec5SDimitry Andric 
VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr * E)7250b57cec5SDimitry Andric   Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
7260b57cec5SDimitry Andric     return EmitNullValue(E->getType());
7270b57cec5SDimitry Andric   }
7280b57cec5SDimitry Andric 
VisitCXXThrowExpr(const CXXThrowExpr * E)7290b57cec5SDimitry Andric   Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
7300b57cec5SDimitry Andric     CGF.EmitCXXThrowExpr(E);
7310b57cec5SDimitry Andric     return nullptr;
7320b57cec5SDimitry Andric   }
7330b57cec5SDimitry Andric 
VisitCXXNoexceptExpr(const CXXNoexceptExpr * E)7340b57cec5SDimitry Andric   Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
7350b57cec5SDimitry Andric     return Builder.getInt1(E->getValue());
7360b57cec5SDimitry Andric   }
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric   // Binary Operators.
EmitMul(const BinOpInfo & Ops)7390b57cec5SDimitry Andric   Value *EmitMul(const BinOpInfo &Ops) {
7400b57cec5SDimitry Andric     if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
7410b57cec5SDimitry Andric       switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
7420b57cec5SDimitry Andric       case LangOptions::SOB_Defined:
7430fca6ea1SDimitry Andric         if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
7440b57cec5SDimitry Andric           return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
7450fca6ea1SDimitry Andric         [[fallthrough]];
7460b57cec5SDimitry Andric       case LangOptions::SOB_Undefined:
7470b57cec5SDimitry Andric         if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
7480b57cec5SDimitry Andric           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
749bdd1243dSDimitry Andric         [[fallthrough]];
7500b57cec5SDimitry Andric       case LangOptions::SOB_Trapping:
7510b57cec5SDimitry Andric         if (CanElideOverflowCheck(CGF.getContext(), Ops))
7520b57cec5SDimitry Andric           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
7530b57cec5SDimitry Andric         return EmitOverflowCheckedBinOp(Ops);
7540b57cec5SDimitry Andric       }
7550b57cec5SDimitry Andric     }
7560b57cec5SDimitry Andric 
7575ffd83dbSDimitry Andric     if (Ops.Ty->isConstantMatrixType()) {
75881ad6265SDimitry Andric       llvm::MatrixBuilder MB(Builder);
7595ffd83dbSDimitry Andric       // We need to check the types of the operands of the operator to get the
7605ffd83dbSDimitry Andric       // correct matrix dimensions.
7615ffd83dbSDimitry Andric       auto *BO = cast<BinaryOperator>(Ops.E);
7625ffd83dbSDimitry Andric       auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
7635ffd83dbSDimitry Andric           BO->getLHS()->getType().getCanonicalType());
7645ffd83dbSDimitry Andric       auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
7655ffd83dbSDimitry Andric           BO->getRHS()->getType().getCanonicalType());
766fe6060f1SDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
7675ffd83dbSDimitry Andric       if (LHSMatTy && RHSMatTy)
7685ffd83dbSDimitry Andric         return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
7695ffd83dbSDimitry Andric                                        LHSMatTy->getNumColumns(),
7705ffd83dbSDimitry Andric                                        RHSMatTy->getNumColumns());
7715ffd83dbSDimitry Andric       return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
7725ffd83dbSDimitry Andric     }
7735ffd83dbSDimitry Andric 
7740b57cec5SDimitry Andric     if (Ops.Ty->isUnsignedIntegerType() &&
7750b57cec5SDimitry Andric         CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
7760b57cec5SDimitry Andric         !CanElideOverflowCheck(CGF.getContext(), Ops))
7770b57cec5SDimitry Andric       return EmitOverflowCheckedBinOp(Ops);
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric     if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
7805ffd83dbSDimitry Andric       //  Preserve the old values
7815ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
7825ffd83dbSDimitry Andric       return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
7830b57cec5SDimitry Andric     }
7845ffd83dbSDimitry Andric     if (Ops.isFixedPointOp())
7855ffd83dbSDimitry Andric       return EmitFixedPointBinOp(Ops);
7860b57cec5SDimitry Andric     return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric   /// Create a binary op that checks for overflow.
7890b57cec5SDimitry Andric   /// Currently only supports +, - and *.
7900b57cec5SDimitry Andric   Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric   // Check for undefined division and modulus behaviors.
7930b57cec5SDimitry Andric   void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops,
7940b57cec5SDimitry Andric                                                   llvm::Value *Zero,bool isDiv);
7950b57cec5SDimitry Andric   // Common helper for getting how wide LHS of shift is.
7960fca6ea1SDimitry Andric   static Value *GetMaximumShiftAmount(Value *LHS, Value *RHS, bool RHSIsSigned);
7975ffd83dbSDimitry Andric 
7985ffd83dbSDimitry Andric   // Used for shifting constraints for OpenCL, do mask for powers of 2, URem for
7995ffd83dbSDimitry Andric   // non powers of two.
8005ffd83dbSDimitry Andric   Value *ConstrainShiftValue(Value *LHS, Value *RHS, const Twine &Name);
8015ffd83dbSDimitry Andric 
8020b57cec5SDimitry Andric   Value *EmitDiv(const BinOpInfo &Ops);
8030b57cec5SDimitry Andric   Value *EmitRem(const BinOpInfo &Ops);
8040b57cec5SDimitry Andric   Value *EmitAdd(const BinOpInfo &Ops);
8050b57cec5SDimitry Andric   Value *EmitSub(const BinOpInfo &Ops);
8060b57cec5SDimitry Andric   Value *EmitShl(const BinOpInfo &Ops);
8070b57cec5SDimitry Andric   Value *EmitShr(const BinOpInfo &Ops);
EmitAnd(const BinOpInfo & Ops)8080b57cec5SDimitry Andric   Value *EmitAnd(const BinOpInfo &Ops) {
8090b57cec5SDimitry Andric     return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
8100b57cec5SDimitry Andric   }
EmitXor(const BinOpInfo & Ops)8110b57cec5SDimitry Andric   Value *EmitXor(const BinOpInfo &Ops) {
8120b57cec5SDimitry Andric     return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
8130b57cec5SDimitry Andric   }
EmitOr(const BinOpInfo & Ops)8140b57cec5SDimitry Andric   Value *EmitOr (const BinOpInfo &Ops) {
8150b57cec5SDimitry Andric     return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
8160b57cec5SDimitry Andric   }
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   // Helper functions for fixed point binary operations.
8190b57cec5SDimitry Andric   Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
8200b57cec5SDimitry Andric 
821bdd1243dSDimitry Andric   BinOpInfo EmitBinOps(const BinaryOperator *E,
822bdd1243dSDimitry Andric                        QualType PromotionTy = QualType());
823bdd1243dSDimitry Andric 
824bdd1243dSDimitry Andric   Value *EmitPromotedValue(Value *result, QualType PromotionType);
825bdd1243dSDimitry Andric   Value *EmitUnPromotedValue(Value *result, QualType ExprType);
826bdd1243dSDimitry Andric   Value *EmitPromoted(const Expr *E, QualType PromotionType);
827bdd1243dSDimitry Andric 
8280b57cec5SDimitry Andric   LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
8290b57cec5SDimitry Andric                             Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
8300b57cec5SDimitry Andric                                   Value *&Result);
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric   Value *EmitCompoundAssign(const CompoundAssignOperator *E,
8330b57cec5SDimitry Andric                             Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
8340b57cec5SDimitry Andric 
getPromotionType(QualType Ty)835bdd1243dSDimitry Andric   QualType getPromotionType(QualType Ty) {
83606c3fb27SDimitry Andric     const auto &Ctx = CGF.getContext();
837bdd1243dSDimitry Andric     if (auto *CT = Ty->getAs<ComplexType>()) {
838bdd1243dSDimitry Andric       QualType ElementType = CT->getElementType();
83906c3fb27SDimitry Andric       if (ElementType.UseExcessPrecision(Ctx))
84006c3fb27SDimitry Andric         return Ctx.getComplexType(Ctx.FloatTy);
841bdd1243dSDimitry Andric     }
84206c3fb27SDimitry Andric 
84306c3fb27SDimitry Andric     if (Ty.UseExcessPrecision(Ctx)) {
84406c3fb27SDimitry Andric       if (auto *VT = Ty->getAs<VectorType>()) {
84506c3fb27SDimitry Andric         unsigned NumElements = VT->getNumElements();
84606c3fb27SDimitry Andric         return Ctx.getVectorType(Ctx.FloatTy, NumElements, VT->getVectorKind());
84706c3fb27SDimitry Andric       }
84806c3fb27SDimitry Andric       return Ctx.FloatTy;
84906c3fb27SDimitry Andric     }
85006c3fb27SDimitry Andric 
851bdd1243dSDimitry Andric     return QualType();
852bdd1243dSDimitry Andric   }
853bdd1243dSDimitry Andric 
8540b57cec5SDimitry Andric   // Binary operators and binary compound assignment operators.
8550b57cec5SDimitry Andric #define HANDLEBINOP(OP)                                                        \
8560b57cec5SDimitry Andric   Value *VisitBin##OP(const BinaryOperator *E) {                               \
857bdd1243dSDimitry Andric     QualType promotionTy = getPromotionType(E->getType());                     \
858bdd1243dSDimitry Andric     auto result = Emit##OP(EmitBinOps(E, promotionTy));                        \
859bdd1243dSDimitry Andric     if (result && !promotionTy.isNull())                                       \
860bdd1243dSDimitry Andric       result = EmitUnPromotedValue(result, E->getType());                      \
861bdd1243dSDimitry Andric     return result;                                                             \
8620b57cec5SDimitry Andric   }                                                                            \
8630b57cec5SDimitry Andric   Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) {               \
8640b57cec5SDimitry Andric     return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP);                \
8650b57cec5SDimitry Andric   }
8660b57cec5SDimitry Andric   HANDLEBINOP(Mul)
8670b57cec5SDimitry Andric   HANDLEBINOP(Div)
8680b57cec5SDimitry Andric   HANDLEBINOP(Rem)
8690b57cec5SDimitry Andric   HANDLEBINOP(Add)
8700b57cec5SDimitry Andric   HANDLEBINOP(Sub)
8710b57cec5SDimitry Andric   HANDLEBINOP(Shl)
8720b57cec5SDimitry Andric   HANDLEBINOP(Shr)
8730b57cec5SDimitry Andric   HANDLEBINOP(And)
8740b57cec5SDimitry Andric   HANDLEBINOP(Xor)
8750b57cec5SDimitry Andric   HANDLEBINOP(Or)
8760b57cec5SDimitry Andric #undef HANDLEBINOP
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   // Comparisons.
8790b57cec5SDimitry Andric   Value *EmitCompare(const BinaryOperator *E, llvm::CmpInst::Predicate UICmpOpc,
8800b57cec5SDimitry Andric                      llvm::CmpInst::Predicate SICmpOpc,
881480093f4SDimitry Andric                      llvm::CmpInst::Predicate FCmpOpc, bool IsSignaling);
882480093f4SDimitry Andric #define VISITCOMP(CODE, UI, SI, FP, SIG) \
8830b57cec5SDimitry Andric     Value *VisitBin##CODE(const BinaryOperator *E) { \
8840b57cec5SDimitry Andric       return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
885480093f4SDimitry Andric                          llvm::FCmpInst::FP, SIG); }
886480093f4SDimitry Andric   VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT, true)
887480093f4SDimitry Andric   VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT, true)
888480093f4SDimitry Andric   VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE, true)
889480093f4SDimitry Andric   VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE, true)
890480093f4SDimitry Andric   VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ, false)
891480093f4SDimitry Andric   VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE, false)
8920b57cec5SDimitry Andric #undef VISITCOMP
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric   Value *VisitBinAssign     (const BinaryOperator *E);
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric   Value *VisitBinLAnd       (const BinaryOperator *E);
8970b57cec5SDimitry Andric   Value *VisitBinLOr        (const BinaryOperator *E);
8980b57cec5SDimitry Andric   Value *VisitBinComma      (const BinaryOperator *E);
8990b57cec5SDimitry Andric 
VisitBinPtrMemD(const Expr * E)9000b57cec5SDimitry Andric   Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
VisitBinPtrMemI(const Expr * E)9010b57cec5SDimitry Andric   Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
9020b57cec5SDimitry Andric 
VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator * E)903a7dea167SDimitry Andric   Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
904a7dea167SDimitry Andric     return Visit(E->getSemanticForm());
905a7dea167SDimitry Andric   }
906a7dea167SDimitry Andric 
9070b57cec5SDimitry Andric   // Other Operators.
9080b57cec5SDimitry Andric   Value *VisitBlockExpr(const BlockExpr *BE);
9090b57cec5SDimitry Andric   Value *VisitAbstractConditionalOperator(const AbstractConditionalOperator *);
9100b57cec5SDimitry Andric   Value *VisitChooseExpr(ChooseExpr *CE);
9110b57cec5SDimitry Andric   Value *VisitVAArgExpr(VAArgExpr *VE);
VisitObjCStringLiteral(const ObjCStringLiteral * E)9120b57cec5SDimitry Andric   Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
9130b57cec5SDimitry Andric     return CGF.EmitObjCStringLiteral(E);
9140b57cec5SDimitry Andric   }
VisitObjCBoxedExpr(ObjCBoxedExpr * E)9150b57cec5SDimitry Andric   Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
9160b57cec5SDimitry Andric     return CGF.EmitObjCBoxedExpr(E);
9170b57cec5SDimitry Andric   }
VisitObjCArrayLiteral(ObjCArrayLiteral * E)9180b57cec5SDimitry Andric   Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
9190b57cec5SDimitry Andric     return CGF.EmitObjCArrayLiteral(E);
9200b57cec5SDimitry Andric   }
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)9210b57cec5SDimitry Andric   Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
9220b57cec5SDimitry Andric     return CGF.EmitObjCDictionaryLiteral(E);
9230b57cec5SDimitry Andric   }
9240b57cec5SDimitry Andric   Value *VisitAsTypeExpr(AsTypeExpr *CE);
9250b57cec5SDimitry Andric   Value *VisitAtomicExpr(AtomicExpr *AE);
VisitPackIndexingExpr(PackIndexingExpr * E)9260fca6ea1SDimitry Andric   Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
9270fca6ea1SDimitry Andric     return Visit(E->getSelectedExpr());
9280fca6ea1SDimitry Andric   }
9290b57cec5SDimitry Andric };
9300b57cec5SDimitry Andric }  // end anonymous namespace.
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9330b57cec5SDimitry Andric //                                Utilities
9340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric /// EmitConversionToBool - Convert the specified expression value to a
9370b57cec5SDimitry Andric /// boolean (i1) truth value.  This is equivalent to "Val != 0".
EmitConversionToBool(Value * Src,QualType SrcType)9380b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
9390b57cec5SDimitry Andric   assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");
9400b57cec5SDimitry Andric 
9410b57cec5SDimitry Andric   if (SrcType->isRealFloatingType())
9420b57cec5SDimitry Andric     return EmitFloatToBoolConversion(Src);
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric   if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
9450b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, Src, MPT);
9460b57cec5SDimitry Andric 
9470b57cec5SDimitry Andric   assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
9480b57cec5SDimitry Andric          "Unknown scalar type to convert");
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   if (isa<llvm::IntegerType>(Src->getType()))
9510b57cec5SDimitry Andric     return EmitIntToBoolConversion(Src);
9520b57cec5SDimitry Andric 
9530b57cec5SDimitry Andric   assert(isa<llvm::PointerType>(Src->getType()));
9540b57cec5SDimitry Andric   return EmitPointerToBoolConversion(Src, SrcType);
9550b57cec5SDimitry Andric }
9560b57cec5SDimitry Andric 
EmitFloatConversionCheck(Value * OrigSrc,QualType OrigSrcType,Value * Src,QualType SrcType,QualType DstType,llvm::Type * DstTy,SourceLocation Loc)9570b57cec5SDimitry Andric void ScalarExprEmitter::EmitFloatConversionCheck(
9580b57cec5SDimitry Andric     Value *OrigSrc, QualType OrigSrcType, Value *Src, QualType SrcType,
9590b57cec5SDimitry Andric     QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
9600b57cec5SDimitry Andric   assert(SrcType->isFloatingType() && "not a conversion from floating point");
9610b57cec5SDimitry Andric   if (!isa<llvm::IntegerType>(DstTy))
9620b57cec5SDimitry Andric     return;
9630b57cec5SDimitry Andric 
9640b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
9650b57cec5SDimitry Andric   using llvm::APFloat;
9660b57cec5SDimitry Andric   using llvm::APSInt;
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   llvm::Value *Check = nullptr;
9690b57cec5SDimitry Andric   const llvm::fltSemantics &SrcSema =
9700b57cec5SDimitry Andric     CGF.getContext().getFloatTypeSemantics(OrigSrcType);
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric   // Floating-point to integer. This has undefined behavior if the source is
9730b57cec5SDimitry Andric   // +-Inf, NaN, or doesn't fit into the destination type (after truncation
9740b57cec5SDimitry Andric   // to an integer).
9750b57cec5SDimitry Andric   unsigned Width = CGF.getContext().getIntWidth(DstType);
9760b57cec5SDimitry Andric   bool Unsigned = DstType->isUnsignedIntegerOrEnumerationType();
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   APSInt Min = APSInt::getMinValue(Width, Unsigned);
9790b57cec5SDimitry Andric   APFloat MinSrc(SrcSema, APFloat::uninitialized);
9800b57cec5SDimitry Andric   if (MinSrc.convertFromAPInt(Min, !Unsigned, APFloat::rmTowardZero) &
9810b57cec5SDimitry Andric       APFloat::opOverflow)
9820b57cec5SDimitry Andric     // Don't need an overflow check for lower bound. Just check for
9830b57cec5SDimitry Andric     // -Inf/NaN.
9840b57cec5SDimitry Andric     MinSrc = APFloat::getInf(SrcSema, true);
9850b57cec5SDimitry Andric   else
9860b57cec5SDimitry Andric     // Find the largest value which is too small to represent (before
9870b57cec5SDimitry Andric     // truncation toward zero).
9880b57cec5SDimitry Andric     MinSrc.subtract(APFloat(SrcSema, 1), APFloat::rmTowardNegative);
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric   APSInt Max = APSInt::getMaxValue(Width, Unsigned);
9910b57cec5SDimitry Andric   APFloat MaxSrc(SrcSema, APFloat::uninitialized);
9920b57cec5SDimitry Andric   if (MaxSrc.convertFromAPInt(Max, !Unsigned, APFloat::rmTowardZero) &
9930b57cec5SDimitry Andric       APFloat::opOverflow)
9940b57cec5SDimitry Andric     // Don't need an overflow check for upper bound. Just check for
9950b57cec5SDimitry Andric     // +Inf/NaN.
9960b57cec5SDimitry Andric     MaxSrc = APFloat::getInf(SrcSema, false);
9970b57cec5SDimitry Andric   else
9980b57cec5SDimitry Andric     // Find the smallest value which is too large to represent (before
9990b57cec5SDimitry Andric     // truncation toward zero).
10000b57cec5SDimitry Andric     MaxSrc.add(APFloat(SrcSema, 1), APFloat::rmTowardPositive);
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   // If we're converting from __half, convert the range to float to match
10030b57cec5SDimitry Andric   // the type of src.
10040b57cec5SDimitry Andric   if (OrigSrcType->isHalfType()) {
10050b57cec5SDimitry Andric     const llvm::fltSemantics &Sema =
10060b57cec5SDimitry Andric       CGF.getContext().getFloatTypeSemantics(SrcType);
10070b57cec5SDimitry Andric     bool IsInexact;
10080b57cec5SDimitry Andric     MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
10090b57cec5SDimitry Andric     MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
10100b57cec5SDimitry Andric   }
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric   llvm::Value *GE =
10130b57cec5SDimitry Andric     Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
10140b57cec5SDimitry Andric   llvm::Value *LE =
10150b57cec5SDimitry Andric     Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
10160b57cec5SDimitry Andric   Check = Builder.CreateAnd(GE, LE);
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
10190b57cec5SDimitry Andric                                   CGF.EmitCheckTypeDescriptor(OrigSrcType),
10200b57cec5SDimitry Andric                                   CGF.EmitCheckTypeDescriptor(DstType)};
10210b57cec5SDimitry Andric   CGF.EmitCheck(std::make_pair(Check, SanitizerKind::FloatCastOverflow),
10220b57cec5SDimitry Andric                 SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc);
10230b57cec5SDimitry Andric }
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
10260b57cec5SDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
10270b57cec5SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
10280b57cec5SDimitry Andric                  std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)10290b57cec5SDimitry Andric EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
10300b57cec5SDimitry Andric                                  QualType DstType, CGBuilderTy &Builder) {
10310b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
10320b57cec5SDimitry Andric   llvm::Type *DstTy = Dst->getType();
10330b57cec5SDimitry Andric   (void)DstTy; // Only used in assert()
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric   // This should be truncation of integral types.
10360b57cec5SDimitry Andric   assert(Src != Dst);
10370b57cec5SDimitry Andric   assert(SrcTy->getScalarSizeInBits() > Dst->getType()->getScalarSizeInBits());
10380b57cec5SDimitry Andric   assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
10390b57cec5SDimitry Andric          "non-integer llvm type");
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
10420b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   // If both (src and dst) types are unsigned, then it's an unsigned truncation.
10450b57cec5SDimitry Andric   // Else, it is a signed truncation.
10460b57cec5SDimitry Andric   ScalarExprEmitter::ImplicitConversionCheckKind Kind;
10470b57cec5SDimitry Andric   SanitizerMask Mask;
10480b57cec5SDimitry Andric   if (!SrcSigned && !DstSigned) {
10490b57cec5SDimitry Andric     Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
10500b57cec5SDimitry Andric     Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation;
10510b57cec5SDimitry Andric   } else {
10520b57cec5SDimitry Andric     Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
10530b57cec5SDimitry Andric     Mask = SanitizerKind::ImplicitSignedIntegerTruncation;
10540b57cec5SDimitry Andric   }
10550b57cec5SDimitry Andric 
10560b57cec5SDimitry Andric   llvm::Value *Check = nullptr;
10570b57cec5SDimitry Andric   // 1. Extend the truncated value back to the same width as the Src.
10580b57cec5SDimitry Andric   Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext");
10590b57cec5SDimitry Andric   // 2. Equality-compare with the original source value
10600b57cec5SDimitry Andric   Check = Builder.CreateICmpEQ(Check, Src, "truncheck");
10610b57cec5SDimitry Andric   // If the comparison result is 'i1 false', then the truncation was lossy.
10620b57cec5SDimitry Andric   return std::make_pair(Kind, std::make_pair(Check, Mask));
10630b57cec5SDimitry Andric }
10640b57cec5SDimitry Andric 
PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType,QualType DstType)1065480093f4SDimitry Andric static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
1066480093f4SDimitry Andric     QualType SrcType, QualType DstType) {
1067480093f4SDimitry Andric   return SrcType->isIntegerType() && DstType->isIntegerType();
1068480093f4SDimitry Andric }
1069480093f4SDimitry Andric 
EmitIntegerTruncationCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)10700b57cec5SDimitry Andric void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
10710b57cec5SDimitry Andric                                                    Value *Dst, QualType DstType,
10720b57cec5SDimitry Andric                                                    SourceLocation Loc) {
10730b57cec5SDimitry Andric   if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation))
10740b57cec5SDimitry Andric     return;
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   // We only care about int->int conversions here.
10770b57cec5SDimitry Andric   // We ignore conversions to/from pointer and/or bool.
1078480093f4SDimitry Andric   if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1079480093f4SDimitry Andric                                                                        DstType))
10800b57cec5SDimitry Andric     return;
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric   unsigned SrcBits = Src->getType()->getScalarSizeInBits();
10830b57cec5SDimitry Andric   unsigned DstBits = Dst->getType()->getScalarSizeInBits();
10840b57cec5SDimitry Andric   // This must be truncation. Else we do not care.
10850b57cec5SDimitry Andric   if (SrcBits <= DstBits)
10860b57cec5SDimitry Andric     return;
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric   assert(!DstType->isBooleanType() && "we should not get here with booleans.");
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric   // If the integer sign change sanitizer is enabled,
10910b57cec5SDimitry Andric   // and we are truncating from larger unsigned type to smaller signed type,
10920b57cec5SDimitry Andric   // let that next sanitizer deal with it.
10930b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
10940b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
10950b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) &&
10960b57cec5SDimitry Andric       (!SrcSigned && DstSigned))
10970b57cec5SDimitry Andric     return;
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
11000b57cec5SDimitry Andric 
11010b57cec5SDimitry Andric   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
11020b57cec5SDimitry Andric             std::pair<llvm::Value *, SanitizerMask>>
11030b57cec5SDimitry Andric       Check =
11040b57cec5SDimitry Andric           EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
11050b57cec5SDimitry Andric   // If the comparison result is 'i1 false', then the truncation was lossy.
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   // Do we care about this type of truncation?
11080b57cec5SDimitry Andric   if (!CGF.SanOpts.has(Check.second.second))
11090b57cec5SDimitry Andric     return;
11100b57cec5SDimitry Andric 
11110b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {
11120b57cec5SDimitry Andric       CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
11130b57cec5SDimitry Andric       CGF.EmitCheckTypeDescriptor(DstType),
11140fca6ea1SDimitry Andric       llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
11150fca6ea1SDimitry Andric       llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
11160fca6ea1SDimitry Andric 
11170b57cec5SDimitry Andric   CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
11180b57cec5SDimitry Andric                 {Src, Dst});
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric 
EmitIsNegativeTestHelper(Value * V,QualType VType,const char * Name,CGBuilderTy & Builder)11210fca6ea1SDimitry Andric static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
11220fca6ea1SDimitry Andric                                              const char *Name,
11230fca6ea1SDimitry Andric                                              CGBuilderTy &Builder) {
11240fca6ea1SDimitry Andric   bool VSigned = VType->isSignedIntegerOrEnumerationType();
11250fca6ea1SDimitry Andric   llvm::Type *VTy = V->getType();
11260fca6ea1SDimitry Andric   if (!VSigned) {
11270fca6ea1SDimitry Andric     // If the value is unsigned, then it is never negative.
11280fca6ea1SDimitry Andric     return llvm::ConstantInt::getFalse(VTy->getContext());
11290fca6ea1SDimitry Andric   }
11300fca6ea1SDimitry Andric   llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
11310fca6ea1SDimitry Andric   return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
11320fca6ea1SDimitry Andric                             llvm::Twine(Name) + "." + V->getName() +
11330fca6ea1SDimitry Andric                                 ".negativitycheck");
11340fca6ea1SDimitry Andric }
11350fca6ea1SDimitry Andric 
11360b57cec5SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
11370b57cec5SDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
11380b57cec5SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
11390b57cec5SDimitry Andric                  std::pair<llvm::Value *, SanitizerMask>>
EmitIntegerSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)11400b57cec5SDimitry Andric EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
11410b57cec5SDimitry Andric                                  QualType DstType, CGBuilderTy &Builder) {
11420b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
11430b57cec5SDimitry Andric   llvm::Type *DstTy = Dst->getType();
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
11460b57cec5SDimitry Andric          "non-integer llvm type");
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
11490b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
11500b57cec5SDimitry Andric   (void)SrcSigned; // Only used in assert()
11510b57cec5SDimitry Andric   (void)DstSigned; // Only used in assert()
11520b57cec5SDimitry Andric   unsigned SrcBits = SrcTy->getScalarSizeInBits();
11530b57cec5SDimitry Andric   unsigned DstBits = DstTy->getScalarSizeInBits();
11540b57cec5SDimitry Andric   (void)SrcBits; // Only used in assert()
11550b57cec5SDimitry Andric   (void)DstBits; // Only used in assert()
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric   assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
11580b57cec5SDimitry Andric          "either the widths should be different, or the signednesses.");
11590b57cec5SDimitry Andric 
11600b57cec5SDimitry Andric   // 1. Was the old Value negative?
11610fca6ea1SDimitry Andric   llvm::Value *SrcIsNegative =
11620fca6ea1SDimitry Andric       EmitIsNegativeTestHelper(Src, SrcType, "src", Builder);
11630b57cec5SDimitry Andric   // 2. Is the new Value negative?
11640fca6ea1SDimitry Andric   llvm::Value *DstIsNegative =
11650fca6ea1SDimitry Andric       EmitIsNegativeTestHelper(Dst, DstType, "dst", Builder);
11660b57cec5SDimitry Andric   // 3. Now, was the 'negativity status' preserved during the conversion?
11670b57cec5SDimitry Andric   //    NOTE: conversion from negative to zero is considered to change the sign.
11680b57cec5SDimitry Andric   //    (We want to get 'false' when the conversion changed the sign)
11690b57cec5SDimitry Andric   //    So we should just equality-compare the negativity statuses.
11700b57cec5SDimitry Andric   llvm::Value *Check = nullptr;
11710b57cec5SDimitry Andric   Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "signchangecheck");
11720b57cec5SDimitry Andric   // If the comparison result is 'false', then the conversion changed the sign.
11730b57cec5SDimitry Andric   return std::make_pair(
11740b57cec5SDimitry Andric       ScalarExprEmitter::ICCK_IntegerSignChange,
11750b57cec5SDimitry Andric       std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange));
11760b57cec5SDimitry Andric }
11770b57cec5SDimitry Andric 
EmitIntegerSignChangeCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,SourceLocation Loc)11780b57cec5SDimitry Andric void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
11790b57cec5SDimitry Andric                                                    Value *Dst, QualType DstType,
11800b57cec5SDimitry Andric                                                    SourceLocation Loc) {
11810b57cec5SDimitry Andric   if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange))
11820b57cec5SDimitry Andric     return;
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
11850b57cec5SDimitry Andric   llvm::Type *DstTy = Dst->getType();
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric   // We only care about int->int conversions here.
11880b57cec5SDimitry Andric   // We ignore conversions to/from pointer and/or bool.
1189480093f4SDimitry Andric   if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
1190480093f4SDimitry Andric                                                                        DstType))
11910b57cec5SDimitry Andric     return;
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
11940b57cec5SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
11950b57cec5SDimitry Andric   unsigned SrcBits = SrcTy->getScalarSizeInBits();
11960b57cec5SDimitry Andric   unsigned DstBits = DstTy->getScalarSizeInBits();
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   // Now, we do not need to emit the check in *all* of the cases.
11990b57cec5SDimitry Andric   // We can avoid emitting it in some obvious cases where it would have been
12000b57cec5SDimitry Andric   // dropped by the opt passes (instcombine) always anyways.
12010b57cec5SDimitry Andric   // If it's a cast between effectively the same type, no check.
12020b57cec5SDimitry Andric   // NOTE: this is *not* equivalent to checking the canonical types.
12030b57cec5SDimitry Andric   if (SrcSigned == DstSigned && SrcBits == DstBits)
12040b57cec5SDimitry Andric     return;
12050b57cec5SDimitry Andric   // At least one of the values needs to have signed type.
12060b57cec5SDimitry Andric   // If both are unsigned, then obviously, neither of them can be negative.
12070b57cec5SDimitry Andric   if (!SrcSigned && !DstSigned)
12080b57cec5SDimitry Andric     return;
12090b57cec5SDimitry Andric   // If the conversion is to *larger* *signed* type, then no check is needed.
12100b57cec5SDimitry Andric   // Because either sign-extension happens (so the sign will remain),
12110b57cec5SDimitry Andric   // or zero-extension will happen (the sign bit will be zero.)
12120b57cec5SDimitry Andric   if ((DstBits > SrcBits) && DstSigned)
12130b57cec5SDimitry Andric     return;
12140b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
12150b57cec5SDimitry Andric       (SrcBits > DstBits) && SrcSigned) {
12160b57cec5SDimitry Andric     // If the signed integer truncation sanitizer is enabled,
12170b57cec5SDimitry Andric     // and this is a truncation from signed type, then no check is needed.
12180b57cec5SDimitry Andric     // Because here sign change check is interchangeable with truncation check.
12190b57cec5SDimitry Andric     return;
12200b57cec5SDimitry Andric   }
12210b57cec5SDimitry Andric   // That's it. We can't rule out any more cases with the data we have.
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
12240b57cec5SDimitry Andric 
12250b57cec5SDimitry Andric   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
12260b57cec5SDimitry Andric             std::pair<llvm::Value *, SanitizerMask>>
12270b57cec5SDimitry Andric       Check;
12280b57cec5SDimitry Andric 
12290b57cec5SDimitry Andric   // Each of these checks needs to return 'false' when an issue was detected.
12300b57cec5SDimitry Andric   ImplicitConversionCheckKind CheckKind;
12310b57cec5SDimitry Andric   llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
12320b57cec5SDimitry Andric   // So we can 'and' all the checks together, and still get 'false',
12330b57cec5SDimitry Andric   // if at least one of the checks detected an issue.
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric   Check = EmitIntegerSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
12360b57cec5SDimitry Andric   CheckKind = Check.first;
12370b57cec5SDimitry Andric   Checks.emplace_back(Check.second);
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
12400b57cec5SDimitry Andric       (SrcBits > DstBits) && !SrcSigned && DstSigned) {
12410b57cec5SDimitry Andric     // If the signed integer truncation sanitizer was enabled,
12420b57cec5SDimitry Andric     // and we are truncating from larger unsigned type to smaller signed type,
12430b57cec5SDimitry Andric     // let's handle the case we skipped in that check.
12440b57cec5SDimitry Andric     Check =
12450b57cec5SDimitry Andric         EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
12460b57cec5SDimitry Andric     CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
12470b57cec5SDimitry Andric     Checks.emplace_back(Check.second);
12480b57cec5SDimitry Andric     // If the comparison result is 'i1 false', then the truncation was lossy.
12490b57cec5SDimitry Andric   }
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {
12520b57cec5SDimitry Andric       CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
12530b57cec5SDimitry Andric       CGF.EmitCheckTypeDescriptor(DstType),
12540fca6ea1SDimitry Andric       llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
12550fca6ea1SDimitry Andric       llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
12560b57cec5SDimitry Andric   // EmitCheck() will 'and' all the checks together.
12570b57cec5SDimitry Andric   CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs,
12580b57cec5SDimitry Andric                 {Src, Dst});
12590b57cec5SDimitry Andric }
12600b57cec5SDimitry Andric 
12610fca6ea1SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
12620fca6ea1SDimitry Andric // Returns 'i1 false' when the truncation Src -> Dst was lossy.
12630fca6ea1SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
12640fca6ea1SDimitry Andric                  std::pair<llvm::Value *, SanitizerMask>>
EmitBitfieldTruncationCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)12650fca6ea1SDimitry Andric EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
12660fca6ea1SDimitry Andric                                   QualType DstType, CGBuilderTy &Builder) {
12670fca6ea1SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
12680fca6ea1SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
12690fca6ea1SDimitry Andric 
12700fca6ea1SDimitry Andric   ScalarExprEmitter::ImplicitConversionCheckKind Kind;
12710fca6ea1SDimitry Andric   if (!SrcSigned && !DstSigned)
12720fca6ea1SDimitry Andric     Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
12730fca6ea1SDimitry Andric   else
12740fca6ea1SDimitry Andric     Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
12750fca6ea1SDimitry Andric 
12760fca6ea1SDimitry Andric   llvm::Value *Check = nullptr;
12770fca6ea1SDimitry Andric   // 1. Extend the truncated value back to the same width as the Src.
12780fca6ea1SDimitry Andric   Check = Builder.CreateIntCast(Dst, Src->getType(), DstSigned, "bf.anyext");
12790fca6ea1SDimitry Andric   // 2. Equality-compare with the original source value
12800fca6ea1SDimitry Andric   Check = Builder.CreateICmpEQ(Check, Src, "bf.truncheck");
12810fca6ea1SDimitry Andric   // If the comparison result is 'i1 false', then the truncation was lossy.
12820fca6ea1SDimitry Andric 
12830fca6ea1SDimitry Andric   return std::make_pair(
12840fca6ea1SDimitry Andric       Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
12850fca6ea1SDimitry Andric }
12860fca6ea1SDimitry Andric 
12870fca6ea1SDimitry Andric // Should be called within CodeGenFunction::SanitizerScope RAII scope.
12880fca6ea1SDimitry Andric // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
12890fca6ea1SDimitry Andric static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
12900fca6ea1SDimitry Andric                  std::pair<llvm::Value *, SanitizerMask>>
EmitBitfieldSignChangeCheckHelper(Value * Src,QualType SrcType,Value * Dst,QualType DstType,CGBuilderTy & Builder)12910fca6ea1SDimitry Andric EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
12920fca6ea1SDimitry Andric                                   QualType DstType, CGBuilderTy &Builder) {
12930fca6ea1SDimitry Andric   // 1. Was the old Value negative?
12940fca6ea1SDimitry Andric   llvm::Value *SrcIsNegative =
12950fca6ea1SDimitry Andric       EmitIsNegativeTestHelper(Src, SrcType, "bf.src", Builder);
12960fca6ea1SDimitry Andric   // 2. Is the new Value negative?
12970fca6ea1SDimitry Andric   llvm::Value *DstIsNegative =
12980fca6ea1SDimitry Andric       EmitIsNegativeTestHelper(Dst, DstType, "bf.dst", Builder);
12990fca6ea1SDimitry Andric   // 3. Now, was the 'negativity status' preserved during the conversion?
13000fca6ea1SDimitry Andric   //    NOTE: conversion from negative to zero is considered to change the sign.
13010fca6ea1SDimitry Andric   //    (We want to get 'false' when the conversion changed the sign)
13020fca6ea1SDimitry Andric   //    So we should just equality-compare the negativity statuses.
13030fca6ea1SDimitry Andric   llvm::Value *Check = nullptr;
13040fca6ea1SDimitry Andric   Check =
13050fca6ea1SDimitry Andric       Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "bf.signchangecheck");
13060fca6ea1SDimitry Andric   // If the comparison result is 'false', then the conversion changed the sign.
13070fca6ea1SDimitry Andric   return std::make_pair(
13080fca6ea1SDimitry Andric       ScalarExprEmitter::ICCK_IntegerSignChange,
13090fca6ea1SDimitry Andric       std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
13100fca6ea1SDimitry Andric }
13110fca6ea1SDimitry Andric 
EmitBitfieldConversionCheck(Value * Src,QualType SrcType,Value * Dst,QualType DstType,const CGBitFieldInfo & Info,SourceLocation Loc)13120fca6ea1SDimitry Andric void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
13130fca6ea1SDimitry Andric                                                   Value *Dst, QualType DstType,
13140fca6ea1SDimitry Andric                                                   const CGBitFieldInfo &Info,
13150fca6ea1SDimitry Andric                                                   SourceLocation Loc) {
13160fca6ea1SDimitry Andric 
13170fca6ea1SDimitry Andric   if (!SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
13180fca6ea1SDimitry Andric     return;
13190fca6ea1SDimitry Andric 
13200fca6ea1SDimitry Andric   // We only care about int->int conversions here.
13210fca6ea1SDimitry Andric   // We ignore conversions to/from pointer and/or bool.
13220fca6ea1SDimitry Andric   if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
13230fca6ea1SDimitry Andric                                                                        DstType))
13240fca6ea1SDimitry Andric     return;
13250fca6ea1SDimitry Andric 
13260fca6ea1SDimitry Andric   if (DstType->isBooleanType() || SrcType->isBooleanType())
13270fca6ea1SDimitry Andric     return;
13280fca6ea1SDimitry Andric 
13290fca6ea1SDimitry Andric   // This should be truncation of integral types.
13300fca6ea1SDimitry Andric   assert(isa<llvm::IntegerType>(Src->getType()) &&
13310fca6ea1SDimitry Andric          isa<llvm::IntegerType>(Dst->getType()) && "non-integer llvm type");
13320fca6ea1SDimitry Andric 
13330fca6ea1SDimitry Andric   // TODO: Calculate src width to avoid emitting code
13340fca6ea1SDimitry Andric   // for unecessary cases.
13350fca6ea1SDimitry Andric   unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits();
13360fca6ea1SDimitry Andric   unsigned DstBits = Info.Size;
13370fca6ea1SDimitry Andric 
13380fca6ea1SDimitry Andric   bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
13390fca6ea1SDimitry Andric   bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
13400fca6ea1SDimitry Andric 
13410fca6ea1SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(this);
13420fca6ea1SDimitry Andric 
13430fca6ea1SDimitry Andric   std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
13440fca6ea1SDimitry Andric             std::pair<llvm::Value *, SanitizerMask>>
13450fca6ea1SDimitry Andric       Check;
13460fca6ea1SDimitry Andric 
13470fca6ea1SDimitry Andric   // Truncation
13480fca6ea1SDimitry Andric   bool EmitTruncation = DstBits < SrcBits;
13490fca6ea1SDimitry Andric   // If Dst is signed and Src unsigned, we want to be more specific
13500fca6ea1SDimitry Andric   // about the CheckKind we emit, in this case we want to emit
13510fca6ea1SDimitry Andric   // ICCK_SignedIntegerTruncationOrSignChange.
13520fca6ea1SDimitry Andric   bool EmitTruncationFromUnsignedToSigned =
13530fca6ea1SDimitry Andric       EmitTruncation && DstSigned && !SrcSigned;
13540fca6ea1SDimitry Andric   // Sign change
13550fca6ea1SDimitry Andric   bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
13560fca6ea1SDimitry Andric   bool BothUnsigned = !SrcSigned && !DstSigned;
13570fca6ea1SDimitry Andric   bool LargerSigned = (DstBits > SrcBits) && DstSigned;
13580fca6ea1SDimitry Andric   // We can avoid emitting sign change checks in some obvious cases
13590fca6ea1SDimitry Andric   //   1. If Src and Dst have the same signedness and size
13600fca6ea1SDimitry Andric   //   2. If both are unsigned sign check is unecessary!
13610fca6ea1SDimitry Andric   //   3. If Dst is signed and bigger than Src, either
13620fca6ea1SDimitry Andric   //      sign-extension or zero-extension will make sure
13630fca6ea1SDimitry Andric   //      the sign remains.
13640fca6ea1SDimitry Andric   bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
13650fca6ea1SDimitry Andric 
13660fca6ea1SDimitry Andric   if (EmitTruncation)
13670fca6ea1SDimitry Andric     Check =
13680fca6ea1SDimitry Andric         EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
13690fca6ea1SDimitry Andric   else if (EmitSignChange) {
13700fca6ea1SDimitry Andric     assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
13710fca6ea1SDimitry Andric            "either the widths should be different, or the signednesses.");
13720fca6ea1SDimitry Andric     Check =
13730fca6ea1SDimitry Andric         EmitBitfieldSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
13740fca6ea1SDimitry Andric   } else
13750fca6ea1SDimitry Andric     return;
13760fca6ea1SDimitry Andric 
13770fca6ea1SDimitry Andric   ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
13780fca6ea1SDimitry Andric   if (EmitTruncationFromUnsignedToSigned)
13790fca6ea1SDimitry Andric     CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
13800fca6ea1SDimitry Andric 
13810fca6ea1SDimitry Andric   llvm::Constant *StaticArgs[] = {
13820fca6ea1SDimitry Andric       EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(SrcType),
13830fca6ea1SDimitry Andric       EmitCheckTypeDescriptor(DstType),
13840fca6ea1SDimitry Andric       llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
13850fca6ea1SDimitry Andric       llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)};
13860fca6ea1SDimitry Andric 
13870fca6ea1SDimitry Andric   EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
13880fca6ea1SDimitry Andric             {Src, Dst});
13890fca6ea1SDimitry Andric }
13900fca6ea1SDimitry Andric 
EmitScalarCast(Value * Src,QualType SrcType,QualType DstType,llvm::Type * SrcTy,llvm::Type * DstTy,ScalarConversionOpts Opts)1391fe6060f1SDimitry Andric Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
1392fe6060f1SDimitry Andric                                          QualType DstType, llvm::Type *SrcTy,
1393fe6060f1SDimitry Andric                                          llvm::Type *DstTy,
1394fe6060f1SDimitry Andric                                          ScalarConversionOpts Opts) {
1395fe6060f1SDimitry Andric   // The Element types determine the type of cast to perform.
1396fe6060f1SDimitry Andric   llvm::Type *SrcElementTy;
1397fe6060f1SDimitry Andric   llvm::Type *DstElementTy;
1398fe6060f1SDimitry Andric   QualType SrcElementType;
1399fe6060f1SDimitry Andric   QualType DstElementType;
1400fe6060f1SDimitry Andric   if (SrcType->isMatrixType() && DstType->isMatrixType()) {
1401fe6060f1SDimitry Andric     SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
1402fe6060f1SDimitry Andric     DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
1403fe6060f1SDimitry Andric     SrcElementType = SrcType->castAs<MatrixType>()->getElementType();
1404fe6060f1SDimitry Andric     DstElementType = DstType->castAs<MatrixType>()->getElementType();
1405fe6060f1SDimitry Andric   } else {
1406fe6060f1SDimitry Andric     assert(!SrcType->isMatrixType() && !DstType->isMatrixType() &&
1407fe6060f1SDimitry Andric            "cannot cast between matrix and non-matrix types");
1408fe6060f1SDimitry Andric     SrcElementTy = SrcTy;
1409fe6060f1SDimitry Andric     DstElementTy = DstTy;
1410fe6060f1SDimitry Andric     SrcElementType = SrcType;
1411fe6060f1SDimitry Andric     DstElementType = DstType;
1412fe6060f1SDimitry Andric   }
1413fe6060f1SDimitry Andric 
1414fe6060f1SDimitry Andric   if (isa<llvm::IntegerType>(SrcElementTy)) {
1415fe6060f1SDimitry Andric     bool InputSigned = SrcElementType->isSignedIntegerOrEnumerationType();
1416fe6060f1SDimitry Andric     if (SrcElementType->isBooleanType() && Opts.TreatBooleanAsSigned) {
1417fe6060f1SDimitry Andric       InputSigned = true;
1418fe6060f1SDimitry Andric     }
1419fe6060f1SDimitry Andric 
1420fe6060f1SDimitry Andric     if (isa<llvm::IntegerType>(DstElementTy))
1421fe6060f1SDimitry Andric       return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
1422fe6060f1SDimitry Andric     if (InputSigned)
1423fe6060f1SDimitry Andric       return Builder.CreateSIToFP(Src, DstTy, "conv");
1424fe6060f1SDimitry Andric     return Builder.CreateUIToFP(Src, DstTy, "conv");
1425fe6060f1SDimitry Andric   }
1426fe6060f1SDimitry Andric 
1427fe6060f1SDimitry Andric   if (isa<llvm::IntegerType>(DstElementTy)) {
1428fe6060f1SDimitry Andric     assert(SrcElementTy->isFloatingPointTy() && "Unknown real conversion");
14290eae32dcSDimitry Andric     bool IsSigned = DstElementType->isSignedIntegerOrEnumerationType();
14300eae32dcSDimitry Andric 
14310eae32dcSDimitry Andric     // If we can't recognize overflow as undefined behavior, assume that
14320eae32dcSDimitry Andric     // overflow saturates. This protects against normal optimizations if we are
14330eae32dcSDimitry Andric     // compiling with non-standard FP semantics.
14340eae32dcSDimitry Andric     if (!CGF.CGM.getCodeGenOpts().StrictFloatCastOverflow) {
14350eae32dcSDimitry Andric       llvm::Intrinsic::ID IID =
14360eae32dcSDimitry Andric           IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
14370eae32dcSDimitry Andric       return Builder.CreateCall(CGF.CGM.getIntrinsic(IID, {DstTy, SrcTy}), Src);
14380eae32dcSDimitry Andric     }
14390eae32dcSDimitry Andric 
14400eae32dcSDimitry Andric     if (IsSigned)
1441fe6060f1SDimitry Andric       return Builder.CreateFPToSI(Src, DstTy, "conv");
1442fe6060f1SDimitry Andric     return Builder.CreateFPToUI(Src, DstTy, "conv");
1443fe6060f1SDimitry Andric   }
1444fe6060f1SDimitry Andric 
1445fe6060f1SDimitry Andric   if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1446fe6060f1SDimitry Andric     return Builder.CreateFPTrunc(Src, DstTy, "conv");
1447fe6060f1SDimitry Andric   return Builder.CreateFPExt(Src, DstTy, "conv");
1448fe6060f1SDimitry Andric }
1449fe6060f1SDimitry Andric 
14500b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
14510b57cec5SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcType,QualType DstType,SourceLocation Loc,ScalarConversionOpts Opts)14520b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
14530b57cec5SDimitry Andric                                                QualType DstType,
14540b57cec5SDimitry Andric                                                SourceLocation Loc,
14550b57cec5SDimitry Andric                                                ScalarConversionOpts Opts) {
14560b57cec5SDimitry Andric   // All conversions involving fixed point types should be handled by the
14570b57cec5SDimitry Andric   // EmitFixedPoint family functions. This is done to prevent bloating up this
14580b57cec5SDimitry Andric   // function more, and although fixed point numbers are represented by
14590b57cec5SDimitry Andric   // integers, we do not want to follow any logic that assumes they should be
14600b57cec5SDimitry Andric   // treated as integers.
14610b57cec5SDimitry Andric   // TODO(leonardchan): When necessary, add another if statement checking for
14620b57cec5SDimitry Andric   // conversions to fixed point types from other types.
14630b57cec5SDimitry Andric   if (SrcType->isFixedPointType()) {
14640b57cec5SDimitry Andric     if (DstType->isBooleanType())
14650b57cec5SDimitry Andric       // It is important that we check this before checking if the dest type is
14660b57cec5SDimitry Andric       // an integer because booleans are technically integer types.
14670b57cec5SDimitry Andric       // We do not need to check the padding bit on unsigned types if unsigned
14680b57cec5SDimitry Andric       // padding is enabled because overflow into this bit is undefined
14690b57cec5SDimitry Andric       // behavior.
14700b57cec5SDimitry Andric       return Builder.CreateIsNotNull(Src, "tobool");
1471e8d8bef9SDimitry Andric     if (DstType->isFixedPointType() || DstType->isIntegerType() ||
1472e8d8bef9SDimitry Andric         DstType->isRealFloatingType())
14730b57cec5SDimitry Andric       return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric     llvm_unreachable(
14760b57cec5SDimitry Andric         "Unhandled scalar conversion from a fixed point type to another type.");
14770b57cec5SDimitry Andric   } else if (DstType->isFixedPointType()) {
1478e8d8bef9SDimitry Andric     if (SrcType->isIntegerType() || SrcType->isRealFloatingType())
14790b57cec5SDimitry Andric       // This also includes converting booleans and enums to fixed point types.
14800b57cec5SDimitry Andric       return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric     llvm_unreachable(
14830b57cec5SDimitry Andric         "Unhandled scalar conversion to a fixed point type from another type.");
14840b57cec5SDimitry Andric   }
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric   QualType NoncanonicalSrcType = SrcType;
14870b57cec5SDimitry Andric   QualType NoncanonicalDstType = DstType;
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric   SrcType = CGF.getContext().getCanonicalType(SrcType);
14900b57cec5SDimitry Andric   DstType = CGF.getContext().getCanonicalType(DstType);
14910b57cec5SDimitry Andric   if (SrcType == DstType) return Src;
14920b57cec5SDimitry Andric 
14930b57cec5SDimitry Andric   if (DstType->isVoidType()) return nullptr;
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric   llvm::Value *OrigSrc = Src;
14960b57cec5SDimitry Andric   QualType OrigSrcType = SrcType;
14970b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
14980b57cec5SDimitry Andric 
14990b57cec5SDimitry Andric   // Handle conversions to bool first, they are special: comparisons against 0.
15000b57cec5SDimitry Andric   if (DstType->isBooleanType())
15010b57cec5SDimitry Andric     return EmitConversionToBool(Src, SrcType);
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric   llvm::Type *DstTy = ConvertType(DstType);
15040b57cec5SDimitry Andric 
15050b57cec5SDimitry Andric   // Cast from half through float if half isn't a native type.
15060b57cec5SDimitry Andric   if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
15070b57cec5SDimitry Andric     // Cast to FP using the intrinsic if the half type itself isn't supported.
15080b57cec5SDimitry Andric     if (DstTy->isFloatingPointTy()) {
15090b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
15100b57cec5SDimitry Andric         return Builder.CreateCall(
15110b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16, DstTy),
15120b57cec5SDimitry Andric             Src);
15130b57cec5SDimitry Andric     } else {
15140b57cec5SDimitry Andric       // Cast to other types through float, using either the intrinsic or FPExt,
15150b57cec5SDimitry Andric       // depending on whether the half type itself is supported
15160b57cec5SDimitry Andric       // (as opposed to operations on half, available with NativeHalfType).
15170b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
15180b57cec5SDimitry Andric         Src = Builder.CreateCall(
15190b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
15200b57cec5SDimitry Andric                                  CGF.CGM.FloatTy),
15210b57cec5SDimitry Andric             Src);
15220b57cec5SDimitry Andric       } else {
15230b57cec5SDimitry Andric         Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
15240b57cec5SDimitry Andric       }
15250b57cec5SDimitry Andric       SrcType = CGF.getContext().FloatTy;
15260b57cec5SDimitry Andric       SrcTy = CGF.FloatTy;
15270b57cec5SDimitry Andric     }
15280b57cec5SDimitry Andric   }
15290b57cec5SDimitry Andric 
15300b57cec5SDimitry Andric   // Ignore conversions like int -> uint.
15310b57cec5SDimitry Andric   if (SrcTy == DstTy) {
15320b57cec5SDimitry Andric     if (Opts.EmitImplicitIntegerSignChangeChecks)
15330b57cec5SDimitry Andric       EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
15340b57cec5SDimitry Andric                                  NoncanonicalDstType, Loc);
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric     return Src;
15370b57cec5SDimitry Andric   }
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric   // Handle pointer conversions next: pointers can only be converted to/from
15400b57cec5SDimitry Andric   // other pointers and integers. Check for pointer types in terms of LLVM, as
15410b57cec5SDimitry Andric   // some native types (like Obj-C id) may map to a pointer type.
15420b57cec5SDimitry Andric   if (auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
15430b57cec5SDimitry Andric     // The source value may be an integer, or a pointer.
15440b57cec5SDimitry Andric     if (isa<llvm::PointerType>(SrcTy))
15450fca6ea1SDimitry Andric       return Src;
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric     assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
15480b57cec5SDimitry Andric     // First, convert to the correct width so that we control the kind of
15490b57cec5SDimitry Andric     // extension.
15500b57cec5SDimitry Andric     llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DstPT);
15510b57cec5SDimitry Andric     bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
15520b57cec5SDimitry Andric     llvm::Value* IntResult =
15530b57cec5SDimitry Andric         Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
15540b57cec5SDimitry Andric     // Then, cast to pointer.
15550b57cec5SDimitry Andric     return Builder.CreateIntToPtr(IntResult, DstTy, "conv");
15560b57cec5SDimitry Andric   }
15570b57cec5SDimitry Andric 
15580b57cec5SDimitry Andric   if (isa<llvm::PointerType>(SrcTy)) {
15590b57cec5SDimitry Andric     // Must be an ptr to int cast.
15600b57cec5SDimitry Andric     assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
15610b57cec5SDimitry Andric     return Builder.CreatePtrToInt(Src, DstTy, "conv");
15620b57cec5SDimitry Andric   }
15630b57cec5SDimitry Andric 
15640b57cec5SDimitry Andric   // A scalar can be splatted to an extended vector of the same element type
15650b57cec5SDimitry Andric   if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
15660b57cec5SDimitry Andric     // Sema should add casts to make sure that the source expression's type is
15670b57cec5SDimitry Andric     // the same as the vector's element type (sans qualifiers)
15680b57cec5SDimitry Andric     assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
15690b57cec5SDimitry Andric                SrcType.getTypePtr() &&
15700b57cec5SDimitry Andric            "Splatted expr doesn't match with vector element type?");
15710b57cec5SDimitry Andric 
15720b57cec5SDimitry Andric     // Splat the element across to all elements
1573e8d8bef9SDimitry Andric     unsigned NumElements = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
15740b57cec5SDimitry Andric     return Builder.CreateVectorSplat(NumElements, Src, "splat");
15750b57cec5SDimitry Andric   }
15760b57cec5SDimitry Andric 
1577fe6060f1SDimitry Andric   if (SrcType->isMatrixType() && DstType->isMatrixType())
1578fe6060f1SDimitry Andric     return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1579fe6060f1SDimitry Andric 
15800b57cec5SDimitry Andric   if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
15810b57cec5SDimitry Andric     // Allow bitcast from vector to integer/fp of the same size.
158281ad6265SDimitry Andric     llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
158381ad6265SDimitry Andric     llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
15840b57cec5SDimitry Andric     if (SrcSize == DstSize)
15850b57cec5SDimitry Andric       return Builder.CreateBitCast(Src, DstTy, "conv");
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric     // Conversions between vectors of different sizes are not allowed except
15880b57cec5SDimitry Andric     // when vectors of half are involved. Operations on storage-only half
15890b57cec5SDimitry Andric     // vectors require promoting half vector operands to float vectors and
15900b57cec5SDimitry Andric     // truncating the result, which is either an int or float vector, to a
15910b57cec5SDimitry Andric     // short or half vector.
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric     // Source and destination are both expected to be vectors.
15945ffd83dbSDimitry Andric     llvm::Type *SrcElementTy = cast<llvm::VectorType>(SrcTy)->getElementType();
15955ffd83dbSDimitry Andric     llvm::Type *DstElementTy = cast<llvm::VectorType>(DstTy)->getElementType();
15960b57cec5SDimitry Andric     (void)DstElementTy;
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric     assert(((SrcElementTy->isIntegerTy() &&
15990b57cec5SDimitry Andric              DstElementTy->isIntegerTy()) ||
16000b57cec5SDimitry Andric             (SrcElementTy->isFloatingPointTy() &&
16010b57cec5SDimitry Andric              DstElementTy->isFloatingPointTy())) &&
16020b57cec5SDimitry Andric            "unexpected conversion between a floating-point vector and an "
16030b57cec5SDimitry Andric            "integer vector");
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric     // Truncate an i32 vector to an i16 vector.
16060b57cec5SDimitry Andric     if (SrcElementTy->isIntegerTy())
16070b57cec5SDimitry Andric       return Builder.CreateIntCast(Src, DstTy, false, "conv");
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric     // Truncate a float vector to a half vector.
16100b57cec5SDimitry Andric     if (SrcSize > DstSize)
16110b57cec5SDimitry Andric       return Builder.CreateFPTrunc(Src, DstTy, "conv");
16120b57cec5SDimitry Andric 
16130b57cec5SDimitry Andric     // Promote a half vector to a float vector.
16140b57cec5SDimitry Andric     return Builder.CreateFPExt(Src, DstTy, "conv");
16150b57cec5SDimitry Andric   }
16160b57cec5SDimitry Andric 
16170b57cec5SDimitry Andric   // Finally, we have the arithmetic types: real int/float.
16180b57cec5SDimitry Andric   Value *Res = nullptr;
16190b57cec5SDimitry Andric   llvm::Type *ResTy = DstTy;
16200b57cec5SDimitry Andric 
16210b57cec5SDimitry Andric   // An overflowing conversion has undefined behavior if either the source type
16220b57cec5SDimitry Andric   // or the destination type is a floating-point type. However, we consider the
16230b57cec5SDimitry Andric   // range of representable values for all floating-point types to be
16240b57cec5SDimitry Andric   // [-inf,+inf], so no overflow can ever happen when the destination type is a
16250b57cec5SDimitry Andric   // floating-point type.
16260b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::FloatCastOverflow) &&
16270b57cec5SDimitry Andric       OrigSrcType->isFloatingType())
16280b57cec5SDimitry Andric     EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
16290b57cec5SDimitry Andric                              Loc);
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric   // Cast to half through float if half isn't a native type.
16320b57cec5SDimitry Andric   if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
16330b57cec5SDimitry Andric     // Make sure we cast in a single step if from another FP type.
16340b57cec5SDimitry Andric     if (SrcTy->isFloatingPointTy()) {
16350b57cec5SDimitry Andric       // Use the intrinsic if the half type itself isn't supported
16360b57cec5SDimitry Andric       // (as opposed to operations on half, available with NativeHalfType).
16370b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics())
16380b57cec5SDimitry Andric         return Builder.CreateCall(
16390b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, SrcTy), Src);
16400b57cec5SDimitry Andric       // If the half type is supported, just use an fptrunc.
16410b57cec5SDimitry Andric       return Builder.CreateFPTrunc(Src, DstTy);
16420b57cec5SDimitry Andric     }
16430b57cec5SDimitry Andric     DstTy = CGF.FloatTy;
16440b57cec5SDimitry Andric   }
16450b57cec5SDimitry Andric 
1646fe6060f1SDimitry Andric   Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
16470b57cec5SDimitry Andric 
16480b57cec5SDimitry Andric   if (DstTy != ResTy) {
16490b57cec5SDimitry Andric     if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
16500b57cec5SDimitry Andric       assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion");
16510b57cec5SDimitry Andric       Res = Builder.CreateCall(
16520b57cec5SDimitry Andric         CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy),
16530b57cec5SDimitry Andric         Res);
16540b57cec5SDimitry Andric     } else {
16550b57cec5SDimitry Andric       Res = Builder.CreateFPTrunc(Res, ResTy, "conv");
16560b57cec5SDimitry Andric     }
16570b57cec5SDimitry Andric   }
16580b57cec5SDimitry Andric 
16590b57cec5SDimitry Andric   if (Opts.EmitImplicitIntegerTruncationChecks)
16600b57cec5SDimitry Andric     EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
16610b57cec5SDimitry Andric                                NoncanonicalDstType, Loc);
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric   if (Opts.EmitImplicitIntegerSignChangeChecks)
16640b57cec5SDimitry Andric     EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
16650b57cec5SDimitry Andric                                NoncanonicalDstType, Loc);
16660b57cec5SDimitry Andric 
16670b57cec5SDimitry Andric   return Res;
16680b57cec5SDimitry Andric }
16690b57cec5SDimitry Andric 
EmitFixedPointConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)16700b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
16710b57cec5SDimitry Andric                                                    QualType DstTy,
16720b57cec5SDimitry Andric                                                    SourceLocation Loc) {
1673e8d8bef9SDimitry Andric   llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1674e8d8bef9SDimitry Andric   llvm::Value *Result;
1675e8d8bef9SDimitry Andric   if (SrcTy->isRealFloatingType())
1676e8d8bef9SDimitry Andric     Result = FPBuilder.CreateFloatingToFixed(Src,
1677e8d8bef9SDimitry Andric         CGF.getContext().getFixedPointSemantics(DstTy));
1678e8d8bef9SDimitry Andric   else if (DstTy->isRealFloatingType())
1679e8d8bef9SDimitry Andric     Result = FPBuilder.CreateFixedToFloating(Src,
1680e8d8bef9SDimitry Andric         CGF.getContext().getFixedPointSemantics(SrcTy),
1681e8d8bef9SDimitry Andric         ConvertType(DstTy));
1682e8d8bef9SDimitry Andric   else {
1683e8d8bef9SDimitry Andric     auto SrcFPSema = CGF.getContext().getFixedPointSemantics(SrcTy);
1684e8d8bef9SDimitry Andric     auto DstFPSema = CGF.getContext().getFixedPointSemantics(DstTy);
16850b57cec5SDimitry Andric 
1686e8d8bef9SDimitry Andric     if (DstTy->isIntegerType())
1687e8d8bef9SDimitry Andric       Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1688e8d8bef9SDimitry Andric                                               DstFPSema.getWidth(),
1689e8d8bef9SDimitry Andric                                               DstFPSema.isSigned());
1690e8d8bef9SDimitry Andric     else if (SrcTy->isIntegerType())
1691e8d8bef9SDimitry Andric       Result =  FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1692e8d8bef9SDimitry Andric                                                DstFPSema);
1693e8d8bef9SDimitry Andric     else
1694e8d8bef9SDimitry Andric       Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
16950b57cec5SDimitry Andric   }
16960b57cec5SDimitry Andric   return Result;
16970b57cec5SDimitry Andric }
16980b57cec5SDimitry Andric 
16990b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
17000b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)17010b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitComplexToScalarConversion(
17020b57cec5SDimitry Andric     CodeGenFunction::ComplexPairTy Src, QualType SrcTy, QualType DstTy,
17030b57cec5SDimitry Andric     SourceLocation Loc) {
17040b57cec5SDimitry Andric   // Get the source element type.
17050b57cec5SDimitry Andric   SrcTy = SrcTy->castAs<ComplexType>()->getElementType();
17060b57cec5SDimitry Andric 
17070b57cec5SDimitry Andric   // Handle conversions to bool first, they are special: comparisons against 0.
17080b57cec5SDimitry Andric   if (DstTy->isBooleanType()) {
17090b57cec5SDimitry Andric     //  Complex != 0  -> (Real != 0) | (Imag != 0)
17100b57cec5SDimitry Andric     Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
17110b57cec5SDimitry Andric     Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
17120b57cec5SDimitry Andric     return Builder.CreateOr(Src.first, Src.second, "tobool");
17130b57cec5SDimitry Andric   }
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric   // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
17160b57cec5SDimitry Andric   // the imaginary part of the complex value is discarded and the value of the
17170b57cec5SDimitry Andric   // real part is converted according to the conversion rules for the
17180b57cec5SDimitry Andric   // corresponding real type.
17190b57cec5SDimitry Andric   return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
17200b57cec5SDimitry Andric }
17210b57cec5SDimitry Andric 
EmitNullValue(QualType Ty)17220b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
17230b57cec5SDimitry Andric   return CGF.EmitFromMemory(CGF.CGM.EmitNullConstant(Ty), Ty);
17240b57cec5SDimitry Andric }
17250b57cec5SDimitry Andric 
17260b57cec5SDimitry Andric /// Emit a sanitization check for the given "binary" operation (which
17270b57cec5SDimitry Andric /// might actually be a unary increment which has been lowered to a binary
17280b57cec5SDimitry Andric /// operation). The check passes if all values in \p Checks (which are \c i1),
17290b57cec5SDimitry Andric /// are \c true.
EmitBinOpCheck(ArrayRef<std::pair<Value *,SanitizerMask>> Checks,const BinOpInfo & Info)17300b57cec5SDimitry Andric void ScalarExprEmitter::EmitBinOpCheck(
17310b57cec5SDimitry Andric     ArrayRef<std::pair<Value *, SanitizerMask>> Checks, const BinOpInfo &Info) {
17320b57cec5SDimitry Andric   assert(CGF.IsSanitizerScope);
17330b57cec5SDimitry Andric   SanitizerHandler Check;
17340b57cec5SDimitry Andric   SmallVector<llvm::Constant *, 4> StaticData;
17350b57cec5SDimitry Andric   SmallVector<llvm::Value *, 2> DynamicData;
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric   BinaryOperatorKind Opcode = Info.Opcode;
17380b57cec5SDimitry Andric   if (BinaryOperator::isCompoundAssignmentOp(Opcode))
17390b57cec5SDimitry Andric     Opcode = BinaryOperator::getOpForCompoundAssignment(Opcode);
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric   StaticData.push_back(CGF.EmitCheckSourceLocation(Info.E->getExprLoc()));
17420b57cec5SDimitry Andric   const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
17430b57cec5SDimitry Andric   if (UO && UO->getOpcode() == UO_Minus) {
17440b57cec5SDimitry Andric     Check = SanitizerHandler::NegateOverflow;
17450b57cec5SDimitry Andric     StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
17460b57cec5SDimitry Andric     DynamicData.push_back(Info.RHS);
17470b57cec5SDimitry Andric   } else {
17480b57cec5SDimitry Andric     if (BinaryOperator::isShiftOp(Opcode)) {
17490b57cec5SDimitry Andric       // Shift LHS negative or too large, or RHS out of bounds.
17500b57cec5SDimitry Andric       Check = SanitizerHandler::ShiftOutOfBounds;
17510b57cec5SDimitry Andric       const BinaryOperator *BO = cast<BinaryOperator>(Info.E);
17520b57cec5SDimitry Andric       StaticData.push_back(
17530b57cec5SDimitry Andric         CGF.EmitCheckTypeDescriptor(BO->getLHS()->getType()));
17540b57cec5SDimitry Andric       StaticData.push_back(
17550b57cec5SDimitry Andric         CGF.EmitCheckTypeDescriptor(BO->getRHS()->getType()));
17560b57cec5SDimitry Andric     } else if (Opcode == BO_Div || Opcode == BO_Rem) {
17570b57cec5SDimitry Andric       // Divide or modulo by zero, or signed overflow (eg INT_MAX / -1).
17580b57cec5SDimitry Andric       Check = SanitizerHandler::DivremOverflow;
17590b57cec5SDimitry Andric       StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
17600b57cec5SDimitry Andric     } else {
17610b57cec5SDimitry Andric       // Arithmetic overflow (+, -, *).
17620b57cec5SDimitry Andric       switch (Opcode) {
17630b57cec5SDimitry Andric       case BO_Add: Check = SanitizerHandler::AddOverflow; break;
17640b57cec5SDimitry Andric       case BO_Sub: Check = SanitizerHandler::SubOverflow; break;
17650b57cec5SDimitry Andric       case BO_Mul: Check = SanitizerHandler::MulOverflow; break;
17660b57cec5SDimitry Andric       default: llvm_unreachable("unexpected opcode for bin op check");
17670b57cec5SDimitry Andric       }
17680b57cec5SDimitry Andric       StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
17690b57cec5SDimitry Andric     }
17700b57cec5SDimitry Andric     DynamicData.push_back(Info.LHS);
17710b57cec5SDimitry Andric     DynamicData.push_back(Info.RHS);
17720b57cec5SDimitry Andric   }
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric   CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
17750b57cec5SDimitry Andric }
17760b57cec5SDimitry Andric 
17770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17780b57cec5SDimitry Andric //                            Visitor Methods
17790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
17800b57cec5SDimitry Andric 
VisitExpr(Expr * E)17810b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitExpr(Expr *E) {
17820b57cec5SDimitry Andric   CGF.ErrorUnsupported(E, "scalar expression");
17830b57cec5SDimitry Andric   if (E->getType()->isVoidType())
17840b57cec5SDimitry Andric     return nullptr;
17850b57cec5SDimitry Andric   return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
17860b57cec5SDimitry Andric }
17870b57cec5SDimitry Andric 
1788fe6060f1SDimitry Andric Value *
VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr * E)1789fe6060f1SDimitry Andric ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1790fe6060f1SDimitry Andric   ASTContext &Context = CGF.getContext();
1791bdd1243dSDimitry Andric   unsigned AddrSpace =
1792bdd1243dSDimitry Andric       Context.getTargetAddressSpace(CGF.CGM.GetGlobalConstantAddressSpace());
1793fe6060f1SDimitry Andric   llvm::Constant *GlobalConstStr = Builder.CreateGlobalStringPtr(
1794bdd1243dSDimitry Andric       E->ComputeName(Context), "__usn_str", AddrSpace);
1795fe6060f1SDimitry Andric 
1796bdd1243dSDimitry Andric   llvm::Type *ExprTy = ConvertType(E->getType());
1797bdd1243dSDimitry Andric   return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1798bdd1243dSDimitry Andric                                                      "usn_addr_cast");
1799fe6060f1SDimitry Andric }
1800fe6060f1SDimitry Andric 
VisitEmbedExpr(EmbedExpr * E)18010fca6ea1SDimitry Andric Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
18020fca6ea1SDimitry Andric   assert(E->getDataElementCount() == 1);
18030fca6ea1SDimitry Andric   auto It = E->begin();
18040fca6ea1SDimitry Andric   return Builder.getInt((*It)->getValue());
18050fca6ea1SDimitry Andric }
18060fca6ea1SDimitry Andric 
VisitShuffleVectorExpr(ShuffleVectorExpr * E)18070b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
18080b57cec5SDimitry Andric   // Vector Mask Case
18090b57cec5SDimitry Andric   if (E->getNumSubExprs() == 2) {
18100b57cec5SDimitry Andric     Value *LHS = CGF.EmitScalarExpr(E->getExpr(0));
18110b57cec5SDimitry Andric     Value *RHS = CGF.EmitScalarExpr(E->getExpr(1));
18120b57cec5SDimitry Andric     Value *Mask;
18130b57cec5SDimitry Andric 
1814e8d8bef9SDimitry Andric     auto *LTy = cast<llvm::FixedVectorType>(LHS->getType());
18150b57cec5SDimitry Andric     unsigned LHSElts = LTy->getNumElements();
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric     Mask = RHS;
18180b57cec5SDimitry Andric 
1819e8d8bef9SDimitry Andric     auto *MTy = cast<llvm::FixedVectorType>(Mask->getType());
18200b57cec5SDimitry Andric 
18210b57cec5SDimitry Andric     // Mask off the high bits of each shuffle index.
18220b57cec5SDimitry Andric     Value *MaskBits =
18230b57cec5SDimitry Andric         llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
18240b57cec5SDimitry Andric     Mask = Builder.CreateAnd(Mask, MaskBits, "mask");
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric     // newv = undef
18270b57cec5SDimitry Andric     // mask = mask & maskbits
18280b57cec5SDimitry Andric     // for each elt
18290b57cec5SDimitry Andric     //   n = extract mask i
18300b57cec5SDimitry Andric     //   x = extract val n
18310b57cec5SDimitry Andric     //   newv = insert newv, x, i
18325ffd83dbSDimitry Andric     auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
18330b57cec5SDimitry Andric                                            MTy->getNumElements());
1834bdd1243dSDimitry Andric     Value* NewV = llvm::PoisonValue::get(RTy);
18350b57cec5SDimitry Andric     for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
18360b57cec5SDimitry Andric       Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
18370b57cec5SDimitry Andric       Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
18380b57cec5SDimitry Andric 
18390b57cec5SDimitry Andric       Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
18400b57cec5SDimitry Andric       NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
18410b57cec5SDimitry Andric     }
18420b57cec5SDimitry Andric     return NewV;
18430b57cec5SDimitry Andric   }
18440b57cec5SDimitry Andric 
18450b57cec5SDimitry Andric   Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
18460b57cec5SDimitry Andric   Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
18470b57cec5SDimitry Andric 
18485ffd83dbSDimitry Andric   SmallVector<int, 32> Indices;
18490b57cec5SDimitry Andric   for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
18500b57cec5SDimitry Andric     llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
18510b57cec5SDimitry Andric     // Check for -1 and output it as undef in the IR.
1852349cc55cSDimitry Andric     if (Idx.isSigned() && Idx.isAllOnes())
18535ffd83dbSDimitry Andric       Indices.push_back(-1);
18540b57cec5SDimitry Andric     else
18555ffd83dbSDimitry Andric       Indices.push_back(Idx.getZExtValue());
18560b57cec5SDimitry Andric   }
18570b57cec5SDimitry Andric 
18585ffd83dbSDimitry Andric   return Builder.CreateShuffleVector(V1, V2, Indices, "shuffle");
18590b57cec5SDimitry Andric }
18600b57cec5SDimitry Andric 
VisitConvertVectorExpr(ConvertVectorExpr * E)18610b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
18620b57cec5SDimitry Andric   QualType SrcType = E->getSrcExpr()->getType(),
18630b57cec5SDimitry Andric            DstType = E->getType();
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric   Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr());
18660b57cec5SDimitry Andric 
18670b57cec5SDimitry Andric   SrcType = CGF.getContext().getCanonicalType(SrcType);
18680b57cec5SDimitry Andric   DstType = CGF.getContext().getCanonicalType(DstType);
18690b57cec5SDimitry Andric   if (SrcType == DstType) return Src;
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric   assert(SrcType->isVectorType() &&
18720b57cec5SDimitry Andric          "ConvertVector source type must be a vector");
18730b57cec5SDimitry Andric   assert(DstType->isVectorType() &&
18740b57cec5SDimitry Andric          "ConvertVector destination type must be a vector");
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
18770b57cec5SDimitry Andric   llvm::Type *DstTy = ConvertType(DstType);
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric   // Ignore conversions like int -> uint.
18800b57cec5SDimitry Andric   if (SrcTy == DstTy)
18810b57cec5SDimitry Andric     return Src;
18820b57cec5SDimitry Andric 
1883a7dea167SDimitry Andric   QualType SrcEltType = SrcType->castAs<VectorType>()->getElementType(),
1884a7dea167SDimitry Andric            DstEltType = DstType->castAs<VectorType>()->getElementType();
18850b57cec5SDimitry Andric 
18860b57cec5SDimitry Andric   assert(SrcTy->isVectorTy() &&
18870b57cec5SDimitry Andric          "ConvertVector source IR type must be a vector");
18880b57cec5SDimitry Andric   assert(DstTy->isVectorTy() &&
18890b57cec5SDimitry Andric          "ConvertVector destination IR type must be a vector");
18900b57cec5SDimitry Andric 
18915ffd83dbSDimitry Andric   llvm::Type *SrcEltTy = cast<llvm::VectorType>(SrcTy)->getElementType(),
18925ffd83dbSDimitry Andric              *DstEltTy = cast<llvm::VectorType>(DstTy)->getElementType();
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric   if (DstEltType->isBooleanType()) {
18950b57cec5SDimitry Andric     assert((SrcEltTy->isFloatingPointTy() ||
18960b57cec5SDimitry Andric             isa<llvm::IntegerType>(SrcEltTy)) && "Unknown boolean conversion");
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
18990b57cec5SDimitry Andric     if (SrcEltTy->isFloatingPointTy()) {
19000b57cec5SDimitry Andric       return Builder.CreateFCmpUNE(Src, Zero, "tobool");
19010b57cec5SDimitry Andric     } else {
19020b57cec5SDimitry Andric       return Builder.CreateICmpNE(Src, Zero, "tobool");
19030b57cec5SDimitry Andric     }
19040b57cec5SDimitry Andric   }
19050b57cec5SDimitry Andric 
19060b57cec5SDimitry Andric   // We have the arithmetic types: real int/float.
19070b57cec5SDimitry Andric   Value *Res = nullptr;
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric   if (isa<llvm::IntegerType>(SrcEltTy)) {
19100b57cec5SDimitry Andric     bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType();
19110b57cec5SDimitry Andric     if (isa<llvm::IntegerType>(DstEltTy))
19120b57cec5SDimitry Andric       Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
19130b57cec5SDimitry Andric     else if (InputSigned)
19140b57cec5SDimitry Andric       Res = Builder.CreateSIToFP(Src, DstTy, "conv");
19150b57cec5SDimitry Andric     else
19160b57cec5SDimitry Andric       Res = Builder.CreateUIToFP(Src, DstTy, "conv");
19170b57cec5SDimitry Andric   } else if (isa<llvm::IntegerType>(DstEltTy)) {
19180b57cec5SDimitry Andric     assert(SrcEltTy->isFloatingPointTy() && "Unknown real conversion");
19190b57cec5SDimitry Andric     if (DstEltType->isSignedIntegerOrEnumerationType())
19200b57cec5SDimitry Andric       Res = Builder.CreateFPToSI(Src, DstTy, "conv");
19210b57cec5SDimitry Andric     else
19220b57cec5SDimitry Andric       Res = Builder.CreateFPToUI(Src, DstTy, "conv");
19230b57cec5SDimitry Andric   } else {
19240b57cec5SDimitry Andric     assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
19250b57cec5SDimitry Andric            "Unknown real conversion");
19260b57cec5SDimitry Andric     if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
19270b57cec5SDimitry Andric       Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
19280b57cec5SDimitry Andric     else
19290b57cec5SDimitry Andric       Res = Builder.CreateFPExt(Src, DstTy, "conv");
19300b57cec5SDimitry Andric   }
19310b57cec5SDimitry Andric 
19320b57cec5SDimitry Andric   return Res;
19330b57cec5SDimitry Andric }
19340b57cec5SDimitry Andric 
VisitMemberExpr(MemberExpr * E)19350b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
19360b57cec5SDimitry Andric   if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) {
19370b57cec5SDimitry Andric     CGF.EmitIgnoredExpr(E->getBase());
19380b57cec5SDimitry Andric     return CGF.emitScalarConstant(Constant, E);
19390b57cec5SDimitry Andric   } else {
19400b57cec5SDimitry Andric     Expr::EvalResult Result;
19410b57cec5SDimitry Andric     if (E->EvaluateAsInt(Result, CGF.getContext(), Expr::SE_AllowSideEffects)) {
19420b57cec5SDimitry Andric       llvm::APSInt Value = Result.Val.getInt();
19430b57cec5SDimitry Andric       CGF.EmitIgnoredExpr(E->getBase());
19440b57cec5SDimitry Andric       return Builder.getInt(Value);
19450b57cec5SDimitry Andric     }
19460b57cec5SDimitry Andric   }
19470b57cec5SDimitry Andric 
19480fca6ea1SDimitry Andric   llvm::Value *Result = EmitLoadOfLValue(E);
19490fca6ea1SDimitry Andric 
19500fca6ea1SDimitry Andric   // If -fdebug-info-for-profiling is specified, emit a pseudo variable and its
19510fca6ea1SDimitry Andric   // debug info for the pointer, even if there is no variable associated with
19520fca6ea1SDimitry Andric   // the pointer's expression.
19530fca6ea1SDimitry Andric   if (CGF.CGM.getCodeGenOpts().DebugInfoForProfiling && CGF.getDebugInfo()) {
19540fca6ea1SDimitry Andric     if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(Result)) {
19550fca6ea1SDimitry Andric       if (llvm::GetElementPtrInst *GEP =
19560fca6ea1SDimitry Andric               dyn_cast<llvm::GetElementPtrInst>(Load->getPointerOperand())) {
19570fca6ea1SDimitry Andric         if (llvm::Instruction *Pointer =
19580fca6ea1SDimitry Andric                 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
19590fca6ea1SDimitry Andric           QualType Ty = E->getBase()->getType();
19600fca6ea1SDimitry Andric           if (!E->isArrow())
19610fca6ea1SDimitry Andric             Ty = CGF.getContext().getPointerType(Ty);
19620fca6ea1SDimitry Andric           CGF.getDebugInfo()->EmitPseudoVariable(Builder, Pointer, Ty);
19630fca6ea1SDimitry Andric         }
19640fca6ea1SDimitry Andric       }
19650fca6ea1SDimitry Andric     }
19660fca6ea1SDimitry Andric   }
19670fca6ea1SDimitry Andric   return Result;
19680b57cec5SDimitry Andric }
19690b57cec5SDimitry Andric 
VisitArraySubscriptExpr(ArraySubscriptExpr * E)19700b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
19710b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
19720b57cec5SDimitry Andric 
19730b57cec5SDimitry Andric   // Emit subscript expressions in rvalue context's.  For most cases, this just
19740b57cec5SDimitry Andric   // loads the lvalue formed by the subscript expr.  However, we have to be
19750b57cec5SDimitry Andric   // careful, because the base of a vector subscript is occasionally an rvalue,
19760b57cec5SDimitry Andric   // so we can't get it as an lvalue.
197781ad6265SDimitry Andric   if (!E->getBase()->getType()->isVectorType() &&
19785f757f3fSDimitry Andric       !E->getBase()->getType()->isSveVLSBuiltinType())
19790b57cec5SDimitry Andric     return EmitLoadOfLValue(E);
19800b57cec5SDimitry Andric 
19810b57cec5SDimitry Andric   // Handle the vector case.  The base must be a vector, the index must be an
19820b57cec5SDimitry Andric   // integer value.
19830b57cec5SDimitry Andric   Value *Base = Visit(E->getBase());
19840b57cec5SDimitry Andric   Value *Idx  = Visit(E->getIdx());
19850b57cec5SDimitry Andric   QualType IdxTy = E->getIdx()->getType();
19860b57cec5SDimitry Andric 
19870b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
19880b57cec5SDimitry Andric     CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric   return Builder.CreateExtractElement(Base, Idx, "vecext");
19910b57cec5SDimitry Andric }
19920b57cec5SDimitry Andric 
VisitMatrixSubscriptExpr(MatrixSubscriptExpr * E)19935ffd83dbSDimitry Andric Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
19945ffd83dbSDimitry Andric   TestAndClearIgnoreResultAssign();
19955ffd83dbSDimitry Andric 
19965ffd83dbSDimitry Andric   // Handle the vector case.  The base must be a vector, the index must be an
19975ffd83dbSDimitry Andric   // integer value.
19985ffd83dbSDimitry Andric   Value *RowIdx = Visit(E->getRowIdx());
19995ffd83dbSDimitry Andric   Value *ColumnIdx = Visit(E->getColumnIdx());
2000349cc55cSDimitry Andric 
2001349cc55cSDimitry Andric   const auto *MatrixTy = E->getBase()->getType()->castAs<ConstantMatrixType>();
2002349cc55cSDimitry Andric   unsigned NumRows = MatrixTy->getNumRows();
200381ad6265SDimitry Andric   llvm::MatrixBuilder MB(Builder);
2004349cc55cSDimitry Andric   Value *Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows);
2005349cc55cSDimitry Andric   if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0)
2006349cc55cSDimitry Andric     MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2007349cc55cSDimitry Andric 
20085ffd83dbSDimitry Andric   Value *Matrix = Visit(E->getBase());
20095ffd83dbSDimitry Andric 
20105ffd83dbSDimitry Andric   // TODO: Should we emit bounds checks with SanitizerKind::ArrayBounds?
2011349cc55cSDimitry Andric   return Builder.CreateExtractElement(Matrix, Idx, "matrixext");
20120b57cec5SDimitry Andric }
20130b57cec5SDimitry Andric 
getMaskElt(llvm::ShuffleVectorInst * SVI,unsigned Idx,unsigned Off)20145ffd83dbSDimitry Andric static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
20155ffd83dbSDimitry Andric                       unsigned Off) {
20165ffd83dbSDimitry Andric   int MV = SVI->getMaskValue(Idx);
20175ffd83dbSDimitry Andric   if (MV == -1)
20185ffd83dbSDimitry Andric     return -1;
20195ffd83dbSDimitry Andric   return Off + MV;
20200b57cec5SDimitry Andric }
20215ffd83dbSDimitry Andric 
getAsInt32(llvm::ConstantInt * C,llvm::Type * I32Ty)20225ffd83dbSDimitry Andric static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {
20235ffd83dbSDimitry Andric   assert(llvm::ConstantInt::isValueValidForType(I32Ty, C->getZExtValue()) &&
20245ffd83dbSDimitry Andric          "Index operand too large for shufflevector mask!");
20255ffd83dbSDimitry Andric   return C->getZExtValue();
20260b57cec5SDimitry Andric }
20270b57cec5SDimitry Andric 
VisitInitListExpr(InitListExpr * E)20280b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
20290b57cec5SDimitry Andric   bool Ignore = TestAndClearIgnoreResultAssign();
20300b57cec5SDimitry Andric   (void)Ignore;
20310b57cec5SDimitry Andric   assert (Ignore == false && "init list ignored");
20320b57cec5SDimitry Andric   unsigned NumInitElements = E->getNumInits();
20330b57cec5SDimitry Andric 
20340b57cec5SDimitry Andric   if (E->hadArrayRangeDesignator())
20350b57cec5SDimitry Andric     CGF.ErrorUnsupported(E, "GNU array range designator extension");
20360b57cec5SDimitry Andric 
20370b57cec5SDimitry Andric   llvm::VectorType *VType =
20380b57cec5SDimitry Andric     dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric   if (!VType) {
20410b57cec5SDimitry Andric     if (NumInitElements == 0) {
20420b57cec5SDimitry Andric       // C++11 value-initialization for the scalar.
20430b57cec5SDimitry Andric       return EmitNullValue(E->getType());
20440b57cec5SDimitry Andric     }
20450b57cec5SDimitry Andric     // We have a scalar in braces. Just use the first element.
20460b57cec5SDimitry Andric     return Visit(E->getInit(0));
20470b57cec5SDimitry Andric   }
20480b57cec5SDimitry Andric 
2049641efdd1SDimitry Andric   if (isa<llvm::ScalableVectorType>(VType)) {
2050641efdd1SDimitry Andric     if (NumInitElements == 0) {
2051641efdd1SDimitry Andric       // C++11 value-initialization for the vector.
2052641efdd1SDimitry Andric       return EmitNullValue(E->getType());
2053641efdd1SDimitry Andric     }
2054641efdd1SDimitry Andric 
2055641efdd1SDimitry Andric     if (NumInitElements == 1) {
2056641efdd1SDimitry Andric       Expr *InitVector = E->getInit(0);
2057641efdd1SDimitry Andric 
2058641efdd1SDimitry Andric       // Initialize from another scalable vector of the same type.
2059641efdd1SDimitry Andric       if (InitVector->getType() == E->getType())
2060641efdd1SDimitry Andric         return Visit(InitVector);
2061641efdd1SDimitry Andric     }
2062641efdd1SDimitry Andric 
2063641efdd1SDimitry Andric     llvm_unreachable("Unexpected initialization of a scalable vector!");
2064641efdd1SDimitry Andric   }
2065641efdd1SDimitry Andric 
2066e8d8bef9SDimitry Andric   unsigned ResElts = cast<llvm::FixedVectorType>(VType)->getNumElements();
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric   // Loop over initializers collecting the Value for each, and remembering
20690b57cec5SDimitry Andric   // whether the source was swizzle (ExtVectorElementExpr).  This will allow
20700b57cec5SDimitry Andric   // us to fold the shuffle for the swizzle into the shuffle for the vector
20710b57cec5SDimitry Andric   // initializer, since LLVM optimizers generally do not want to touch
20720b57cec5SDimitry Andric   // shuffles.
20730b57cec5SDimitry Andric   unsigned CurIdx = 0;
2074cb14a3feSDimitry Andric   bool VIsPoisonShuffle = false;
2075cb14a3feSDimitry Andric   llvm::Value *V = llvm::PoisonValue::get(VType);
20760b57cec5SDimitry Andric   for (unsigned i = 0; i != NumInitElements; ++i) {
20770b57cec5SDimitry Andric     Expr *IE = E->getInit(i);
20780b57cec5SDimitry Andric     Value *Init = Visit(IE);
20795ffd83dbSDimitry Andric     SmallVector<int, 16> Args;
20800b57cec5SDimitry Andric 
20810b57cec5SDimitry Andric     llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType());
20820b57cec5SDimitry Andric 
20830b57cec5SDimitry Andric     // Handle scalar elements.  If the scalar initializer is actually one
20840b57cec5SDimitry Andric     // element of a different vector of the same width, use shuffle instead of
20850b57cec5SDimitry Andric     // extract+insert.
20860b57cec5SDimitry Andric     if (!VVT) {
20870b57cec5SDimitry Andric       if (isa<ExtVectorElementExpr>(IE)) {
20880b57cec5SDimitry Andric         llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init);
20890b57cec5SDimitry Andric 
2090e8d8bef9SDimitry Andric         if (cast<llvm::FixedVectorType>(EI->getVectorOperandType())
2091e8d8bef9SDimitry Andric                 ->getNumElements() == ResElts) {
20920b57cec5SDimitry Andric           llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
20930b57cec5SDimitry Andric           Value *LHS = nullptr, *RHS = nullptr;
20940b57cec5SDimitry Andric           if (CurIdx == 0) {
2095cb14a3feSDimitry Andric             // insert into poison -> shuffle (src, poison)
20960b57cec5SDimitry Andric             // shufflemask must use an i32
20970b57cec5SDimitry Andric             Args.push_back(getAsInt32(C, CGF.Int32Ty));
20985ffd83dbSDimitry Andric             Args.resize(ResElts, -1);
20990b57cec5SDimitry Andric 
21000b57cec5SDimitry Andric             LHS = EI->getVectorOperand();
21010b57cec5SDimitry Andric             RHS = V;
2102cb14a3feSDimitry Andric             VIsPoisonShuffle = true;
2103cb14a3feSDimitry Andric           } else if (VIsPoisonShuffle) {
2104cb14a3feSDimitry Andric             // insert into poison shuffle && size match -> shuffle (v, src)
21050b57cec5SDimitry Andric             llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V);
21060b57cec5SDimitry Andric             for (unsigned j = 0; j != CurIdx; ++j)
21075ffd83dbSDimitry Andric               Args.push_back(getMaskElt(SVV, j, 0));
21085ffd83dbSDimitry Andric             Args.push_back(ResElts + C->getZExtValue());
21095ffd83dbSDimitry Andric             Args.resize(ResElts, -1);
21100b57cec5SDimitry Andric 
21110b57cec5SDimitry Andric             LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
21120b57cec5SDimitry Andric             RHS = EI->getVectorOperand();
2113cb14a3feSDimitry Andric             VIsPoisonShuffle = false;
21140b57cec5SDimitry Andric           }
21150b57cec5SDimitry Andric           if (!Args.empty()) {
21165ffd83dbSDimitry Andric             V = Builder.CreateShuffleVector(LHS, RHS, Args);
21170b57cec5SDimitry Andric             ++CurIdx;
21180b57cec5SDimitry Andric             continue;
21190b57cec5SDimitry Andric           }
21200b57cec5SDimitry Andric         }
21210b57cec5SDimitry Andric       }
21220b57cec5SDimitry Andric       V = Builder.CreateInsertElement(V, Init, Builder.getInt32(CurIdx),
21230b57cec5SDimitry Andric                                       "vecinit");
2124cb14a3feSDimitry Andric       VIsPoisonShuffle = false;
21250b57cec5SDimitry Andric       ++CurIdx;
21260b57cec5SDimitry Andric       continue;
21270b57cec5SDimitry Andric     }
21280b57cec5SDimitry Andric 
2129e8d8bef9SDimitry Andric     unsigned InitElts = cast<llvm::FixedVectorType>(VVT)->getNumElements();
21300b57cec5SDimitry Andric 
21310b57cec5SDimitry Andric     // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's
21320b57cec5SDimitry Andric     // input is the same width as the vector being constructed, generate an
21330b57cec5SDimitry Andric     // optimized shuffle of the swizzle input into the result.
21340b57cec5SDimitry Andric     unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
21350b57cec5SDimitry Andric     if (isa<ExtVectorElementExpr>(IE)) {
21360b57cec5SDimitry Andric       llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init);
21370b57cec5SDimitry Andric       Value *SVOp = SVI->getOperand(0);
2138e8d8bef9SDimitry Andric       auto *OpTy = cast<llvm::FixedVectorType>(SVOp->getType());
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric       if (OpTy->getNumElements() == ResElts) {
21410b57cec5SDimitry Andric         for (unsigned j = 0; j != CurIdx; ++j) {
2142cb14a3feSDimitry Andric           // If the current vector initializer is a shuffle with poison, merge
21430b57cec5SDimitry Andric           // this shuffle directly into it.
2144cb14a3feSDimitry Andric           if (VIsPoisonShuffle) {
21455ffd83dbSDimitry Andric             Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0));
21460b57cec5SDimitry Andric           } else {
21475ffd83dbSDimitry Andric             Args.push_back(j);
21480b57cec5SDimitry Andric           }
21490b57cec5SDimitry Andric         }
21500b57cec5SDimitry Andric         for (unsigned j = 0, je = InitElts; j != je; ++j)
21515ffd83dbSDimitry Andric           Args.push_back(getMaskElt(SVI, j, Offset));
21525ffd83dbSDimitry Andric         Args.resize(ResElts, -1);
21530b57cec5SDimitry Andric 
2154cb14a3feSDimitry Andric         if (VIsPoisonShuffle)
21550b57cec5SDimitry Andric           V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0);
21560b57cec5SDimitry Andric 
21570b57cec5SDimitry Andric         Init = SVOp;
21580b57cec5SDimitry Andric       }
21590b57cec5SDimitry Andric     }
21600b57cec5SDimitry Andric 
21610b57cec5SDimitry Andric     // Extend init to result vector length, and then shuffle its contribution
21620b57cec5SDimitry Andric     // to the vector initializer into V.
21630b57cec5SDimitry Andric     if (Args.empty()) {
21640b57cec5SDimitry Andric       for (unsigned j = 0; j != InitElts; ++j)
21655ffd83dbSDimitry Andric         Args.push_back(j);
21665ffd83dbSDimitry Andric       Args.resize(ResElts, -1);
2167e8d8bef9SDimitry Andric       Init = Builder.CreateShuffleVector(Init, Args, "vext");
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric       Args.clear();
21700b57cec5SDimitry Andric       for (unsigned j = 0; j != CurIdx; ++j)
21715ffd83dbSDimitry Andric         Args.push_back(j);
21720b57cec5SDimitry Andric       for (unsigned j = 0; j != InitElts; ++j)
21735ffd83dbSDimitry Andric         Args.push_back(j + Offset);
21745ffd83dbSDimitry Andric       Args.resize(ResElts, -1);
21750b57cec5SDimitry Andric     }
21760b57cec5SDimitry Andric 
2177cb14a3feSDimitry Andric     // If V is poison, make sure it ends up on the RHS of the shuffle to aid
21780b57cec5SDimitry Andric     // merging subsequent shuffles into this one.
21790b57cec5SDimitry Andric     if (CurIdx == 0)
21800b57cec5SDimitry Andric       std::swap(V, Init);
21815ffd83dbSDimitry Andric     V = Builder.CreateShuffleVector(V, Init, Args, "vecinit");
2182cb14a3feSDimitry Andric     VIsPoisonShuffle = isa<llvm::PoisonValue>(Init);
21830b57cec5SDimitry Andric     CurIdx += InitElts;
21840b57cec5SDimitry Andric   }
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric   // FIXME: evaluate codegen vs. shuffling against constant null vector.
21870b57cec5SDimitry Andric   // Emit remaining default initializers.
21880b57cec5SDimitry Andric   llvm::Type *EltTy = VType->getElementType();
21890b57cec5SDimitry Andric 
21900b57cec5SDimitry Andric   // Emit remaining default initializers
21910b57cec5SDimitry Andric   for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) {
21920b57cec5SDimitry Andric     Value *Idx = Builder.getInt32(CurIdx);
21930b57cec5SDimitry Andric     llvm::Value *Init = llvm::Constant::getNullValue(EltTy);
21940b57cec5SDimitry Andric     V = Builder.CreateInsertElement(V, Init, Idx, "vecinit");
21950b57cec5SDimitry Andric   }
21960b57cec5SDimitry Andric   return V;
21970b57cec5SDimitry Andric }
21980b57cec5SDimitry Andric 
ShouldNullCheckClassCastValue(const CastExpr * CE)21990b57cec5SDimitry Andric bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) {
22000b57cec5SDimitry Andric   const Expr *E = CE->getSubExpr();
22010b57cec5SDimitry Andric 
22020b57cec5SDimitry Andric   if (CE->getCastKind() == CK_UncheckedDerivedToBase)
22030b57cec5SDimitry Andric     return false;
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric   if (isa<CXXThisExpr>(E->IgnoreParens())) {
22060b57cec5SDimitry Andric     // We always assume that 'this' is never null.
22070b57cec5SDimitry Andric     return false;
22080b57cec5SDimitry Andric   }
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric   if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
22110b57cec5SDimitry Andric     // And that glvalue casts are never null.
2212fe6060f1SDimitry Andric     if (ICE->isGLValue())
22130b57cec5SDimitry Andric       return false;
22140b57cec5SDimitry Andric   }
22150b57cec5SDimitry Andric 
22160b57cec5SDimitry Andric   return true;
22170b57cec5SDimitry Andric }
22180b57cec5SDimitry Andric 
22190b57cec5SDimitry Andric // VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
22200b57cec5SDimitry Andric // have to handle a more broad range of conversions than explicit casts, as they
22210b57cec5SDimitry Andric // handle things like function to ptr-to-function decay etc.
VisitCastExpr(CastExpr * CE)22220b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
22230b57cec5SDimitry Andric   Expr *E = CE->getSubExpr();
22240b57cec5SDimitry Andric   QualType DestTy = CE->getType();
22250b57cec5SDimitry Andric   CastKind Kind = CE->getCastKind();
2226bdd1243dSDimitry Andric   CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
22270b57cec5SDimitry Andric 
22280b57cec5SDimitry Andric   // These cases are generally not written to ignore the result of
22290b57cec5SDimitry Andric   // evaluating their sub-expressions, so we clear this now.
22300b57cec5SDimitry Andric   bool Ignored = TestAndClearIgnoreResultAssign();
22310b57cec5SDimitry Andric 
22320b57cec5SDimitry Andric   // Since almost all cast kinds apply to scalars, this switch doesn't have
22330b57cec5SDimitry Andric   // a default case, so the compiler will warn on a missing case.  The cases
22340b57cec5SDimitry Andric   // are in the same order as in the CastKind enum.
22350b57cec5SDimitry Andric   switch (Kind) {
22360b57cec5SDimitry Andric   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
22370b57cec5SDimitry Andric   case CK_BuiltinFnToFnPtr:
22380b57cec5SDimitry Andric     llvm_unreachable("builtin functions are handled elsewhere");
22390b57cec5SDimitry Andric 
22400b57cec5SDimitry Andric   case CK_LValueBitCast:
22410b57cec5SDimitry Andric   case CK_ObjCObjectLValueCast: {
22420fca6ea1SDimitry Andric     Address Addr = EmitLValue(E).getAddress();
224306c3fb27SDimitry Andric     Addr = Addr.withElementType(CGF.ConvertTypeForMem(DestTy));
22440b57cec5SDimitry Andric     LValue LV = CGF.MakeAddrLValue(Addr, DestTy);
22450b57cec5SDimitry Andric     return EmitLoadOfLValue(LV, CE->getExprLoc());
22460b57cec5SDimitry Andric   }
22470b57cec5SDimitry Andric 
22480b57cec5SDimitry Andric   case CK_LValueToRValueBitCast: {
22490b57cec5SDimitry Andric     LValue SourceLVal = CGF.EmitLValue(E);
22500fca6ea1SDimitry Andric     Address Addr =
22510fca6ea1SDimitry Andric         SourceLVal.getAddress().withElementType(CGF.ConvertTypeForMem(DestTy));
22520b57cec5SDimitry Andric     LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
22530b57cec5SDimitry Andric     DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
22540b57cec5SDimitry Andric     return EmitLoadOfLValue(DestLV, CE->getExprLoc());
22550b57cec5SDimitry Andric   }
22560b57cec5SDimitry Andric 
22570b57cec5SDimitry Andric   case CK_CPointerToObjCPointerCast:
22580b57cec5SDimitry Andric   case CK_BlockPointerToObjCPointerCast:
22590b57cec5SDimitry Andric   case CK_AnyPointerToBlockPointerCast:
22600b57cec5SDimitry Andric   case CK_BitCast: {
22610b57cec5SDimitry Andric     Value *Src = Visit(const_cast<Expr*>(E));
22620b57cec5SDimitry Andric     llvm::Type *SrcTy = Src->getType();
22630b57cec5SDimitry Andric     llvm::Type *DstTy = ConvertType(DestTy);
22645f757f3fSDimitry Andric     assert(
22655f757f3fSDimitry Andric         (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
22665f757f3fSDimitry Andric          SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
22675f757f3fSDimitry Andric         "Address-space cast must be used to convert address spaces");
22680b57cec5SDimitry Andric 
22690b57cec5SDimitry Andric     if (CGF.SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
227081ad6265SDimitry Andric       if (auto *PT = DestTy->getAs<PointerType>()) {
227181ad6265SDimitry Andric         CGF.EmitVTablePtrCheckForCast(
227281ad6265SDimitry Andric             PT->getPointeeType(),
227381ad6265SDimitry Andric             Address(Src,
227481ad6265SDimitry Andric                     CGF.ConvertTypeForMem(
227581ad6265SDimitry Andric                         E->getType()->castAs<PointerType>()->getPointeeType()),
227681ad6265SDimitry Andric                     CGF.getPointerAlign()),
227781ad6265SDimitry Andric             /*MayBeNull=*/true, CodeGenFunction::CFITCK_UnrelatedCast,
22780b57cec5SDimitry Andric             CE->getBeginLoc());
22790b57cec5SDimitry Andric       }
228081ad6265SDimitry Andric     }
22810b57cec5SDimitry Andric 
22820b57cec5SDimitry Andric     if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
22830b57cec5SDimitry Andric       const QualType SrcType = E->getType();
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric       if (SrcType.mayBeNotDynamicClass() && DestTy.mayBeDynamicClass()) {
22860b57cec5SDimitry Andric         // Casting to pointer that could carry dynamic information (provided by
22870b57cec5SDimitry Andric         // invariant.group) requires launder.
22880b57cec5SDimitry Andric         Src = Builder.CreateLaunderInvariantGroup(Src);
22890b57cec5SDimitry Andric       } else if (SrcType.mayBeDynamicClass() && DestTy.mayBeNotDynamicClass()) {
22900b57cec5SDimitry Andric         // Casting to pointer that does not carry dynamic information (provided
22910b57cec5SDimitry Andric         // by invariant.group) requires stripping it.  Note that we don't do it
22920b57cec5SDimitry Andric         // if the source could not be dynamic type and destination could be
22930b57cec5SDimitry Andric         // dynamic because dynamic information is already laundered.  It is
22940b57cec5SDimitry Andric         // because launder(strip(src)) == launder(src), so there is no need to
22950b57cec5SDimitry Andric         // add extra strip before launder.
22960b57cec5SDimitry Andric         Src = Builder.CreateStripInvariantGroup(Src);
22970b57cec5SDimitry Andric       }
22980b57cec5SDimitry Andric     }
22990b57cec5SDimitry Andric 
23005ffd83dbSDimitry Andric     // Update heapallocsite metadata when there is an explicit pointer cast.
23015ffd83dbSDimitry Andric     if (auto *CI = dyn_cast<llvm::CallBase>(Src)) {
230206c3fb27SDimitry Andric       if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE) &&
230306c3fb27SDimitry Andric           !isa<CastExpr>(E)) {
23045ffd83dbSDimitry Andric         QualType PointeeType = DestTy->getPointeeType();
23055ffd83dbSDimitry Andric         if (!PointeeType.isNull())
23065ffd83dbSDimitry Andric           CGF.getDebugInfo()->addHeapAllocSiteMetadata(CI, PointeeType,
23075ffd83dbSDimitry Andric                                                        CE->getExprLoc());
23085ffd83dbSDimitry Andric       }
23095ffd83dbSDimitry Andric     }
23100b57cec5SDimitry Andric 
2311e8d8bef9SDimitry Andric     // If Src is a fixed vector and Dst is a scalable vector, and both have the
231281ad6265SDimitry Andric     // same element type, use the llvm.vector.insert intrinsic to perform the
231381ad6265SDimitry Andric     // bitcast.
23140fca6ea1SDimitry Andric     if (auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
23150fca6ea1SDimitry Andric       if (auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
23160fca6ea1SDimitry Andric         // If we are casting a fixed i8 vector to a scalable i1 predicate
2317349cc55cSDimitry Andric         // vector, use a vector insert and bitcast the result.
23180fca6ea1SDimitry Andric         if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
23190fca6ea1SDimitry Andric             ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
23200fca6ea1SDimitry Andric             FixedSrcTy->getElementType()->isIntegerTy(8)) {
23210fca6ea1SDimitry Andric           ScalableDstTy = llvm::ScalableVectorType::get(
23220fca6ea1SDimitry Andric               FixedSrcTy->getElementType(),
23230fca6ea1SDimitry Andric               ScalableDstTy->getElementCount().getKnownMinValue() / 8);
2324349cc55cSDimitry Andric         }
23250fca6ea1SDimitry Andric         if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
23260fca6ea1SDimitry Andric           llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy);
2327e8d8bef9SDimitry Andric           llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2328349cc55cSDimitry Andric           llvm::Value *Result = Builder.CreateInsertVector(
23290fca6ea1SDimitry Andric               ScalableDstTy, UndefVec, Src, Zero, "cast.scalable");
23300fca6ea1SDimitry Andric           if (Result->getType() != DstTy)
23310fca6ea1SDimitry Andric             Result = Builder.CreateBitCast(Result, DstTy);
2332349cc55cSDimitry Andric           return Result;
2333e8d8bef9SDimitry Andric         }
2334e8d8bef9SDimitry Andric       }
2335e8d8bef9SDimitry Andric     }
2336e8d8bef9SDimitry Andric 
2337e8d8bef9SDimitry Andric     // If Src is a scalable vector and Dst is a fixed vector, and both have the
233881ad6265SDimitry Andric     // same element type, use the llvm.vector.extract intrinsic to perform the
233981ad6265SDimitry Andric     // bitcast.
23400fca6ea1SDimitry Andric     if (auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
23410fca6ea1SDimitry Andric       if (auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
23420fca6ea1SDimitry Andric         // If we are casting a scalable i1 predicate vector to a fixed i8
2343349cc55cSDimitry Andric         // vector, bitcast the source and use a vector extract.
23440fca6ea1SDimitry Andric         if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
23450fca6ea1SDimitry Andric             ScalableSrcTy->getElementCount().isKnownMultipleOf(8) &&
23460fca6ea1SDimitry Andric             FixedDstTy->getElementType()->isIntegerTy(8)) {
23470fca6ea1SDimitry Andric           ScalableSrcTy = llvm::ScalableVectorType::get(
23480fca6ea1SDimitry Andric               FixedDstTy->getElementType(),
23490fca6ea1SDimitry Andric               ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
23500fca6ea1SDimitry Andric           Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2351349cc55cSDimitry Andric         }
23520fca6ea1SDimitry Andric         if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType()) {
2353e8d8bef9SDimitry Andric           llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
235406c3fb27SDimitry Andric           return Builder.CreateExtractVector(DstTy, Src, Zero, "cast.fixed");
2355e8d8bef9SDimitry Andric         }
2356e8d8bef9SDimitry Andric       }
2357e8d8bef9SDimitry Andric     }
2358e8d8bef9SDimitry Andric 
2359e8d8bef9SDimitry Andric     // Perform VLAT <-> VLST bitcast through memory.
23600fca6ea1SDimitry Andric     // TODO: since the llvm.vector.{insert,extract} intrinsics
2361e8d8bef9SDimitry Andric     //       require the element types of the vectors to be the same, we
2362349cc55cSDimitry Andric     //       need to keep this around for bitcasts between VLAT <-> VLST where
2363349cc55cSDimitry Andric     //       the element types of the vectors are not the same, until we figure
2364349cc55cSDimitry Andric     //       out a better way of doing these casts.
2365e8d8bef9SDimitry Andric     if ((isa<llvm::FixedVectorType>(SrcTy) &&
2366e8d8bef9SDimitry Andric          isa<llvm::ScalableVectorType>(DstTy)) ||
2367e8d8bef9SDimitry Andric         (isa<llvm::ScalableVectorType>(SrcTy) &&
2368e8d8bef9SDimitry Andric          isa<llvm::FixedVectorType>(DstTy))) {
2369fe6060f1SDimitry Andric       Address Addr = CGF.CreateDefaultAlignTempAlloca(SrcTy, "saved-value");
2370fe6060f1SDimitry Andric       LValue LV = CGF.MakeAddrLValue(Addr, E->getType());
2371e8d8bef9SDimitry Andric       CGF.EmitStoreOfScalar(Src, LV);
237206c3fb27SDimitry Andric       Addr = Addr.withElementType(CGF.ConvertTypeForMem(DestTy));
2373e8d8bef9SDimitry Andric       LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
2374e8d8bef9SDimitry Andric       DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
2375e8d8bef9SDimitry Andric       return EmitLoadOfLValue(DestLV, CE->getExprLoc());
2376e8d8bef9SDimitry Andric     }
23770fca6ea1SDimitry Andric 
23780fca6ea1SDimitry Andric     llvm::Value *Result = Builder.CreateBitCast(Src, DstTy);
23790fca6ea1SDimitry Andric     return CGF.authPointerToPointerCast(Result, E->getType(), DestTy);
23800b57cec5SDimitry Andric   }
23810b57cec5SDimitry Andric   case CK_AddressSpaceConversion: {
23820b57cec5SDimitry Andric     Expr::EvalResult Result;
23830b57cec5SDimitry Andric     if (E->EvaluateAsRValue(Result, CGF.getContext()) &&
23840b57cec5SDimitry Andric         Result.Val.isNullPointer()) {
23850b57cec5SDimitry Andric       // If E has side effect, it is emitted even if its final result is a
23860b57cec5SDimitry Andric       // null pointer. In that case, a DCE pass should be able to
23870b57cec5SDimitry Andric       // eliminate the useless instructions emitted during translating E.
23880b57cec5SDimitry Andric       if (Result.HasSideEffects)
23890b57cec5SDimitry Andric         Visit(E);
23900b57cec5SDimitry Andric       return CGF.CGM.getNullPointer(cast<llvm::PointerType>(
23910b57cec5SDimitry Andric           ConvertType(DestTy)), DestTy);
23920b57cec5SDimitry Andric     }
23930b57cec5SDimitry Andric     // Since target may map different address spaces in AST to the same address
23940b57cec5SDimitry Andric     // space, an address space conversion may end up as a bitcast.
23950b57cec5SDimitry Andric     return CGF.CGM.getTargetCodeGenInfo().performAddrSpaceCast(
23960b57cec5SDimitry Andric         CGF, Visit(E), E->getType()->getPointeeType().getAddressSpace(),
23970b57cec5SDimitry Andric         DestTy->getPointeeType().getAddressSpace(), ConvertType(DestTy));
23980b57cec5SDimitry Andric   }
23990b57cec5SDimitry Andric   case CK_AtomicToNonAtomic:
24000b57cec5SDimitry Andric   case CK_NonAtomicToAtomic:
24010b57cec5SDimitry Andric   case CK_UserDefinedConversion:
24020b57cec5SDimitry Andric     return Visit(const_cast<Expr*>(E));
24030b57cec5SDimitry Andric 
2404349cc55cSDimitry Andric   case CK_NoOp: {
24055f757f3fSDimitry Andric     return CE->changesVolatileQualification() ? EmitLoadOfLValue(CE)
24065f757f3fSDimitry Andric                                               : Visit(const_cast<Expr *>(E));
2407349cc55cSDimitry Andric   }
2408349cc55cSDimitry Andric 
24090b57cec5SDimitry Andric   case CK_BaseToDerived: {
24100b57cec5SDimitry Andric     const CXXRecordDecl *DerivedClassDecl = DestTy->getPointeeCXXRecordDecl();
24110b57cec5SDimitry Andric     assert(DerivedClassDecl && "BaseToDerived arg isn't a C++ object pointer!");
24120b57cec5SDimitry Andric 
24130b57cec5SDimitry Andric     Address Base = CGF.EmitPointerWithAlignment(E);
24140b57cec5SDimitry Andric     Address Derived =
24150b57cec5SDimitry Andric       CGF.GetAddressOfDerivedClass(Base, DerivedClassDecl,
24160b57cec5SDimitry Andric                                    CE->path_begin(), CE->path_end(),
24170b57cec5SDimitry Andric                                    CGF.ShouldNullCheckClassCastValue(CE));
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric     // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
24200b57cec5SDimitry Andric     // performed and the object is not of the derived type.
24210b57cec5SDimitry Andric     if (CGF.sanitizePerformTypeCheck())
24220b57cec5SDimitry Andric       CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
24230fca6ea1SDimitry Andric                         Derived, DestTy->getPointeeType());
24240b57cec5SDimitry Andric 
24250b57cec5SDimitry Andric     if (CGF.SanOpts.has(SanitizerKind::CFIDerivedCast))
242681ad6265SDimitry Andric       CGF.EmitVTablePtrCheckForCast(DestTy->getPointeeType(), Derived,
242781ad6265SDimitry Andric                                     /*MayBeNull=*/true,
242881ad6265SDimitry Andric                                     CodeGenFunction::CFITCK_DerivedCast,
24290b57cec5SDimitry Andric                                     CE->getBeginLoc());
24300b57cec5SDimitry Andric 
24310fca6ea1SDimitry Andric     return CGF.getAsNaturalPointerTo(Derived, CE->getType()->getPointeeType());
24320b57cec5SDimitry Andric   }
24330b57cec5SDimitry Andric   case CK_UncheckedDerivedToBase:
24340b57cec5SDimitry Andric   case CK_DerivedToBase: {
24350b57cec5SDimitry Andric     // The EmitPointerWithAlignment path does this fine; just discard
24360b57cec5SDimitry Andric     // the alignment.
24370fca6ea1SDimitry Andric     return CGF.getAsNaturalPointerTo(CGF.EmitPointerWithAlignment(CE),
24380fca6ea1SDimitry Andric                                      CE->getType()->getPointeeType());
24390b57cec5SDimitry Andric   }
24400b57cec5SDimitry Andric 
24410b57cec5SDimitry Andric   case CK_Dynamic: {
24420b57cec5SDimitry Andric     Address V = CGF.EmitPointerWithAlignment(E);
24430b57cec5SDimitry Andric     const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE);
24440b57cec5SDimitry Andric     return CGF.EmitDynamicCast(V, DCE);
24450b57cec5SDimitry Andric   }
24460b57cec5SDimitry Andric 
24470b57cec5SDimitry Andric   case CK_ArrayToPointerDecay:
24480fca6ea1SDimitry Andric     return CGF.getAsNaturalPointerTo(CGF.EmitArrayToPointerDecay(E),
24490fca6ea1SDimitry Andric                                      CE->getType()->getPointeeType());
24500b57cec5SDimitry Andric   case CK_FunctionToPointerDecay:
2451480093f4SDimitry Andric     return EmitLValue(E).getPointer(CGF);
24520b57cec5SDimitry Andric 
24530b57cec5SDimitry Andric   case CK_NullToPointer:
24540b57cec5SDimitry Andric     if (MustVisitNullValue(E))
24550b57cec5SDimitry Andric       CGF.EmitIgnoredExpr(E);
24560b57cec5SDimitry Andric 
24570b57cec5SDimitry Andric     return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
24580b57cec5SDimitry Andric                               DestTy);
24590b57cec5SDimitry Andric 
24600b57cec5SDimitry Andric   case CK_NullToMemberPointer: {
24610b57cec5SDimitry Andric     if (MustVisitNullValue(E))
24620b57cec5SDimitry Andric       CGF.EmitIgnoredExpr(E);
24630b57cec5SDimitry Andric 
24640b57cec5SDimitry Andric     const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
24650b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
24660b57cec5SDimitry Andric   }
24670b57cec5SDimitry Andric 
24680b57cec5SDimitry Andric   case CK_ReinterpretMemberPointer:
24690b57cec5SDimitry Andric   case CK_BaseToDerivedMemberPointer:
24700b57cec5SDimitry Andric   case CK_DerivedToBaseMemberPointer: {
24710b57cec5SDimitry Andric     Value *Src = Visit(E);
24720b57cec5SDimitry Andric 
24730b57cec5SDimitry Andric     // Note that the AST doesn't distinguish between checked and
24740b57cec5SDimitry Andric     // unchecked member pointer conversions, so we always have to
24750b57cec5SDimitry Andric     // implement checked conversions here.  This is inefficient when
24760b57cec5SDimitry Andric     // actual control flow may be required in order to perform the
24770b57cec5SDimitry Andric     // check, which it is for data member pointers (but not member
24780b57cec5SDimitry Andric     // function pointers on Itanium and ARM).
24790b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);
24800b57cec5SDimitry Andric   }
24810b57cec5SDimitry Andric 
24820b57cec5SDimitry Andric   case CK_ARCProduceObject:
24830b57cec5SDimitry Andric     return CGF.EmitARCRetainScalarExpr(E);
24840b57cec5SDimitry Andric   case CK_ARCConsumeObject:
24850b57cec5SDimitry Andric     return CGF.EmitObjCConsumeObject(E->getType(), Visit(E));
24860b57cec5SDimitry Andric   case CK_ARCReclaimReturnedObject:
24870b57cec5SDimitry Andric     return CGF.EmitARCReclaimReturnedObject(E, /*allowUnsafe*/ Ignored);
24880b57cec5SDimitry Andric   case CK_ARCExtendBlockObject:
24890b57cec5SDimitry Andric     return CGF.EmitARCExtendBlockObject(E);
24900b57cec5SDimitry Andric 
24910b57cec5SDimitry Andric   case CK_CopyAndAutoreleaseBlockObject:
24920b57cec5SDimitry Andric     return CGF.EmitBlockCopyAndAutorelease(Visit(E), E->getType());
24930b57cec5SDimitry Andric 
24940b57cec5SDimitry Andric   case CK_FloatingRealToComplex:
24950b57cec5SDimitry Andric   case CK_FloatingComplexCast:
24960b57cec5SDimitry Andric   case CK_IntegralRealToComplex:
24970b57cec5SDimitry Andric   case CK_IntegralComplexCast:
24980b57cec5SDimitry Andric   case CK_IntegralComplexToFloatingComplex:
24990b57cec5SDimitry Andric   case CK_FloatingComplexToIntegralComplex:
25000b57cec5SDimitry Andric   case CK_ConstructorConversion:
25010b57cec5SDimitry Andric   case CK_ToUnion:
25020fca6ea1SDimitry Andric   case CK_HLSLArrayRValue:
25030b57cec5SDimitry Andric     llvm_unreachable("scalar cast to non-scalar value");
25040b57cec5SDimitry Andric 
25050b57cec5SDimitry Andric   case CK_LValueToRValue:
25060b57cec5SDimitry Andric     assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
25070b57cec5SDimitry Andric     assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!");
25080b57cec5SDimitry Andric     return Visit(const_cast<Expr*>(E));
25090b57cec5SDimitry Andric 
25100b57cec5SDimitry Andric   case CK_IntegralToPointer: {
25110b57cec5SDimitry Andric     Value *Src = Visit(const_cast<Expr*>(E));
25120b57cec5SDimitry Andric 
25130b57cec5SDimitry Andric     // First, convert to the correct width so that we control the kind of
25140b57cec5SDimitry Andric     // extension.
25150b57cec5SDimitry Andric     auto DestLLVMTy = ConvertType(DestTy);
25160b57cec5SDimitry Andric     llvm::Type *MiddleTy = CGF.CGM.getDataLayout().getIntPtrType(DestLLVMTy);
25170b57cec5SDimitry Andric     bool InputSigned = E->getType()->isSignedIntegerOrEnumerationType();
25180b57cec5SDimitry Andric     llvm::Value* IntResult =
25190b57cec5SDimitry Andric       Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv");
25200b57cec5SDimitry Andric 
25210b57cec5SDimitry Andric     auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
25220b57cec5SDimitry Andric 
25230b57cec5SDimitry Andric     if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
25240b57cec5SDimitry Andric       // Going from integer to pointer that could be dynamic requires reloading
25250b57cec5SDimitry Andric       // dynamic information from invariant.group.
25260b57cec5SDimitry Andric       if (DestTy.mayBeDynamicClass())
25270b57cec5SDimitry Andric         IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
25280b57cec5SDimitry Andric     }
25290fca6ea1SDimitry Andric 
25300fca6ea1SDimitry Andric     IntToPtr = CGF.authPointerToPointerCast(IntToPtr, E->getType(), DestTy);
25310b57cec5SDimitry Andric     return IntToPtr;
25320b57cec5SDimitry Andric   }
25330b57cec5SDimitry Andric   case CK_PointerToIntegral: {
25340b57cec5SDimitry Andric     assert(!DestTy->isBooleanType() && "bool should use PointerToBool");
25350b57cec5SDimitry Andric     auto *PtrExpr = Visit(E);
25360b57cec5SDimitry Andric 
25370b57cec5SDimitry Andric     if (CGF.CGM.getCodeGenOpts().StrictVTablePointers) {
25380b57cec5SDimitry Andric       const QualType SrcType = E->getType();
25390b57cec5SDimitry Andric 
25400b57cec5SDimitry Andric       // Casting to integer requires stripping dynamic information as it does
25410b57cec5SDimitry Andric       // not carries it.
25420b57cec5SDimitry Andric       if (SrcType.mayBeDynamicClass())
25430b57cec5SDimitry Andric         PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
25440b57cec5SDimitry Andric     }
25450b57cec5SDimitry Andric 
25460fca6ea1SDimitry Andric     PtrExpr = CGF.authPointerToPointerCast(PtrExpr, E->getType(), DestTy);
25470b57cec5SDimitry Andric     return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
25480b57cec5SDimitry Andric   }
25490b57cec5SDimitry Andric   case CK_ToVoid: {
25500b57cec5SDimitry Andric     CGF.EmitIgnoredExpr(E);
25510b57cec5SDimitry Andric     return nullptr;
25520b57cec5SDimitry Andric   }
2553fe6060f1SDimitry Andric   case CK_MatrixCast: {
2554fe6060f1SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
2555fe6060f1SDimitry Andric                                 CE->getExprLoc());
2556fe6060f1SDimitry Andric   }
25570b57cec5SDimitry Andric   case CK_VectorSplat: {
25580b57cec5SDimitry Andric     llvm::Type *DstTy = ConvertType(DestTy);
25590b57cec5SDimitry Andric     Value *Elt = Visit(const_cast<Expr *>(E));
25600b57cec5SDimitry Andric     // Splat the element across to all elements
256181ad6265SDimitry Andric     llvm::ElementCount NumElements =
256281ad6265SDimitry Andric         cast<llvm::VectorType>(DstTy)->getElementCount();
25630b57cec5SDimitry Andric     return Builder.CreateVectorSplat(NumElements, Elt, "splat");
25640b57cec5SDimitry Andric   }
25650b57cec5SDimitry Andric 
25660b57cec5SDimitry Andric   case CK_FixedPointCast:
25670b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
25680b57cec5SDimitry Andric                                 CE->getExprLoc());
25690b57cec5SDimitry Andric 
25700b57cec5SDimitry Andric   case CK_FixedPointToBoolean:
25710b57cec5SDimitry Andric     assert(E->getType()->isFixedPointType() &&
25720b57cec5SDimitry Andric            "Expected src type to be fixed point type");
25730b57cec5SDimitry Andric     assert(DestTy->isBooleanType() && "Expected dest type to be boolean type");
25740b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
25750b57cec5SDimitry Andric                                 CE->getExprLoc());
25760b57cec5SDimitry Andric 
25770b57cec5SDimitry Andric   case CK_FixedPointToIntegral:
25780b57cec5SDimitry Andric     assert(E->getType()->isFixedPointType() &&
25790b57cec5SDimitry Andric            "Expected src type to be fixed point type");
25800b57cec5SDimitry Andric     assert(DestTy->isIntegerType() && "Expected dest type to be an integer");
25810b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
25820b57cec5SDimitry Andric                                 CE->getExprLoc());
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   case CK_IntegralToFixedPoint:
25850b57cec5SDimitry Andric     assert(E->getType()->isIntegerType() &&
25860b57cec5SDimitry Andric            "Expected src type to be an integer");
25870b57cec5SDimitry Andric     assert(DestTy->isFixedPointType() &&
25880b57cec5SDimitry Andric            "Expected dest type to be fixed point type");
25890b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
25900b57cec5SDimitry Andric                                 CE->getExprLoc());
25910b57cec5SDimitry Andric 
25920b57cec5SDimitry Andric   case CK_IntegralCast: {
25930fca6ea1SDimitry Andric     if (E->getType()->isExtVectorType() && DestTy->isExtVectorType()) {
25940fca6ea1SDimitry Andric       QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType();
25950fca6ea1SDimitry Andric       return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
25960fca6ea1SDimitry Andric                                    SrcElTy->isSignedIntegerOrEnumerationType(),
25970fca6ea1SDimitry Andric                                    "conv");
25980fca6ea1SDimitry Andric     }
25990b57cec5SDimitry Andric     ScalarConversionOpts Opts;
26000b57cec5SDimitry Andric     if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
26010b57cec5SDimitry Andric       if (!ICE->isPartOfExplicitCast())
26020b57cec5SDimitry Andric         Opts = ScalarConversionOpts(CGF.SanOpts);
26030b57cec5SDimitry Andric     }
26040b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
26050b57cec5SDimitry Andric                                 CE->getExprLoc(), Opts);
26060b57cec5SDimitry Andric   }
26070fca6ea1SDimitry Andric   case CK_IntegralToFloating: {
26080fca6ea1SDimitry Andric     if (E->getType()->isVectorType() && DestTy->isVectorType()) {
26090fca6ea1SDimitry Andric       // TODO: Support constrained FP intrinsics.
26100fca6ea1SDimitry Andric       QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType();
26110fca6ea1SDimitry Andric       if (SrcElTy->isSignedIntegerOrEnumerationType())
26120fca6ea1SDimitry Andric         return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy), "conv");
26130fca6ea1SDimitry Andric       return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy), "conv");
26140fca6ea1SDimitry Andric     }
26150fca6ea1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
26160fca6ea1SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
26170fca6ea1SDimitry Andric                                 CE->getExprLoc());
26180fca6ea1SDimitry Andric   }
26190fca6ea1SDimitry Andric   case CK_FloatingToIntegral: {
26200fca6ea1SDimitry Andric     if (E->getType()->isVectorType() && DestTy->isVectorType()) {
26210fca6ea1SDimitry Andric       // TODO: Support constrained FP intrinsics.
26220fca6ea1SDimitry Andric       QualType DstElTy = DestTy->castAs<VectorType>()->getElementType();
26230fca6ea1SDimitry Andric       if (DstElTy->isSignedIntegerOrEnumerationType())
26240fca6ea1SDimitry Andric         return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy), "conv");
26250fca6ea1SDimitry Andric       return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy), "conv");
26260fca6ea1SDimitry Andric     }
26270fca6ea1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
26280fca6ea1SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
26290fca6ea1SDimitry Andric                                 CE->getExprLoc());
26300fca6ea1SDimitry Andric   }
26310fca6ea1SDimitry Andric   case CK_FloatingCast: {
26320fca6ea1SDimitry Andric     if (E->getType()->isVectorType() && DestTy->isVectorType()) {
26330fca6ea1SDimitry Andric       // TODO: Support constrained FP intrinsics.
26340fca6ea1SDimitry Andric       QualType SrcElTy = E->getType()->castAs<VectorType>()->getElementType();
26350fca6ea1SDimitry Andric       QualType DstElTy = DestTy->castAs<VectorType>()->getElementType();
26360fca6ea1SDimitry Andric       if (DstElTy->castAs<BuiltinType>()->getKind() <
26370fca6ea1SDimitry Andric           SrcElTy->castAs<BuiltinType>()->getKind())
26380fca6ea1SDimitry Andric         return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy), "conv");
26390fca6ea1SDimitry Andric       return Builder.CreateFPExt(Visit(E), ConvertType(DestTy), "conv");
26400fca6ea1SDimitry Andric     }
26410fca6ea1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
26420fca6ea1SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
26430fca6ea1SDimitry Andric                                 CE->getExprLoc());
26440fca6ea1SDimitry Andric   }
2645e8d8bef9SDimitry Andric   case CK_FixedPointToFloating:
2646e8d8bef9SDimitry Andric   case CK_FloatingToFixedPoint: {
2647e8d8bef9SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
26480b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
26490b57cec5SDimitry Andric                                 CE->getExprLoc());
2650e8d8bef9SDimitry Andric   }
26510b57cec5SDimitry Andric   case CK_BooleanToSignedIntegral: {
26520b57cec5SDimitry Andric     ScalarConversionOpts Opts;
26530b57cec5SDimitry Andric     Opts.TreatBooleanAsSigned = true;
26540b57cec5SDimitry Andric     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
26550b57cec5SDimitry Andric                                 CE->getExprLoc(), Opts);
26560b57cec5SDimitry Andric   }
26570b57cec5SDimitry Andric   case CK_IntegralToBoolean:
26580b57cec5SDimitry Andric     return EmitIntToBoolConversion(Visit(E));
26590b57cec5SDimitry Andric   case CK_PointerToBoolean:
26600b57cec5SDimitry Andric     return EmitPointerToBoolConversion(Visit(E), E->getType());
2661e8d8bef9SDimitry Andric   case CK_FloatingToBoolean: {
2662e8d8bef9SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
26630b57cec5SDimitry Andric     return EmitFloatToBoolConversion(Visit(E));
2664e8d8bef9SDimitry Andric   }
26650b57cec5SDimitry Andric   case CK_MemberPointerToBoolean: {
26660b57cec5SDimitry Andric     llvm::Value *MemPtr = Visit(E);
26670b57cec5SDimitry Andric     const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
26680b57cec5SDimitry Andric     return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
26690b57cec5SDimitry Andric   }
26700b57cec5SDimitry Andric 
26710b57cec5SDimitry Andric   case CK_FloatingComplexToReal:
26720b57cec5SDimitry Andric   case CK_IntegralComplexToReal:
26730b57cec5SDimitry Andric     return CGF.EmitComplexExpr(E, false, true).first;
26740b57cec5SDimitry Andric 
26750b57cec5SDimitry Andric   case CK_FloatingComplexToBoolean:
26760b57cec5SDimitry Andric   case CK_IntegralComplexToBoolean: {
26770b57cec5SDimitry Andric     CodeGenFunction::ComplexPairTy V = CGF.EmitComplexExpr(E);
26780b57cec5SDimitry Andric 
26790b57cec5SDimitry Andric     // TODO: kill this function off, inline appropriate case here
26800b57cec5SDimitry Andric     return EmitComplexToScalarConversion(V, E->getType(), DestTy,
26810b57cec5SDimitry Andric                                          CE->getExprLoc());
26820b57cec5SDimitry Andric   }
26830b57cec5SDimitry Andric 
26840b57cec5SDimitry Andric   case CK_ZeroToOCLOpaqueType: {
26850b57cec5SDimitry Andric     assert((DestTy->isEventT() || DestTy->isQueueT() ||
26860b57cec5SDimitry Andric             DestTy->isOCLIntelSubgroupAVCType()) &&
26870b57cec5SDimitry Andric            "CK_ZeroToOCLEvent cast on non-event type");
26880b57cec5SDimitry Andric     return llvm::Constant::getNullValue(ConvertType(DestTy));
26890b57cec5SDimitry Andric   }
26900b57cec5SDimitry Andric 
26910b57cec5SDimitry Andric   case CK_IntToOCLSampler:
26920b57cec5SDimitry Andric     return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
26930b57cec5SDimitry Andric 
26940fca6ea1SDimitry Andric   case CK_HLSLVectorTruncation: {
26950fca6ea1SDimitry Andric     assert(DestTy->isVectorType() && "Expected dest type to be vector type");
26960fca6ea1SDimitry Andric     Value *Vec = Visit(const_cast<Expr *>(E));
26970fca6ea1SDimitry Andric     SmallVector<int, 16> Mask;
26980fca6ea1SDimitry Andric     unsigned NumElts = DestTy->castAs<VectorType>()->getNumElements();
26990fca6ea1SDimitry Andric     for (unsigned I = 0; I != NumElts; ++I)
27000fca6ea1SDimitry Andric       Mask.push_back(I);
27010fca6ea1SDimitry Andric 
27020fca6ea1SDimitry Andric     return Builder.CreateShuffleVector(Vec, Mask, "trunc");
27030fca6ea1SDimitry Andric   }
27040fca6ea1SDimitry Andric 
27050b57cec5SDimitry Andric   } // end of switch
27060b57cec5SDimitry Andric 
27070b57cec5SDimitry Andric   llvm_unreachable("unknown scalar cast");
27080b57cec5SDimitry Andric }
27090b57cec5SDimitry Andric 
VisitStmtExpr(const StmtExpr * E)27100b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
27110b57cec5SDimitry Andric   CodeGenFunction::StmtExprEvaluation eval(CGF);
27120b57cec5SDimitry Andric   Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(),
27130b57cec5SDimitry Andric                                            !E->getType()->isVoidType());
27140b57cec5SDimitry Andric   if (!RetAlloca.isValid())
27150b57cec5SDimitry Andric     return nullptr;
27160b57cec5SDimitry Andric   return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()),
27170b57cec5SDimitry Andric                               E->getExprLoc());
27180b57cec5SDimitry Andric }
27190b57cec5SDimitry Andric 
VisitExprWithCleanups(ExprWithCleanups * E)27200b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
27210b57cec5SDimitry Andric   CodeGenFunction::RunCleanupsScope Scope(CGF);
27220b57cec5SDimitry Andric   Value *V = Visit(E->getSubExpr());
27230b57cec5SDimitry Andric   // Defend against dominance problems caused by jumps out of expression
27240b57cec5SDimitry Andric   // evaluation through the shared cleanup block.
27250b57cec5SDimitry Andric   Scope.ForceCleanup({&V});
27260b57cec5SDimitry Andric   return V;
27270b57cec5SDimitry Andric }
27280b57cec5SDimitry Andric 
27290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27300b57cec5SDimitry Andric //                             Unary Operators
27310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27320b57cec5SDimitry Andric 
createBinOpInfoFromIncDec(const UnaryOperator * E,llvm::Value * InVal,bool IsInc,FPOptions FPFeatures)27330b57cec5SDimitry Andric static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E,
27345ffd83dbSDimitry Andric                                            llvm::Value *InVal, bool IsInc,
27355ffd83dbSDimitry Andric                                            FPOptions FPFeatures) {
27360b57cec5SDimitry Andric   BinOpInfo BinOp;
27370b57cec5SDimitry Andric   BinOp.LHS = InVal;
27380b57cec5SDimitry Andric   BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
27390b57cec5SDimitry Andric   BinOp.Ty = E->getType();
27400b57cec5SDimitry Andric   BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
27415ffd83dbSDimitry Andric   BinOp.FPFeatures = FPFeatures;
27420b57cec5SDimitry Andric   BinOp.E = E;
27430b57cec5SDimitry Andric   return BinOp;
27440b57cec5SDimitry Andric }
27450b57cec5SDimitry Andric 
EmitIncDecConsiderOverflowBehavior(const UnaryOperator * E,llvm::Value * InVal,bool IsInc)27460b57cec5SDimitry Andric llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
27470b57cec5SDimitry Andric     const UnaryOperator *E, llvm::Value *InVal, bool IsInc) {
27480b57cec5SDimitry Andric   llvm::Value *Amount =
27490b57cec5SDimitry Andric       llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1, true);
27500b57cec5SDimitry Andric   StringRef Name = IsInc ? "inc" : "dec";
27510b57cec5SDimitry Andric   switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
27520b57cec5SDimitry Andric   case LangOptions::SOB_Defined:
27530fca6ea1SDimitry Andric     if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
27540b57cec5SDimitry Andric       return Builder.CreateAdd(InVal, Amount, Name);
27550fca6ea1SDimitry Andric     [[fallthrough]];
27560b57cec5SDimitry Andric   case LangOptions::SOB_Undefined:
27570b57cec5SDimitry Andric     if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
27580b57cec5SDimitry Andric       return Builder.CreateNSWAdd(InVal, Amount, Name);
2759bdd1243dSDimitry Andric     [[fallthrough]];
27600b57cec5SDimitry Andric   case LangOptions::SOB_Trapping:
27610b57cec5SDimitry Andric     if (!E->canOverflow())
27620b57cec5SDimitry Andric       return Builder.CreateNSWAdd(InVal, Amount, Name);
27635ffd83dbSDimitry Andric     return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
27645ffd83dbSDimitry Andric         E, InVal, IsInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
27650b57cec5SDimitry Andric   }
27660b57cec5SDimitry Andric   llvm_unreachable("Unknown SignedOverflowBehaviorTy");
27670b57cec5SDimitry Andric }
27680b57cec5SDimitry Andric 
2769480093f4SDimitry Andric namespace {
2770480093f4SDimitry Andric /// Handles check and update for lastprivate conditional variables.
2771480093f4SDimitry Andric class OMPLastprivateConditionalUpdateRAII {
2772480093f4SDimitry Andric private:
2773480093f4SDimitry Andric   CodeGenFunction &CGF;
2774480093f4SDimitry Andric   const UnaryOperator *E;
2775480093f4SDimitry Andric 
2776480093f4SDimitry Andric public:
OMPLastprivateConditionalUpdateRAII(CodeGenFunction & CGF,const UnaryOperator * E)2777480093f4SDimitry Andric   OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
2778480093f4SDimitry Andric                                       const UnaryOperator *E)
2779480093f4SDimitry Andric       : CGF(CGF), E(E) {}
~OMPLastprivateConditionalUpdateRAII()2780480093f4SDimitry Andric   ~OMPLastprivateConditionalUpdateRAII() {
2781480093f4SDimitry Andric     if (CGF.getLangOpts().OpenMP)
2782480093f4SDimitry Andric       CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(
2783480093f4SDimitry Andric           CGF, E->getSubExpr());
2784480093f4SDimitry Andric   }
2785480093f4SDimitry Andric };
2786480093f4SDimitry Andric } // namespace
2787480093f4SDimitry Andric 
27880b57cec5SDimitry Andric llvm::Value *
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)27890b57cec5SDimitry Andric ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
27900b57cec5SDimitry Andric                                            bool isInc, bool isPre) {
2791480093f4SDimitry Andric   OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
27920b57cec5SDimitry Andric   QualType type = E->getSubExpr()->getType();
27930b57cec5SDimitry Andric   llvm::PHINode *atomicPHI = nullptr;
27940b57cec5SDimitry Andric   llvm::Value *value;
27950b57cec5SDimitry Andric   llvm::Value *input;
27960fca6ea1SDimitry Andric   llvm::Value *Previous = nullptr;
27970fca6ea1SDimitry Andric   QualType SrcType = E->getType();
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric   int amount = (isInc ? 1 : -1);
28000b57cec5SDimitry Andric   bool isSubtraction = !isInc;
28010b57cec5SDimitry Andric 
28020b57cec5SDimitry Andric   if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
28030b57cec5SDimitry Andric     type = atomicTy->getValueType();
28040b57cec5SDimitry Andric     if (isInc && type->isBooleanType()) {
28050b57cec5SDimitry Andric       llvm::Value *True = CGF.EmitToMemory(Builder.getTrue(), type);
28060b57cec5SDimitry Andric       if (isPre) {
28070fca6ea1SDimitry Andric         Builder.CreateStore(True, LV.getAddress(), LV.isVolatileQualified())
28080b57cec5SDimitry Andric             ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
28090b57cec5SDimitry Andric         return Builder.getTrue();
28100b57cec5SDimitry Andric       }
28110b57cec5SDimitry Andric       // For atomic bool increment, we just store true and return it for
28120b57cec5SDimitry Andric       // preincrement, do an atomic swap with true for postincrement
28130b57cec5SDimitry Andric       return Builder.CreateAtomicRMW(
28140fca6ea1SDimitry Andric           llvm::AtomicRMWInst::Xchg, LV.getAddress(), True,
28150b57cec5SDimitry Andric           llvm::AtomicOrdering::SequentiallyConsistent);
28160b57cec5SDimitry Andric     }
28170b57cec5SDimitry Andric     // Special case for atomic increment / decrement on integers, emit
28180b57cec5SDimitry Andric     // atomicrmw instructions.  We skip this if we want to be doing overflow
28190b57cec5SDimitry Andric     // checking, and fall into the slow path with the atomic cmpxchg loop.
28200b57cec5SDimitry Andric     if (!type->isBooleanType() && type->isIntegerType() &&
28210b57cec5SDimitry Andric         !(type->isUnsignedIntegerType() &&
28220b57cec5SDimitry Andric           CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
28230b57cec5SDimitry Andric         CGF.getLangOpts().getSignedOverflowBehavior() !=
28240b57cec5SDimitry Andric             LangOptions::SOB_Trapping) {
28250b57cec5SDimitry Andric       llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
28260b57cec5SDimitry Andric         llvm::AtomicRMWInst::Sub;
28270b57cec5SDimitry Andric       llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
28280b57cec5SDimitry Andric         llvm::Instruction::Sub;
28290b57cec5SDimitry Andric       llvm::Value *amt = CGF.EmitToMemory(
28300b57cec5SDimitry Andric           llvm::ConstantInt::get(ConvertType(type), 1, true), type);
2831480093f4SDimitry Andric       llvm::Value *old =
28320fca6ea1SDimitry Andric           Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
28330fca6ea1SDimitry Andric                                   llvm::AtomicOrdering::SequentiallyConsistent);
28340fca6ea1SDimitry Andric       return isPre ? Builder.CreateBinOp(op, old, amt) : old;
28350fca6ea1SDimitry Andric     }
2836*6e516c87SDimitry Andric     // Special case for atomic increment/decrement on floats.
2837*6e516c87SDimitry Andric     // Bail out non-power-of-2-sized floating point types (e.g., x86_fp80).
28380fca6ea1SDimitry Andric     if (type->isFloatingType()) {
2839*6e516c87SDimitry Andric       llvm::Type *Ty = ConvertType(type);
2840*6e516c87SDimitry Andric       if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
28410fca6ea1SDimitry Andric         llvm::AtomicRMWInst::BinOp aop =
28420fca6ea1SDimitry Andric             isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
28430fca6ea1SDimitry Andric         llvm::Instruction::BinaryOps op =
28440fca6ea1SDimitry Andric             isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
2845*6e516c87SDimitry Andric         llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
2846*6e516c87SDimitry Andric         llvm::AtomicRMWInst *old = Builder.CreateAtomicRMW(
2847*6e516c87SDimitry Andric             aop, LV.getAddress(), amt,
2848480093f4SDimitry Andric             llvm::AtomicOrdering::SequentiallyConsistent);
2849*6e516c87SDimitry Andric 
28500b57cec5SDimitry Andric         return isPre ? Builder.CreateBinOp(op, old, amt) : old;
28510b57cec5SDimitry Andric       }
2852*6e516c87SDimitry Andric     }
28530b57cec5SDimitry Andric     value = EmitLoadOfLValue(LV, E->getExprLoc());
28540b57cec5SDimitry Andric     input = value;
28550b57cec5SDimitry Andric     // For every other atomic operation, we need to emit a load-op-cmpxchg loop
28560b57cec5SDimitry Andric     llvm::BasicBlock *startBB = Builder.GetInsertBlock();
28570b57cec5SDimitry Andric     llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
28580b57cec5SDimitry Andric     value = CGF.EmitToMemory(value, type);
28590b57cec5SDimitry Andric     Builder.CreateBr(opBB);
28600b57cec5SDimitry Andric     Builder.SetInsertPoint(opBB);
28610b57cec5SDimitry Andric     atomicPHI = Builder.CreatePHI(value->getType(), 2);
28620b57cec5SDimitry Andric     atomicPHI->addIncoming(value, startBB);
28630b57cec5SDimitry Andric     value = atomicPHI;
28640b57cec5SDimitry Andric   } else {
28650b57cec5SDimitry Andric     value = EmitLoadOfLValue(LV, E->getExprLoc());
28660b57cec5SDimitry Andric     input = value;
28670b57cec5SDimitry Andric   }
28680b57cec5SDimitry Andric 
28690b57cec5SDimitry Andric   // Special case of integer increment that we have to check first: bool++.
28700b57cec5SDimitry Andric   // Due to promotion rules, we get:
28710b57cec5SDimitry Andric   //   bool++ -> bool = bool + 1
28720b57cec5SDimitry Andric   //          -> bool = (int)bool + 1
28730b57cec5SDimitry Andric   //          -> bool = ((int)bool + 1 != 0)
28740b57cec5SDimitry Andric   // An interesting aspect of this is that increment is always true.
28750b57cec5SDimitry Andric   // Decrement does not have this property.
28760b57cec5SDimitry Andric   if (isInc && type->isBooleanType()) {
28770b57cec5SDimitry Andric     value = Builder.getTrue();
28780b57cec5SDimitry Andric 
28790b57cec5SDimitry Andric   // Most common case by far: integer increment.
28800b57cec5SDimitry Andric   } else if (type->isIntegerType()) {
2881480093f4SDimitry Andric     QualType promotedType;
2882480093f4SDimitry Andric     bool canPerformLossyDemotionCheck = false;
2883bdd1243dSDimitry Andric     if (CGF.getContext().isPromotableIntegerType(type)) {
2884480093f4SDimitry Andric       promotedType = CGF.getContext().getPromotedIntegerType(type);
2885480093f4SDimitry Andric       assert(promotedType != type && "Shouldn't promote to the same type.");
2886480093f4SDimitry Andric       canPerformLossyDemotionCheck = true;
2887480093f4SDimitry Andric       canPerformLossyDemotionCheck &=
2888480093f4SDimitry Andric           CGF.getContext().getCanonicalType(type) !=
2889480093f4SDimitry Andric           CGF.getContext().getCanonicalType(promotedType);
2890480093f4SDimitry Andric       canPerformLossyDemotionCheck &=
2891480093f4SDimitry Andric           PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(
2892480093f4SDimitry Andric               type, promotedType);
2893480093f4SDimitry Andric       assert((!canPerformLossyDemotionCheck ||
2894480093f4SDimitry Andric               type->isSignedIntegerOrEnumerationType() ||
2895480093f4SDimitry Andric               promotedType->isSignedIntegerOrEnumerationType() ||
2896480093f4SDimitry Andric               ConvertType(type)->getScalarSizeInBits() ==
2897480093f4SDimitry Andric                   ConvertType(promotedType)->getScalarSizeInBits()) &&
2898480093f4SDimitry Andric              "The following check expects that if we do promotion to different "
2899480093f4SDimitry Andric              "underlying canonical type, at least one of the types (either "
2900480093f4SDimitry Andric              "base or promoted) will be signed, or the bitwidths will match.");
2901480093f4SDimitry Andric     }
2902480093f4SDimitry Andric     if (CGF.SanOpts.hasOneOf(
29030fca6ea1SDimitry Andric             SanitizerKind::ImplicitIntegerArithmeticValueChange |
29040fca6ea1SDimitry Andric             SanitizerKind::ImplicitBitfieldConversion) &&
2905480093f4SDimitry Andric         canPerformLossyDemotionCheck) {
2906480093f4SDimitry Andric       // While `x += 1` (for `x` with width less than int) is modeled as
2907480093f4SDimitry Andric       // promotion+arithmetics+demotion, and we can catch lossy demotion with
2908480093f4SDimitry Andric       // ease; inc/dec with width less than int can't overflow because of
2909480093f4SDimitry Andric       // promotion rules, so we omit promotion+demotion, which means that we can
2910480093f4SDimitry Andric       // not catch lossy "demotion". Because we still want to catch these cases
2911480093f4SDimitry Andric       // when the sanitizer is enabled, we perform the promotion, then perform
2912480093f4SDimitry Andric       // the increment/decrement in the wider type, and finally
2913480093f4SDimitry Andric       // perform the demotion. This will catch lossy demotions.
2914480093f4SDimitry Andric 
29150fca6ea1SDimitry Andric       // We have a special case for bitfields defined using all the bits of the
29160fca6ea1SDimitry Andric       // type. In this case we need to do the same trick as for the integer
29170fca6ea1SDimitry Andric       // sanitizer checks, i.e., promotion -> increment/decrement -> demotion.
29180fca6ea1SDimitry Andric 
2919480093f4SDimitry Andric       value = EmitScalarConversion(value, type, promotedType, E->getExprLoc());
2920480093f4SDimitry Andric       Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
2921480093f4SDimitry Andric       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
2922480093f4SDimitry Andric       // Do pass non-default ScalarConversionOpts so that sanitizer check is
29230fca6ea1SDimitry Andric       // emitted if LV is not a bitfield, otherwise the bitfield sanitizer
29240fca6ea1SDimitry Andric       // checks will take care of the conversion.
29250fca6ea1SDimitry Andric       ScalarConversionOpts Opts;
29260fca6ea1SDimitry Andric       if (!LV.isBitField())
29270fca6ea1SDimitry Andric         Opts = ScalarConversionOpts(CGF.SanOpts);
29280fca6ea1SDimitry Andric       else if (CGF.SanOpts.has(SanitizerKind::ImplicitBitfieldConversion)) {
29290fca6ea1SDimitry Andric         Previous = value;
29300fca6ea1SDimitry Andric         SrcType = promotedType;
29310fca6ea1SDimitry Andric       }
29320fca6ea1SDimitry Andric 
2933480093f4SDimitry Andric       value = EmitScalarConversion(value, promotedType, type, E->getExprLoc(),
29340fca6ea1SDimitry Andric                                    Opts);
2935480093f4SDimitry Andric 
29360b57cec5SDimitry Andric       // Note that signed integer inc/dec with width less than int can't
2937480093f4SDimitry Andric       // overflow because of promotion rules; we're just eliding a few steps
2938480093f4SDimitry Andric       // here.
2939480093f4SDimitry Andric     } else if (E->canOverflow() && type->isSignedIntegerOrEnumerationType()) {
29400b57cec5SDimitry Andric       value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
29410b57cec5SDimitry Andric     } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
29420b57cec5SDimitry Andric                CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
29435ffd83dbSDimitry Andric       value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
29445ffd83dbSDimitry Andric           E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
29450b57cec5SDimitry Andric     } else {
29460b57cec5SDimitry Andric       llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
29470b57cec5SDimitry Andric       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
29480b57cec5SDimitry Andric     }
29490b57cec5SDimitry Andric 
29500b57cec5SDimitry Andric   // Next most common: pointer increment.
29510b57cec5SDimitry Andric   } else if (const PointerType *ptr = type->getAs<PointerType>()) {
29520b57cec5SDimitry Andric     QualType type = ptr->getPointeeType();
29530b57cec5SDimitry Andric 
29540b57cec5SDimitry Andric     // VLA types don't have constant size.
29550b57cec5SDimitry Andric     if (const VariableArrayType *vla
29560b57cec5SDimitry Andric           = CGF.getContext().getAsVariableArrayType(type)) {
29570b57cec5SDimitry Andric       llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
29580b57cec5SDimitry Andric       if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
295981ad6265SDimitry Andric       llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
29600b57cec5SDimitry Andric       if (CGF.getLangOpts().isSignedOverflowDefined())
29610eae32dcSDimitry Andric         value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc");
29620b57cec5SDimitry Andric       else
29630b57cec5SDimitry Andric         value = CGF.EmitCheckedInBoundsGEP(
29640eae32dcSDimitry Andric             elemTy, value, numElts, /*SignedIndices=*/false, isSubtraction,
29650b57cec5SDimitry Andric             E->getExprLoc(), "vla.inc");
29660b57cec5SDimitry Andric 
29670b57cec5SDimitry Andric     // Arithmetic on function pointers (!) is just +-1.
29680b57cec5SDimitry Andric     } else if (type->isFunctionType()) {
29690b57cec5SDimitry Andric       llvm::Value *amt = Builder.getInt32(amount);
29700b57cec5SDimitry Andric 
29710b57cec5SDimitry Andric       if (CGF.getLangOpts().isSignedOverflowDefined())
2972fe6060f1SDimitry Andric         value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
29730b57cec5SDimitry Andric       else
297406c3fb27SDimitry Andric         value =
297506c3fb27SDimitry Andric             CGF.EmitCheckedInBoundsGEP(CGF.Int8Ty, value, amt,
297606c3fb27SDimitry Andric                                        /*SignedIndices=*/false, isSubtraction,
297706c3fb27SDimitry Andric                                        E->getExprLoc(), "incdec.funcptr");
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric     // For everything else, we can just do a simple increment.
29800b57cec5SDimitry Andric     } else {
29810b57cec5SDimitry Andric       llvm::Value *amt = Builder.getInt32(amount);
29820eae32dcSDimitry Andric       llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
29830b57cec5SDimitry Andric       if (CGF.getLangOpts().isSignedOverflowDefined())
29840eae32dcSDimitry Andric         value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr");
29850b57cec5SDimitry Andric       else
29860eae32dcSDimitry Andric         value = CGF.EmitCheckedInBoundsGEP(
29870eae32dcSDimitry Andric             elemTy, value, amt, /*SignedIndices=*/false, isSubtraction,
29880eae32dcSDimitry Andric             E->getExprLoc(), "incdec.ptr");
29890b57cec5SDimitry Andric     }
29900b57cec5SDimitry Andric 
29910b57cec5SDimitry Andric   // Vector increment/decrement.
29920b57cec5SDimitry Andric   } else if (type->isVectorType()) {
29930b57cec5SDimitry Andric     if (type->hasIntegerRepresentation()) {
29940b57cec5SDimitry Andric       llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount);
29950b57cec5SDimitry Andric 
29960b57cec5SDimitry Andric       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
29970b57cec5SDimitry Andric     } else {
29980b57cec5SDimitry Andric       value = Builder.CreateFAdd(
29990b57cec5SDimitry Andric                   value,
30000b57cec5SDimitry Andric                   llvm::ConstantFP::get(value->getType(), amount),
30010b57cec5SDimitry Andric                   isInc ? "inc" : "dec");
30020b57cec5SDimitry Andric     }
30030b57cec5SDimitry Andric 
30040b57cec5SDimitry Andric   // Floating point.
30050b57cec5SDimitry Andric   } else if (type->isRealFloatingType()) {
30060b57cec5SDimitry Andric     // Add the inc/dec to the real part.
30070b57cec5SDimitry Andric     llvm::Value *amt;
3008e8d8bef9SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
30090b57cec5SDimitry Andric 
30100b57cec5SDimitry Andric     if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
30110b57cec5SDimitry Andric       // Another special case: half FP increment should be done via float
30120b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
30130b57cec5SDimitry Andric         value = Builder.CreateCall(
30140b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
30150b57cec5SDimitry Andric                                  CGF.CGM.FloatTy),
30160b57cec5SDimitry Andric             input, "incdec.conv");
30170b57cec5SDimitry Andric       } else {
30180b57cec5SDimitry Andric         value = Builder.CreateFPExt(input, CGF.CGM.FloatTy, "incdec.conv");
30190b57cec5SDimitry Andric       }
30200b57cec5SDimitry Andric     }
30210b57cec5SDimitry Andric 
30220b57cec5SDimitry Andric     if (value->getType()->isFloatTy())
30230b57cec5SDimitry Andric       amt = llvm::ConstantFP::get(VMContext,
30240b57cec5SDimitry Andric                                   llvm::APFloat(static_cast<float>(amount)));
30250b57cec5SDimitry Andric     else if (value->getType()->isDoubleTy())
30260b57cec5SDimitry Andric       amt = llvm::ConstantFP::get(VMContext,
30270b57cec5SDimitry Andric                                   llvm::APFloat(static_cast<double>(amount)));
30280b57cec5SDimitry Andric     else {
30295f757f3fSDimitry Andric       // Remaining types are Half, Bfloat16, LongDouble, __ibm128 or __float128.
30305f757f3fSDimitry Andric       // Convert from float.
30310b57cec5SDimitry Andric       llvm::APFloat F(static_cast<float>(amount));
30320b57cec5SDimitry Andric       bool ignored;
30330b57cec5SDimitry Andric       const llvm::fltSemantics *FS;
30340b57cec5SDimitry Andric       // Don't use getFloatTypeSemantics because Half isn't
30350b57cec5SDimitry Andric       // necessarily represented using the "half" LLVM type.
30360b57cec5SDimitry Andric       if (value->getType()->isFP128Ty())
30370b57cec5SDimitry Andric         FS = &CGF.getTarget().getFloat128Format();
30380b57cec5SDimitry Andric       else if (value->getType()->isHalfTy())
30390b57cec5SDimitry Andric         FS = &CGF.getTarget().getHalfFormat();
30405f757f3fSDimitry Andric       else if (value->getType()->isBFloatTy())
30415f757f3fSDimitry Andric         FS = &CGF.getTarget().getBFloat16Format();
3042349cc55cSDimitry Andric       else if (value->getType()->isPPC_FP128Ty())
3043349cc55cSDimitry Andric         FS = &CGF.getTarget().getIbm128Format();
30440b57cec5SDimitry Andric       else
30450b57cec5SDimitry Andric         FS = &CGF.getTarget().getLongDoubleFormat();
30460b57cec5SDimitry Andric       F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
30470b57cec5SDimitry Andric       amt = llvm::ConstantFP::get(VMContext, F);
30480b57cec5SDimitry Andric     }
30490b57cec5SDimitry Andric     value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
30500b57cec5SDimitry Andric 
30510b57cec5SDimitry Andric     if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
30520b57cec5SDimitry Andric       if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
30530b57cec5SDimitry Andric         value = Builder.CreateCall(
30540b57cec5SDimitry Andric             CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,
30550b57cec5SDimitry Andric                                  CGF.CGM.FloatTy),
30560b57cec5SDimitry Andric             value, "incdec.conv");
30570b57cec5SDimitry Andric       } else {
30580b57cec5SDimitry Andric         value = Builder.CreateFPTrunc(value, input->getType(), "incdec.conv");
30590b57cec5SDimitry Andric       }
30600b57cec5SDimitry Andric     }
30610b57cec5SDimitry Andric 
30625ffd83dbSDimitry Andric   // Fixed-point types.
30635ffd83dbSDimitry Andric   } else if (type->isFixedPointType()) {
30645ffd83dbSDimitry Andric     // Fixed-point types are tricky. In some cases, it isn't possible to
30655ffd83dbSDimitry Andric     // represent a 1 or a -1 in the type at all. Piggyback off of
30665ffd83dbSDimitry Andric     // EmitFixedPointBinOp to avoid having to reimplement saturation.
30675ffd83dbSDimitry Andric     BinOpInfo Info;
30685ffd83dbSDimitry Andric     Info.E = E;
30695ffd83dbSDimitry Andric     Info.Ty = E->getType();
30705ffd83dbSDimitry Andric     Info.Opcode = isInc ? BO_Add : BO_Sub;
30715ffd83dbSDimitry Andric     Info.LHS = value;
30725ffd83dbSDimitry Andric     Info.RHS = llvm::ConstantInt::get(value->getType(), 1, false);
30735ffd83dbSDimitry Andric     // If the type is signed, it's better to represent this as +(-1) or -(-1),
30745ffd83dbSDimitry Andric     // since -1 is guaranteed to be representable.
30755ffd83dbSDimitry Andric     if (type->isSignedFixedPointType()) {
30765ffd83dbSDimitry Andric       Info.Opcode = isInc ? BO_Sub : BO_Add;
30775ffd83dbSDimitry Andric       Info.RHS = Builder.CreateNeg(Info.RHS);
30785ffd83dbSDimitry Andric     }
30795ffd83dbSDimitry Andric     // Now, convert from our invented integer literal to the type of the unary
30805ffd83dbSDimitry Andric     // op. This will upscale and saturate if necessary. This value can become
30815ffd83dbSDimitry Andric     // undef in some cases.
3082e8d8bef9SDimitry Andric     llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3083e8d8bef9SDimitry Andric     auto DstSema = CGF.getContext().getFixedPointSemantics(Info.Ty);
3084e8d8bef9SDimitry Andric     Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS, true, DstSema);
30855ffd83dbSDimitry Andric     value = EmitFixedPointBinOp(Info);
30865ffd83dbSDimitry Andric 
30870b57cec5SDimitry Andric   // Objective-C pointer types.
30880b57cec5SDimitry Andric   } else {
30890b57cec5SDimitry Andric     const ObjCObjectPointerType *OPT = type->castAs<ObjCObjectPointerType>();
30900b57cec5SDimitry Andric 
30910b57cec5SDimitry Andric     CharUnits size = CGF.getContext().getTypeSizeInChars(OPT->getObjectType());
30920b57cec5SDimitry Andric     if (!isInc) size = -size;
30930b57cec5SDimitry Andric     llvm::Value *sizeValue =
30940b57cec5SDimitry Andric       llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
30950b57cec5SDimitry Andric 
30960b57cec5SDimitry Andric     if (CGF.getLangOpts().isSignedOverflowDefined())
3097fe6060f1SDimitry Andric       value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
30980b57cec5SDimitry Andric     else
30990eae32dcSDimitry Andric       value = CGF.EmitCheckedInBoundsGEP(
31000eae32dcSDimitry Andric           CGF.Int8Ty, value, sizeValue, /*SignedIndices=*/false, isSubtraction,
31010b57cec5SDimitry Andric           E->getExprLoc(), "incdec.objptr");
31020b57cec5SDimitry Andric     value = Builder.CreateBitCast(value, input->getType());
31030b57cec5SDimitry Andric   }
31040b57cec5SDimitry Andric 
31050b57cec5SDimitry Andric   if (atomicPHI) {
31060b57cec5SDimitry Andric     llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
31070b57cec5SDimitry Andric     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
31080b57cec5SDimitry Andric     auto Pair = CGF.EmitAtomicCompareExchange(
31090b57cec5SDimitry Andric         LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
31100b57cec5SDimitry Andric     llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
31110b57cec5SDimitry Andric     llvm::Value *success = Pair.second;
31120b57cec5SDimitry Andric     atomicPHI->addIncoming(old, curBlock);
31130b57cec5SDimitry Andric     Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
31140b57cec5SDimitry Andric     Builder.SetInsertPoint(contBB);
31150b57cec5SDimitry Andric     return isPre ? value : input;
31160b57cec5SDimitry Andric   }
31170b57cec5SDimitry Andric 
31180b57cec5SDimitry Andric   // Store the updated result through the lvalue.
31190fca6ea1SDimitry Andric   if (LV.isBitField()) {
31200fca6ea1SDimitry Andric     Value *Src = Previous ? Previous : value;
31210b57cec5SDimitry Andric     CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
31220fca6ea1SDimitry Andric     CGF.EmitBitfieldConversionCheck(Src, SrcType, value, E->getType(),
31230fca6ea1SDimitry Andric                                     LV.getBitFieldInfo(), E->getExprLoc());
31240fca6ea1SDimitry Andric   } else
31250b57cec5SDimitry Andric     CGF.EmitStoreThroughLValue(RValue::get(value), LV);
31260b57cec5SDimitry Andric 
31270b57cec5SDimitry Andric   // If this is a postinc, return the value read from memory, otherwise use the
31280b57cec5SDimitry Andric   // updated value.
31290b57cec5SDimitry Andric   return isPre ? value : input;
31300b57cec5SDimitry Andric }
31310b57cec5SDimitry Andric 
31320b57cec5SDimitry Andric 
VisitUnaryPlus(const UnaryOperator * E,QualType PromotionType)3133bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
3134bdd1243dSDimitry Andric                                          QualType PromotionType) {
3135bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
3136bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
3137bdd1243dSDimitry Andric                              : PromotionType;
3138bdd1243dSDimitry Andric   Value *result = VisitPlus(E, promotionTy);
3139bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
3140bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
3141bdd1243dSDimitry Andric   return result;
3142bdd1243dSDimitry Andric }
31430b57cec5SDimitry Andric 
VisitPlus(const UnaryOperator * E,QualType PromotionType)3144bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitPlus(const UnaryOperator *E,
3145bdd1243dSDimitry Andric                                     QualType PromotionType) {
3146bdd1243dSDimitry Andric   // This differs from gcc, though, most likely due to a bug in gcc.
31470b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
3148bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3149bdd1243dSDimitry Andric     return CGF.EmitPromotedScalarExpr(E->getSubExpr(), PromotionType);
3150bdd1243dSDimitry Andric   return Visit(E->getSubExpr());
3151bdd1243dSDimitry Andric }
3152bdd1243dSDimitry Andric 
VisitUnaryMinus(const UnaryOperator * E,QualType PromotionType)3153bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
3154bdd1243dSDimitry Andric                                           QualType PromotionType) {
3155bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
3156bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
3157bdd1243dSDimitry Andric                              : PromotionType;
3158bdd1243dSDimitry Andric   Value *result = VisitMinus(E, promotionTy);
3159bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
3160bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
3161bdd1243dSDimitry Andric   return result;
3162bdd1243dSDimitry Andric }
3163bdd1243dSDimitry Andric 
VisitMinus(const UnaryOperator * E,QualType PromotionType)3164bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitMinus(const UnaryOperator *E,
3165bdd1243dSDimitry Andric                                      QualType PromotionType) {
3166bdd1243dSDimitry Andric   TestAndClearIgnoreResultAssign();
3167bdd1243dSDimitry Andric   Value *Op;
3168bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3169bdd1243dSDimitry Andric     Op = CGF.EmitPromotedScalarExpr(E->getSubExpr(), PromotionType);
3170bdd1243dSDimitry Andric   else
3171bdd1243dSDimitry Andric     Op = Visit(E->getSubExpr());
3172a7dea167SDimitry Andric 
3173a7dea167SDimitry Andric   // Generate a unary FNeg for FP ops.
3174a7dea167SDimitry Andric   if (Op->getType()->isFPOrFPVectorTy())
3175a7dea167SDimitry Andric     return Builder.CreateFNeg(Op, "fneg");
3176a7dea167SDimitry Andric 
31770b57cec5SDimitry Andric   // Emit unary minus with EmitSub so we handle overflow cases etc.
31780b57cec5SDimitry Andric   BinOpInfo BinOp;
3179a7dea167SDimitry Andric   BinOp.RHS = Op;
31800b57cec5SDimitry Andric   BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
31810b57cec5SDimitry Andric   BinOp.Ty = E->getType();
31820b57cec5SDimitry Andric   BinOp.Opcode = BO_Sub;
31835ffd83dbSDimitry Andric   BinOp.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
31840b57cec5SDimitry Andric   BinOp.E = E;
31850b57cec5SDimitry Andric   return EmitSub(BinOp);
31860b57cec5SDimitry Andric }
31870b57cec5SDimitry Andric 
VisitUnaryNot(const UnaryOperator * E)31880b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
31890b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
31900b57cec5SDimitry Andric   Value *Op = Visit(E->getSubExpr());
3191bdd1243dSDimitry Andric   return Builder.CreateNot(Op, "not");
31920b57cec5SDimitry Andric }
31930b57cec5SDimitry Andric 
VisitUnaryLNot(const UnaryOperator * E)31940b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
31950b57cec5SDimitry Andric   // Perform vector logical not on comparison with zero vector.
31965ffd83dbSDimitry Andric   if (E->getType()->isVectorType() &&
31975ffd83dbSDimitry Andric       E->getType()->castAs<VectorType>()->getVectorKind() ==
31985f757f3fSDimitry Andric           VectorKind::Generic) {
31990b57cec5SDimitry Andric     Value *Oper = Visit(E->getSubExpr());
32000b57cec5SDimitry Andric     Value *Zero = llvm::Constant::getNullValue(Oper->getType());
32010b57cec5SDimitry Andric     Value *Result;
32025ffd83dbSDimitry Andric     if (Oper->getType()->isFPOrFPVectorTy()) {
32035ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
32045ffd83dbSDimitry Andric           CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
32050b57cec5SDimitry Andric       Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
32065ffd83dbSDimitry Andric     } else
32070b57cec5SDimitry Andric       Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
32080b57cec5SDimitry Andric     return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
32090b57cec5SDimitry Andric   }
32100b57cec5SDimitry Andric 
32110b57cec5SDimitry Andric   // Compare operand to zero.
32120b57cec5SDimitry Andric   Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
32130b57cec5SDimitry Andric 
32140b57cec5SDimitry Andric   // Invert value.
32150b57cec5SDimitry Andric   // TODO: Could dynamically modify easy computations here.  For example, if
32160b57cec5SDimitry Andric   // the operand is an icmp ne, turn into icmp eq.
32170b57cec5SDimitry Andric   BoolVal = Builder.CreateNot(BoolVal, "lnot");
32180b57cec5SDimitry Andric 
32190b57cec5SDimitry Andric   // ZExt result to the expr type.
32200b57cec5SDimitry Andric   return Builder.CreateZExt(BoolVal, ConvertType(E->getType()), "lnot.ext");
32210b57cec5SDimitry Andric }
32220b57cec5SDimitry Andric 
VisitOffsetOfExpr(OffsetOfExpr * E)32230b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
32240b57cec5SDimitry Andric   // Try folding the offsetof to a constant.
32250b57cec5SDimitry Andric   Expr::EvalResult EVResult;
32260b57cec5SDimitry Andric   if (E->EvaluateAsInt(EVResult, CGF.getContext())) {
32270b57cec5SDimitry Andric     llvm::APSInt Value = EVResult.Val.getInt();
32280b57cec5SDimitry Andric     return Builder.getInt(Value);
32290b57cec5SDimitry Andric   }
32300b57cec5SDimitry Andric 
32310b57cec5SDimitry Andric   // Loop over the components of the offsetof to compute the value.
32320b57cec5SDimitry Andric   unsigned n = E->getNumComponents();
32330b57cec5SDimitry Andric   llvm::Type* ResultType = ConvertType(E->getType());
32340b57cec5SDimitry Andric   llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
32350b57cec5SDimitry Andric   QualType CurrentType = E->getTypeSourceInfo()->getType();
32360b57cec5SDimitry Andric   for (unsigned i = 0; i != n; ++i) {
32370b57cec5SDimitry Andric     OffsetOfNode ON = E->getComponent(i);
32380b57cec5SDimitry Andric     llvm::Value *Offset = nullptr;
32390b57cec5SDimitry Andric     switch (ON.getKind()) {
32400b57cec5SDimitry Andric     case OffsetOfNode::Array: {
32410b57cec5SDimitry Andric       // Compute the index
32420b57cec5SDimitry Andric       Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
32430b57cec5SDimitry Andric       llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
32440b57cec5SDimitry Andric       bool IdxSigned = IdxExpr->getType()->isSignedIntegerOrEnumerationType();
32450b57cec5SDimitry Andric       Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned, "conv");
32460b57cec5SDimitry Andric 
32470b57cec5SDimitry Andric       // Save the element type
32480b57cec5SDimitry Andric       CurrentType =
32490b57cec5SDimitry Andric           CGF.getContext().getAsArrayType(CurrentType)->getElementType();
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric       // Compute the element size
32520b57cec5SDimitry Andric       llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
32530b57cec5SDimitry Andric           CGF.getContext().getTypeSizeInChars(CurrentType).getQuantity());
32540b57cec5SDimitry Andric 
32550b57cec5SDimitry Andric       // Multiply out to compute the result
32560b57cec5SDimitry Andric       Offset = Builder.CreateMul(Idx, ElemSize);
32570b57cec5SDimitry Andric       break;
32580b57cec5SDimitry Andric     }
32590b57cec5SDimitry Andric 
32600b57cec5SDimitry Andric     case OffsetOfNode::Field: {
32610b57cec5SDimitry Andric       FieldDecl *MemberDecl = ON.getField();
3262a7dea167SDimitry Andric       RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
32630b57cec5SDimitry Andric       const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
32640b57cec5SDimitry Andric 
32650b57cec5SDimitry Andric       // Compute the index of the field in its parent.
32660b57cec5SDimitry Andric       unsigned i = 0;
32670b57cec5SDimitry Andric       // FIXME: It would be nice if we didn't have to loop here!
32680b57cec5SDimitry Andric       for (RecordDecl::field_iterator Field = RD->field_begin(),
32690b57cec5SDimitry Andric                                       FieldEnd = RD->field_end();
32700b57cec5SDimitry Andric            Field != FieldEnd; ++Field, ++i) {
32710b57cec5SDimitry Andric         if (*Field == MemberDecl)
32720b57cec5SDimitry Andric           break;
32730b57cec5SDimitry Andric       }
32740b57cec5SDimitry Andric       assert(i < RL.getFieldCount() && "offsetof field in wrong type");
32750b57cec5SDimitry Andric 
32760b57cec5SDimitry Andric       // Compute the offset to the field
32770b57cec5SDimitry Andric       int64_t OffsetInt = RL.getFieldOffset(i) /
32780b57cec5SDimitry Andric                           CGF.getContext().getCharWidth();
32790b57cec5SDimitry Andric       Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
32800b57cec5SDimitry Andric 
32810b57cec5SDimitry Andric       // Save the element type.
32820b57cec5SDimitry Andric       CurrentType = MemberDecl->getType();
32830b57cec5SDimitry Andric       break;
32840b57cec5SDimitry Andric     }
32850b57cec5SDimitry Andric 
32860b57cec5SDimitry Andric     case OffsetOfNode::Identifier:
32870b57cec5SDimitry Andric       llvm_unreachable("dependent __builtin_offsetof");
32880b57cec5SDimitry Andric 
32890b57cec5SDimitry Andric     case OffsetOfNode::Base: {
32900b57cec5SDimitry Andric       if (ON.getBase()->isVirtual()) {
32910b57cec5SDimitry Andric         CGF.ErrorUnsupported(E, "virtual base in offsetof");
32920b57cec5SDimitry Andric         continue;
32930b57cec5SDimitry Andric       }
32940b57cec5SDimitry Andric 
3295a7dea167SDimitry Andric       RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
32960b57cec5SDimitry Andric       const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
32970b57cec5SDimitry Andric 
32980b57cec5SDimitry Andric       // Save the element type.
32990b57cec5SDimitry Andric       CurrentType = ON.getBase()->getType();
33000b57cec5SDimitry Andric 
33010b57cec5SDimitry Andric       // Compute the offset to the base.
330281ad6265SDimitry Andric       auto *BaseRT = CurrentType->castAs<RecordType>();
330381ad6265SDimitry Andric       auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
33040b57cec5SDimitry Andric       CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD);
33050b57cec5SDimitry Andric       Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
33060b57cec5SDimitry Andric       break;
33070b57cec5SDimitry Andric     }
33080b57cec5SDimitry Andric     }
33090b57cec5SDimitry Andric     Result = Builder.CreateAdd(Result, Offset);
33100b57cec5SDimitry Andric   }
33110b57cec5SDimitry Andric   return Result;
33120b57cec5SDimitry Andric }
33130b57cec5SDimitry Andric 
33140b57cec5SDimitry Andric /// VisitUnaryExprOrTypeTraitExpr - Return the size or alignment of the type of
33150b57cec5SDimitry Andric /// argument of the sizeof expression as an integer.
33160b57cec5SDimitry Andric Value *
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)33170b57cec5SDimitry Andric ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
33180b57cec5SDimitry Andric                               const UnaryExprOrTypeTraitExpr *E) {
33190b57cec5SDimitry Andric   QualType TypeToSize = E->getTypeOfArgument();
33205f757f3fSDimitry Andric   if (auto Kind = E->getKind();
33215f757f3fSDimitry Andric       Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
33220b57cec5SDimitry Andric     if (const VariableArrayType *VAT =
33230b57cec5SDimitry Andric             CGF.getContext().getAsVariableArrayType(TypeToSize)) {
33240b57cec5SDimitry Andric       if (E->isArgumentType()) {
33250b57cec5SDimitry Andric         // sizeof(type) - make sure to emit the VLA size.
33260b57cec5SDimitry Andric         CGF.EmitVariablyModifiedType(TypeToSize);
33270b57cec5SDimitry Andric       } else {
33280b57cec5SDimitry Andric         // C99 6.5.3.4p2: If the argument is an expression of type
33290b57cec5SDimitry Andric         // VLA, it is evaluated.
33300b57cec5SDimitry Andric         CGF.EmitIgnoredExpr(E->getArgumentExpr());
33310b57cec5SDimitry Andric       }
33320b57cec5SDimitry Andric 
33330b57cec5SDimitry Andric       auto VlaSize = CGF.getVLASize(VAT);
33340b57cec5SDimitry Andric       llvm::Value *size = VlaSize.NumElts;
33350b57cec5SDimitry Andric 
33360b57cec5SDimitry Andric       // Scale the number of non-VLA elements by the non-VLA element size.
33370b57cec5SDimitry Andric       CharUnits eltSize = CGF.getContext().getTypeSizeInChars(VlaSize.Type);
33380b57cec5SDimitry Andric       if (!eltSize.isOne())
33390b57cec5SDimitry Andric         size = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), size);
33400b57cec5SDimitry Andric 
33410b57cec5SDimitry Andric       return size;
33420b57cec5SDimitry Andric     }
33430b57cec5SDimitry Andric   } else if (E->getKind() == UETT_OpenMPRequiredSimdAlign) {
33440b57cec5SDimitry Andric     auto Alignment =
33450b57cec5SDimitry Andric         CGF.getContext()
33460b57cec5SDimitry Andric             .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
33470b57cec5SDimitry Andric                 E->getTypeOfArgument()->getPointeeType()))
33480b57cec5SDimitry Andric             .getQuantity();
33490b57cec5SDimitry Andric     return llvm::ConstantInt::get(CGF.SizeTy, Alignment);
33505f757f3fSDimitry Andric   } else if (E->getKind() == UETT_VectorElements) {
33515f757f3fSDimitry Andric     auto *VecTy = cast<llvm::VectorType>(ConvertType(E->getTypeOfArgument()));
33525f757f3fSDimitry Andric     return Builder.CreateElementCount(CGF.SizeTy, VecTy->getElementCount());
33530b57cec5SDimitry Andric   }
33540b57cec5SDimitry Andric 
33550b57cec5SDimitry Andric   // If this isn't sizeof(vla), the result must be constant; use the constant
33560b57cec5SDimitry Andric   // folding logic so we don't have to duplicate it here.
33570b57cec5SDimitry Andric   return Builder.getInt(E->EvaluateKnownConstInt(CGF.getContext()));
33580b57cec5SDimitry Andric }
33590b57cec5SDimitry Andric 
VisitUnaryReal(const UnaryOperator * E,QualType PromotionType)3360bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E,
3361bdd1243dSDimitry Andric                                          QualType PromotionType) {
3362bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
3363bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
3364bdd1243dSDimitry Andric                              : PromotionType;
3365bdd1243dSDimitry Andric   Value *result = VisitReal(E, promotionTy);
3366bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
3367bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
3368bdd1243dSDimitry Andric   return result;
3369bdd1243dSDimitry Andric }
3370bdd1243dSDimitry Andric 
VisitReal(const UnaryOperator * E,QualType PromotionType)3371bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitReal(const UnaryOperator *E,
3372bdd1243dSDimitry Andric                                     QualType PromotionType) {
33730b57cec5SDimitry Andric   Expr *Op = E->getSubExpr();
33740b57cec5SDimitry Andric   if (Op->getType()->isAnyComplexType()) {
33750b57cec5SDimitry Andric     // If it's an l-value, load through the appropriate subobject l-value.
33760b57cec5SDimitry Andric     // Note that we have to ask E because Op might be an l-value that
33770b57cec5SDimitry Andric     // this won't work for, e.g. an Obj-C property.
3378bdd1243dSDimitry Andric     if (E->isGLValue())  {
3379bdd1243dSDimitry Andric       if (!PromotionType.isNull()) {
3380bdd1243dSDimitry Andric         CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
3381bdd1243dSDimitry Andric             Op, /*IgnoreReal*/ IgnoreResultAssign, /*IgnoreImag*/ true);
3382bdd1243dSDimitry Andric         if (result.first)
3383bdd1243dSDimitry Andric           result.first = CGF.EmitPromotedValue(result, PromotionType).first;
3384bdd1243dSDimitry Andric         return result.first;
3385bdd1243dSDimitry Andric       } else {
3386bdd1243dSDimitry Andric         return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3387bdd1243dSDimitry Andric             .getScalarVal();
3388bdd1243dSDimitry Andric       }
3389bdd1243dSDimitry Andric     }
33900b57cec5SDimitry Andric     // Otherwise, calculate and project.
33910b57cec5SDimitry Andric     return CGF.EmitComplexExpr(Op, false, true).first;
33920b57cec5SDimitry Andric   }
33930b57cec5SDimitry Andric 
3394bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3395bdd1243dSDimitry Andric     return CGF.EmitPromotedScalarExpr(Op, PromotionType);
33960b57cec5SDimitry Andric   return Visit(Op);
33970b57cec5SDimitry Andric }
33980b57cec5SDimitry Andric 
VisitUnaryImag(const UnaryOperator * E,QualType PromotionType)3399bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E,
3400bdd1243dSDimitry Andric                                          QualType PromotionType) {
3401bdd1243dSDimitry Andric   QualType promotionTy = PromotionType.isNull()
3402bdd1243dSDimitry Andric                              ? getPromotionType(E->getSubExpr()->getType())
3403bdd1243dSDimitry Andric                              : PromotionType;
3404bdd1243dSDimitry Andric   Value *result = VisitImag(E, promotionTy);
3405bdd1243dSDimitry Andric   if (result && !promotionTy.isNull())
3406bdd1243dSDimitry Andric     result = EmitUnPromotedValue(result, E->getType());
3407bdd1243dSDimitry Andric   return result;
3408bdd1243dSDimitry Andric }
3409bdd1243dSDimitry Andric 
VisitImag(const UnaryOperator * E,QualType PromotionType)3410bdd1243dSDimitry Andric Value *ScalarExprEmitter::VisitImag(const UnaryOperator *E,
3411bdd1243dSDimitry Andric                                     QualType PromotionType) {
34120b57cec5SDimitry Andric   Expr *Op = E->getSubExpr();
34130b57cec5SDimitry Andric   if (Op->getType()->isAnyComplexType()) {
34140b57cec5SDimitry Andric     // If it's an l-value, load through the appropriate subobject l-value.
34150b57cec5SDimitry Andric     // Note that we have to ask E because Op might be an l-value that
34160b57cec5SDimitry Andric     // this won't work for, e.g. an Obj-C property.
3417bdd1243dSDimitry Andric     if (Op->isGLValue()) {
3418bdd1243dSDimitry Andric       if (!PromotionType.isNull()) {
3419bdd1243dSDimitry Andric         CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
3420bdd1243dSDimitry Andric             Op, /*IgnoreReal*/ true, /*IgnoreImag*/ IgnoreResultAssign);
3421bdd1243dSDimitry Andric         if (result.second)
3422bdd1243dSDimitry Andric           result.second = CGF.EmitPromotedValue(result, PromotionType).second;
3423bdd1243dSDimitry Andric         return result.second;
3424bdd1243dSDimitry Andric       } else {
3425bdd1243dSDimitry Andric         return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3426bdd1243dSDimitry Andric             .getScalarVal();
3427bdd1243dSDimitry Andric       }
3428bdd1243dSDimitry Andric     }
34290b57cec5SDimitry Andric     // Otherwise, calculate and project.
34300b57cec5SDimitry Andric     return CGF.EmitComplexExpr(Op, true, false).second;
34310b57cec5SDimitry Andric   }
34320b57cec5SDimitry Andric 
34330b57cec5SDimitry Andric   // __imag on a scalar returns zero.  Emit the subexpr to ensure side
34340b57cec5SDimitry Andric   // effects are evaluated, but not the actual value.
34350b57cec5SDimitry Andric   if (Op->isGLValue())
34360b57cec5SDimitry Andric     CGF.EmitLValue(Op);
3437bdd1243dSDimitry Andric   else if (!PromotionType.isNull())
3438bdd1243dSDimitry Andric     CGF.EmitPromotedScalarExpr(Op, PromotionType);
34390b57cec5SDimitry Andric   else
34400b57cec5SDimitry Andric     CGF.EmitScalarExpr(Op, true);
3441bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3442bdd1243dSDimitry Andric     return llvm::Constant::getNullValue(ConvertType(PromotionType));
34430b57cec5SDimitry Andric   return llvm::Constant::getNullValue(ConvertType(E->getType()));
34440b57cec5SDimitry Andric }
34450b57cec5SDimitry Andric 
34460b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
34470b57cec5SDimitry Andric //                           Binary Operators
34480b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
34490b57cec5SDimitry Andric 
EmitPromotedValue(Value * result,QualType PromotionType)3450bdd1243dSDimitry Andric Value *ScalarExprEmitter::EmitPromotedValue(Value *result,
3451bdd1243dSDimitry Andric                                             QualType PromotionType) {
3452bdd1243dSDimitry Andric   return CGF.Builder.CreateFPExt(result, ConvertType(PromotionType), "ext");
3453bdd1243dSDimitry Andric }
3454bdd1243dSDimitry Andric 
EmitUnPromotedValue(Value * result,QualType ExprType)3455bdd1243dSDimitry Andric Value *ScalarExprEmitter::EmitUnPromotedValue(Value *result,
3456bdd1243dSDimitry Andric                                               QualType ExprType) {
3457bdd1243dSDimitry Andric   return CGF.Builder.CreateFPTrunc(result, ConvertType(ExprType), "unpromotion");
3458bdd1243dSDimitry Andric }
3459bdd1243dSDimitry Andric 
EmitPromoted(const Expr * E,QualType PromotionType)3460bdd1243dSDimitry Andric Value *ScalarExprEmitter::EmitPromoted(const Expr *E, QualType PromotionType) {
3461bdd1243dSDimitry Andric   E = E->IgnoreParens();
3462bdd1243dSDimitry Andric   if (auto BO = dyn_cast<BinaryOperator>(E)) {
3463bdd1243dSDimitry Andric     switch (BO->getOpcode()) {
3464bdd1243dSDimitry Andric #define HANDLE_BINOP(OP)                                                       \
3465bdd1243dSDimitry Andric   case BO_##OP:                                                                \
3466bdd1243dSDimitry Andric     return Emit##OP(EmitBinOps(BO, PromotionType));
3467bdd1243dSDimitry Andric       HANDLE_BINOP(Add)
3468bdd1243dSDimitry Andric       HANDLE_BINOP(Sub)
3469bdd1243dSDimitry Andric       HANDLE_BINOP(Mul)
3470bdd1243dSDimitry Andric       HANDLE_BINOP(Div)
3471bdd1243dSDimitry Andric #undef HANDLE_BINOP
3472bdd1243dSDimitry Andric     default:
3473bdd1243dSDimitry Andric       break;
3474bdd1243dSDimitry Andric     }
3475bdd1243dSDimitry Andric   } else if (auto UO = dyn_cast<UnaryOperator>(E)) {
3476bdd1243dSDimitry Andric     switch (UO->getOpcode()) {
3477bdd1243dSDimitry Andric     case UO_Imag:
3478bdd1243dSDimitry Andric       return VisitImag(UO, PromotionType);
3479bdd1243dSDimitry Andric     case UO_Real:
3480bdd1243dSDimitry Andric       return VisitReal(UO, PromotionType);
3481bdd1243dSDimitry Andric     case UO_Minus:
3482bdd1243dSDimitry Andric       return VisitMinus(UO, PromotionType);
3483bdd1243dSDimitry Andric     case UO_Plus:
3484bdd1243dSDimitry Andric       return VisitPlus(UO, PromotionType);
3485bdd1243dSDimitry Andric     default:
3486bdd1243dSDimitry Andric       break;
3487bdd1243dSDimitry Andric     }
3488bdd1243dSDimitry Andric   }
3489bdd1243dSDimitry Andric   auto result = Visit(const_cast<Expr *>(E));
3490bdd1243dSDimitry Andric   if (result) {
3491bdd1243dSDimitry Andric     if (!PromotionType.isNull())
3492bdd1243dSDimitry Andric       return EmitPromotedValue(result, PromotionType);
3493bdd1243dSDimitry Andric     else
3494bdd1243dSDimitry Andric       return EmitUnPromotedValue(result, E->getType());
3495bdd1243dSDimitry Andric   }
3496bdd1243dSDimitry Andric   return result;
3497bdd1243dSDimitry Andric }
3498bdd1243dSDimitry Andric 
EmitBinOps(const BinaryOperator * E,QualType PromotionType)3499bdd1243dSDimitry Andric BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E,
3500bdd1243dSDimitry Andric                                         QualType PromotionType) {
35010b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
35020b57cec5SDimitry Andric   BinOpInfo Result;
3503bdd1243dSDimitry Andric   Result.LHS = CGF.EmitPromotedScalarExpr(E->getLHS(), PromotionType);
3504bdd1243dSDimitry Andric   Result.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionType);
3505bdd1243dSDimitry Andric   if (!PromotionType.isNull())
3506bdd1243dSDimitry Andric     Result.Ty = PromotionType;
3507bdd1243dSDimitry Andric   else
35080b57cec5SDimitry Andric     Result.Ty  = E->getType();
35090b57cec5SDimitry Andric   Result.Opcode = E->getOpcode();
35105ffd83dbSDimitry Andric   Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
35110b57cec5SDimitry Andric   Result.E = E;
35120b57cec5SDimitry Andric   return Result;
35130b57cec5SDimitry Andric }
35140b57cec5SDimitry Andric 
EmitCompoundAssignLValue(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &),Value * & Result)35150b57cec5SDimitry Andric LValue ScalarExprEmitter::EmitCompoundAssignLValue(
35160b57cec5SDimitry Andric                                               const CompoundAssignOperator *E,
35170b57cec5SDimitry Andric                         Value *(ScalarExprEmitter::*Func)(const BinOpInfo &),
35180b57cec5SDimitry Andric                                                    Value *&Result) {
35190b57cec5SDimitry Andric   QualType LHSTy = E->getLHS()->getType();
35200b57cec5SDimitry Andric   BinOpInfo OpInfo;
35210b57cec5SDimitry Andric 
35220b57cec5SDimitry Andric   if (E->getComputationResultType()->isAnyComplexType())
35230b57cec5SDimitry Andric     return CGF.EmitScalarCompoundAssignWithComplex(E, Result);
35240b57cec5SDimitry Andric 
35250b57cec5SDimitry Andric   // Emit the RHS first.  __block variables need to have the rhs evaluated
35260b57cec5SDimitry Andric   // first, plus this should improve codegen a little.
3527bdd1243dSDimitry Andric 
3528bdd1243dSDimitry Andric   QualType PromotionTypeCR;
3529bdd1243dSDimitry Andric   PromotionTypeCR = getPromotionType(E->getComputationResultType());
3530bdd1243dSDimitry Andric   if (PromotionTypeCR.isNull())
3531bdd1243dSDimitry Andric       PromotionTypeCR = E->getComputationResultType();
3532bdd1243dSDimitry Andric   QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType());
3533bdd1243dSDimitry Andric   QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType());
3534bdd1243dSDimitry Andric   if (!PromotionTypeRHS.isNull())
3535bdd1243dSDimitry Andric     OpInfo.RHS = CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS);
3536bdd1243dSDimitry Andric   else
35370b57cec5SDimitry Andric     OpInfo.RHS = Visit(E->getRHS());
3538bdd1243dSDimitry Andric   OpInfo.Ty = PromotionTypeCR;
35390b57cec5SDimitry Andric   OpInfo.Opcode = E->getOpcode();
35405ffd83dbSDimitry Andric   OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
35410b57cec5SDimitry Andric   OpInfo.E = E;
35420b57cec5SDimitry Andric   // Load/convert the LHS.
35430b57cec5SDimitry Andric   LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
35440b57cec5SDimitry Andric 
35450b57cec5SDimitry Andric   llvm::PHINode *atomicPHI = nullptr;
35460b57cec5SDimitry Andric   if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
35470b57cec5SDimitry Andric     QualType type = atomicTy->getValueType();
35480b57cec5SDimitry Andric     if (!type->isBooleanType() && type->isIntegerType() &&
35490b57cec5SDimitry Andric         !(type->isUnsignedIntegerType() &&
35500b57cec5SDimitry Andric           CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) &&
35510b57cec5SDimitry Andric         CGF.getLangOpts().getSignedOverflowBehavior() !=
35520b57cec5SDimitry Andric             LangOptions::SOB_Trapping) {
3553480093f4SDimitry Andric       llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3554480093f4SDimitry Andric       llvm::Instruction::BinaryOps Op;
35550b57cec5SDimitry Andric       switch (OpInfo.Opcode) {
35560b57cec5SDimitry Andric         // We don't have atomicrmw operands for *, %, /, <<, >>
35570b57cec5SDimitry Andric         case BO_MulAssign: case BO_DivAssign:
35580b57cec5SDimitry Andric         case BO_RemAssign:
35590b57cec5SDimitry Andric         case BO_ShlAssign:
35600b57cec5SDimitry Andric         case BO_ShrAssign:
35610b57cec5SDimitry Andric           break;
35620b57cec5SDimitry Andric         case BO_AddAssign:
3563480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Add;
3564480093f4SDimitry Andric           Op = llvm::Instruction::Add;
35650b57cec5SDimitry Andric           break;
35660b57cec5SDimitry Andric         case BO_SubAssign:
3567480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Sub;
3568480093f4SDimitry Andric           Op = llvm::Instruction::Sub;
35690b57cec5SDimitry Andric           break;
35700b57cec5SDimitry Andric         case BO_AndAssign:
3571480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::And;
3572480093f4SDimitry Andric           Op = llvm::Instruction::And;
35730b57cec5SDimitry Andric           break;
35740b57cec5SDimitry Andric         case BO_XorAssign:
3575480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Xor;
3576480093f4SDimitry Andric           Op = llvm::Instruction::Xor;
35770b57cec5SDimitry Andric           break;
35780b57cec5SDimitry Andric         case BO_OrAssign:
3579480093f4SDimitry Andric           AtomicOp = llvm::AtomicRMWInst::Or;
3580480093f4SDimitry Andric           Op = llvm::Instruction::Or;
35810b57cec5SDimitry Andric           break;
35820b57cec5SDimitry Andric         default:
35830b57cec5SDimitry Andric           llvm_unreachable("Invalid compound assignment type");
35840b57cec5SDimitry Andric       }
3585480093f4SDimitry Andric       if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3586480093f4SDimitry Andric         llvm::Value *Amt = CGF.EmitToMemory(
35870b57cec5SDimitry Andric             EmitScalarConversion(OpInfo.RHS, E->getRHS()->getType(), LHSTy,
35880b57cec5SDimitry Andric                                  E->getExprLoc()),
35890b57cec5SDimitry Andric             LHSTy);
3590480093f4SDimitry Andric         Value *OldVal = Builder.CreateAtomicRMW(
35910fca6ea1SDimitry Andric             AtomicOp, LHSLV.getAddress(), Amt,
35920b57cec5SDimitry Andric             llvm::AtomicOrdering::SequentiallyConsistent);
3593480093f4SDimitry Andric 
3594480093f4SDimitry Andric         // Since operation is atomic, the result type is guaranteed to be the
3595480093f4SDimitry Andric         // same as the input in LLVM terms.
3596480093f4SDimitry Andric         Result = Builder.CreateBinOp(Op, OldVal, Amt);
35970b57cec5SDimitry Andric         return LHSLV;
35980b57cec5SDimitry Andric       }
35990b57cec5SDimitry Andric     }
36000b57cec5SDimitry Andric     // FIXME: For floating point types, we should be saving and restoring the
36010b57cec5SDimitry Andric     // floating point environment in the loop.
36020b57cec5SDimitry Andric     llvm::BasicBlock *startBB = Builder.GetInsertBlock();
36030b57cec5SDimitry Andric     llvm::BasicBlock *opBB = CGF.createBasicBlock("atomic_op", CGF.CurFn);
36040b57cec5SDimitry Andric     OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
36050b57cec5SDimitry Andric     OpInfo.LHS = CGF.EmitToMemory(OpInfo.LHS, type);
36060b57cec5SDimitry Andric     Builder.CreateBr(opBB);
36070b57cec5SDimitry Andric     Builder.SetInsertPoint(opBB);
36080b57cec5SDimitry Andric     atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
36090b57cec5SDimitry Andric     atomicPHI->addIncoming(OpInfo.LHS, startBB);
36100b57cec5SDimitry Andric     OpInfo.LHS = atomicPHI;
36110b57cec5SDimitry Andric   }
36120b57cec5SDimitry Andric   else
36130b57cec5SDimitry Andric     OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->getExprLoc());
36140b57cec5SDimitry Andric 
3615e8d8bef9SDimitry Andric   CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
36160b57cec5SDimitry Andric   SourceLocation Loc = E->getExprLoc();
3617bdd1243dSDimitry Andric   if (!PromotionTypeLHS.isNull())
3618bdd1243dSDimitry Andric     OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
3619bdd1243dSDimitry Andric                                       E->getExprLoc());
3620bdd1243dSDimitry Andric   else
3621bdd1243dSDimitry Andric     OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
3622bdd1243dSDimitry Andric                                       E->getComputationLHSType(), Loc);
36230b57cec5SDimitry Andric 
36240b57cec5SDimitry Andric   // Expand the binary operator.
36250b57cec5SDimitry Andric   Result = (this->*Func)(OpInfo);
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric   // Convert the result back to the LHS type,
36280b57cec5SDimitry Andric   // potentially with Implicit Conversion sanitizer check.
36290fca6ea1SDimitry Andric   // If LHSLV is a bitfield, use default ScalarConversionOpts
36300fca6ea1SDimitry Andric   // to avoid emit any implicit integer checks.
36310fca6ea1SDimitry Andric   Value *Previous = nullptr;
36320fca6ea1SDimitry Andric   if (LHSLV.isBitField()) {
36330fca6ea1SDimitry Andric     Previous = Result;
36340fca6ea1SDimitry Andric     Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc);
36350fca6ea1SDimitry Andric   } else
3636bdd1243dSDimitry Andric     Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc,
3637bdd1243dSDimitry Andric                                   ScalarConversionOpts(CGF.SanOpts));
36380b57cec5SDimitry Andric 
36390b57cec5SDimitry Andric   if (atomicPHI) {
36400b57cec5SDimitry Andric     llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
36410b57cec5SDimitry Andric     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
36420b57cec5SDimitry Andric     auto Pair = CGF.EmitAtomicCompareExchange(
36430b57cec5SDimitry Andric         LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc());
36440b57cec5SDimitry Andric     llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy);
36450b57cec5SDimitry Andric     llvm::Value *success = Pair.second;
36460b57cec5SDimitry Andric     atomicPHI->addIncoming(old, curBlock);
36470b57cec5SDimitry Andric     Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
36480b57cec5SDimitry Andric     Builder.SetInsertPoint(contBB);
36490b57cec5SDimitry Andric     return LHSLV;
36500b57cec5SDimitry Andric   }
36510b57cec5SDimitry Andric 
36520b57cec5SDimitry Andric   // Store the result value into the LHS lvalue. Bit-fields are handled
36530b57cec5SDimitry Andric   // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
36540b57cec5SDimitry Andric   // 'An assignment expression has the value of the left operand after the
36550b57cec5SDimitry Andric   // assignment...'.
36560fca6ea1SDimitry Andric   if (LHSLV.isBitField()) {
36570fca6ea1SDimitry Andric     Value *Src = Previous ? Previous : Result;
36580fca6ea1SDimitry Andric     QualType SrcType = E->getRHS()->getType();
36590fca6ea1SDimitry Andric     QualType DstType = E->getLHS()->getType();
36600b57cec5SDimitry Andric     CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
36610fca6ea1SDimitry Andric     CGF.EmitBitfieldConversionCheck(Src, SrcType, Result, DstType,
36620fca6ea1SDimitry Andric                                     LHSLV.getBitFieldInfo(), E->getExprLoc());
36630fca6ea1SDimitry Andric   } else
36640b57cec5SDimitry Andric     CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
36650b57cec5SDimitry Andric 
3666480093f4SDimitry Andric   if (CGF.getLangOpts().OpenMP)
3667480093f4SDimitry Andric     CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
3668480093f4SDimitry Andric                                                                   E->getLHS());
36690b57cec5SDimitry Andric   return LHSLV;
36700b57cec5SDimitry Andric }
36710b57cec5SDimitry Andric 
EmitCompoundAssign(const CompoundAssignOperator * E,Value * (ScalarExprEmitter::* Func)(const BinOpInfo &))36720b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
36730b57cec5SDimitry Andric                       Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
36740b57cec5SDimitry Andric   bool Ignore = TestAndClearIgnoreResultAssign();
36750b57cec5SDimitry Andric   Value *RHS = nullptr;
36760b57cec5SDimitry Andric   LValue LHS = EmitCompoundAssignLValue(E, Func, RHS);
36770b57cec5SDimitry Andric 
36780b57cec5SDimitry Andric   // If the result is clearly ignored, return now.
36790b57cec5SDimitry Andric   if (Ignore)
36800b57cec5SDimitry Andric     return nullptr;
36810b57cec5SDimitry Andric 
36820b57cec5SDimitry Andric   // The result of an assignment in C is the assigned r-value.
36830b57cec5SDimitry Andric   if (!CGF.getLangOpts().CPlusPlus)
36840b57cec5SDimitry Andric     return RHS;
36850b57cec5SDimitry Andric 
36860b57cec5SDimitry Andric   // If the lvalue is non-volatile, return the computed value of the assignment.
36870b57cec5SDimitry Andric   if (!LHS.isVolatileQualified())
36880b57cec5SDimitry Andric     return RHS;
36890b57cec5SDimitry Andric 
36900b57cec5SDimitry Andric   // Otherwise, reload the value.
36910b57cec5SDimitry Andric   return EmitLoadOfLValue(LHS, E->getExprLoc());
36920b57cec5SDimitry Andric }
36930b57cec5SDimitry Andric 
EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo & Ops,llvm::Value * Zero,bool isDiv)36940b57cec5SDimitry Andric void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
36950b57cec5SDimitry Andric     const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
36960b57cec5SDimitry Andric   SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
36970b57cec5SDimitry Andric 
36980b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
36990b57cec5SDimitry Andric     Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
37000b57cec5SDimitry Andric                                     SanitizerKind::IntegerDivideByZero));
37010b57cec5SDimitry Andric   }
37020b57cec5SDimitry Andric 
37030b57cec5SDimitry Andric   const auto *BO = cast<BinaryOperator>(Ops.E);
37040b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
37050b57cec5SDimitry Andric       Ops.Ty->hasSignedIntegerRepresentation() &&
37060b57cec5SDimitry Andric       !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) &&
37070b57cec5SDimitry Andric       Ops.mayHaveIntegerOverflow()) {
37080b57cec5SDimitry Andric     llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
37090b57cec5SDimitry Andric 
37100b57cec5SDimitry Andric     llvm::Value *IntMin =
37110b57cec5SDimitry Andric       Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
3712fe6060f1SDimitry Andric     llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
37130b57cec5SDimitry Andric 
37140b57cec5SDimitry Andric     llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
37150b57cec5SDimitry Andric     llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
37160b57cec5SDimitry Andric     llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
37170b57cec5SDimitry Andric     Checks.push_back(
37180b57cec5SDimitry Andric         std::make_pair(NotOverflow, SanitizerKind::SignedIntegerOverflow));
37190b57cec5SDimitry Andric   }
37200b57cec5SDimitry Andric 
37210b57cec5SDimitry Andric   if (Checks.size() > 0)
37220b57cec5SDimitry Andric     EmitBinOpCheck(Checks, Ops);
37230b57cec5SDimitry Andric }
37240b57cec5SDimitry Andric 
EmitDiv(const BinOpInfo & Ops)37250b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
37260b57cec5SDimitry Andric   {
37270b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
37280b57cec5SDimitry Andric     if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
37290b57cec5SDimitry Andric          CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
37300b57cec5SDimitry Andric         Ops.Ty->isIntegerType() &&
37310b57cec5SDimitry Andric         (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
37320b57cec5SDimitry Andric       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
37330b57cec5SDimitry Andric       EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
37340b57cec5SDimitry Andric     } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
37350b57cec5SDimitry Andric                Ops.Ty->isRealFloatingType() &&
37360b57cec5SDimitry Andric                Ops.mayHaveFloatDivisionByZero()) {
37370b57cec5SDimitry Andric       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
37380b57cec5SDimitry Andric       llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
37390b57cec5SDimitry Andric       EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
37400b57cec5SDimitry Andric                      Ops);
37410b57cec5SDimitry Andric     }
37420b57cec5SDimitry Andric   }
37430b57cec5SDimitry Andric 
3744fe6060f1SDimitry Andric   if (Ops.Ty->isConstantMatrixType()) {
374581ad6265SDimitry Andric     llvm::MatrixBuilder MB(Builder);
3746fe6060f1SDimitry Andric     // We need to check the types of the operands of the operator to get the
3747fe6060f1SDimitry Andric     // correct matrix dimensions.
3748fe6060f1SDimitry Andric     auto *BO = cast<BinaryOperator>(Ops.E);
3749fe6060f1SDimitry Andric     (void)BO;
3750fe6060f1SDimitry Andric     assert(
3751fe6060f1SDimitry Andric         isa<ConstantMatrixType>(BO->getLHS()->getType().getCanonicalType()) &&
3752fe6060f1SDimitry Andric         "first operand must be a matrix");
3753fe6060f1SDimitry Andric     assert(BO->getRHS()->getType().getCanonicalType()->isArithmeticType() &&
3754fe6060f1SDimitry Andric            "second operand must be an arithmetic type");
3755fe6060f1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
3756fe6060f1SDimitry Andric     return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
3757fe6060f1SDimitry Andric                               Ops.Ty->hasUnsignedIntegerRepresentation());
3758fe6060f1SDimitry Andric   }
3759fe6060f1SDimitry Andric 
37600b57cec5SDimitry Andric   if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
37615ffd83dbSDimitry Andric     llvm::Value *Val;
37625ffd83dbSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
37635ffd83dbSDimitry Andric     Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
376406c3fb27SDimitry Andric     CGF.SetDivFPAccuracy(Val);
37650b57cec5SDimitry Andric     return Val;
37660b57cec5SDimitry Andric   }
37675ffd83dbSDimitry Andric   else if (Ops.isFixedPointOp())
37685ffd83dbSDimitry Andric     return EmitFixedPointBinOp(Ops);
37690b57cec5SDimitry Andric   else if (Ops.Ty->hasUnsignedIntegerRepresentation())
37700b57cec5SDimitry Andric     return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
37710b57cec5SDimitry Andric   else
37720b57cec5SDimitry Andric     return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
37730b57cec5SDimitry Andric }
37740b57cec5SDimitry Andric 
EmitRem(const BinOpInfo & Ops)37750b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
37760b57cec5SDimitry Andric   // Rem in C can't be a floating point type: C99 6.5.5p2.
37770b57cec5SDimitry Andric   if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
37780b57cec5SDimitry Andric        CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
37790b57cec5SDimitry Andric       Ops.Ty->isIntegerType() &&
37800b57cec5SDimitry Andric       (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
37810b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
37820b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
37830b57cec5SDimitry Andric     EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
37840b57cec5SDimitry Andric   }
37850b57cec5SDimitry Andric 
37860b57cec5SDimitry Andric   if (Ops.Ty->hasUnsignedIntegerRepresentation())
37870b57cec5SDimitry Andric     return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
37880b57cec5SDimitry Andric   else
37890b57cec5SDimitry Andric     return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
37900b57cec5SDimitry Andric }
37910b57cec5SDimitry Andric 
EmitOverflowCheckedBinOp(const BinOpInfo & Ops)37920b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
37930b57cec5SDimitry Andric   unsigned IID;
37940b57cec5SDimitry Andric   unsigned OpID = 0;
3795e8d8bef9SDimitry Andric   SanitizerHandler OverflowKind;
37960b57cec5SDimitry Andric 
37970b57cec5SDimitry Andric   bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
37980b57cec5SDimitry Andric   switch (Ops.Opcode) {
37990b57cec5SDimitry Andric   case BO_Add:
38000b57cec5SDimitry Andric   case BO_AddAssign:
38010b57cec5SDimitry Andric     OpID = 1;
38020b57cec5SDimitry Andric     IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
38030b57cec5SDimitry Andric                      llvm::Intrinsic::uadd_with_overflow;
3804e8d8bef9SDimitry Andric     OverflowKind = SanitizerHandler::AddOverflow;
38050b57cec5SDimitry Andric     break;
38060b57cec5SDimitry Andric   case BO_Sub:
38070b57cec5SDimitry Andric   case BO_SubAssign:
38080b57cec5SDimitry Andric     OpID = 2;
38090b57cec5SDimitry Andric     IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
38100b57cec5SDimitry Andric                      llvm::Intrinsic::usub_with_overflow;
3811e8d8bef9SDimitry Andric     OverflowKind = SanitizerHandler::SubOverflow;
38120b57cec5SDimitry Andric     break;
38130b57cec5SDimitry Andric   case BO_Mul:
38140b57cec5SDimitry Andric   case BO_MulAssign:
38150b57cec5SDimitry Andric     OpID = 3;
38160b57cec5SDimitry Andric     IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
38170b57cec5SDimitry Andric                      llvm::Intrinsic::umul_with_overflow;
3818e8d8bef9SDimitry Andric     OverflowKind = SanitizerHandler::MulOverflow;
38190b57cec5SDimitry Andric     break;
38200b57cec5SDimitry Andric   default:
38210b57cec5SDimitry Andric     llvm_unreachable("Unsupported operation for overflow detection");
38220b57cec5SDimitry Andric   }
38230b57cec5SDimitry Andric   OpID <<= 1;
38240b57cec5SDimitry Andric   if (isSigned)
38250b57cec5SDimitry Andric     OpID |= 1;
38260b57cec5SDimitry Andric 
38270b57cec5SDimitry Andric   CodeGenFunction::SanitizerScope SanScope(&CGF);
38280b57cec5SDimitry Andric   llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
38290b57cec5SDimitry Andric 
38300b57cec5SDimitry Andric   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
38310b57cec5SDimitry Andric 
38320b57cec5SDimitry Andric   Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
38330b57cec5SDimitry Andric   Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
38340b57cec5SDimitry Andric   Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
38350b57cec5SDimitry Andric 
38360b57cec5SDimitry Andric   // Handle overflow with llvm.trap if no custom handler has been specified.
38370b57cec5SDimitry Andric   const std::string *handlerName =
38380b57cec5SDimitry Andric     &CGF.getLangOpts().OverflowHandler;
38390b57cec5SDimitry Andric   if (handlerName->empty()) {
38400b57cec5SDimitry Andric     // If the signed-integer-overflow sanitizer is enabled, emit a call to its
38410b57cec5SDimitry Andric     // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
38420b57cec5SDimitry Andric     if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
38430b57cec5SDimitry Andric       llvm::Value *NotOverflow = Builder.CreateNot(overflow);
38440b57cec5SDimitry Andric       SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
38450b57cec5SDimitry Andric                               : SanitizerKind::UnsignedIntegerOverflow;
38460b57cec5SDimitry Andric       EmitBinOpCheck(std::make_pair(NotOverflow, Kind), Ops);
38470b57cec5SDimitry Andric     } else
3848e8d8bef9SDimitry Andric       CGF.EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
38490b57cec5SDimitry Andric     return result;
38500b57cec5SDimitry Andric   }
38510b57cec5SDimitry Andric 
38520b57cec5SDimitry Andric   // Branch in case of overflow.
38530b57cec5SDimitry Andric   llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
38540b57cec5SDimitry Andric   llvm::BasicBlock *continueBB =
38550b57cec5SDimitry Andric       CGF.createBasicBlock("nooverflow", CGF.CurFn, initialBB->getNextNode());
38560b57cec5SDimitry Andric   llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
38570b57cec5SDimitry Andric 
38580b57cec5SDimitry Andric   Builder.CreateCondBr(overflow, overflowBB, continueBB);
38590b57cec5SDimitry Andric 
38600b57cec5SDimitry Andric   // If an overflow handler is set, then we want to call it and then use its
38610b57cec5SDimitry Andric   // result, if it returns.
38620b57cec5SDimitry Andric   Builder.SetInsertPoint(overflowBB);
38630b57cec5SDimitry Andric 
38640b57cec5SDimitry Andric   // Get the overflow handler.
38650b57cec5SDimitry Andric   llvm::Type *Int8Ty = CGF.Int8Ty;
38660b57cec5SDimitry Andric   llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty };
38670b57cec5SDimitry Andric   llvm::FunctionType *handlerTy =
38680b57cec5SDimitry Andric       llvm::FunctionType::get(CGF.Int64Ty, argTypes, true);
38690b57cec5SDimitry Andric   llvm::FunctionCallee handler =
38700b57cec5SDimitry Andric       CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
38710b57cec5SDimitry Andric 
38720b57cec5SDimitry Andric   // Sign extend the args to 64-bit, so that we can use the same handler for
38730b57cec5SDimitry Andric   // all types of overflow.
38740b57cec5SDimitry Andric   llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty);
38750b57cec5SDimitry Andric   llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty);
38760b57cec5SDimitry Andric 
38770b57cec5SDimitry Andric   // Call the handler with the two arguments, the operation, and the size of
38780b57cec5SDimitry Andric   // the result.
38790b57cec5SDimitry Andric   llvm::Value *handlerArgs[] = {
38800b57cec5SDimitry Andric     lhs,
38810b57cec5SDimitry Andric     rhs,
38820b57cec5SDimitry Andric     Builder.getInt8(OpID),
38830b57cec5SDimitry Andric     Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth())
38840b57cec5SDimitry Andric   };
38850b57cec5SDimitry Andric   llvm::Value *handlerResult =
38860b57cec5SDimitry Andric     CGF.EmitNounwindRuntimeCall(handler, handlerArgs);
38870b57cec5SDimitry Andric 
38880b57cec5SDimitry Andric   // Truncate the result back to the desired size.
38890b57cec5SDimitry Andric   handlerResult = Builder.CreateTrunc(handlerResult, opTy);
38900b57cec5SDimitry Andric   Builder.CreateBr(continueBB);
38910b57cec5SDimitry Andric 
38920b57cec5SDimitry Andric   Builder.SetInsertPoint(continueBB);
38930b57cec5SDimitry Andric   llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
38940b57cec5SDimitry Andric   phi->addIncoming(result, initialBB);
38950b57cec5SDimitry Andric   phi->addIncoming(handlerResult, overflowBB);
38960b57cec5SDimitry Andric 
38970b57cec5SDimitry Andric   return phi;
38980b57cec5SDimitry Andric }
38990b57cec5SDimitry Andric 
39000b57cec5SDimitry Andric /// Emit pointer + index arithmetic.
emitPointerArithmetic(CodeGenFunction & CGF,const BinOpInfo & op,bool isSubtraction)39010b57cec5SDimitry Andric static Value *emitPointerArithmetic(CodeGenFunction &CGF,
39020b57cec5SDimitry Andric                                     const BinOpInfo &op,
39030b57cec5SDimitry Andric                                     bool isSubtraction) {
39040b57cec5SDimitry Andric   // Must have binary (not unary) expr here.  Unary pointer
39050b57cec5SDimitry Andric   // increment/decrement doesn't use this path.
39060b57cec5SDimitry Andric   const BinaryOperator *expr = cast<BinaryOperator>(op.E);
39070b57cec5SDimitry Andric 
39080b57cec5SDimitry Andric   Value *pointer = op.LHS;
39090b57cec5SDimitry Andric   Expr *pointerOperand = expr->getLHS();
39100b57cec5SDimitry Andric   Value *index = op.RHS;
39110b57cec5SDimitry Andric   Expr *indexOperand = expr->getRHS();
39120b57cec5SDimitry Andric 
39130b57cec5SDimitry Andric   // In a subtraction, the LHS is always the pointer.
39140b57cec5SDimitry Andric   if (!isSubtraction && !pointer->getType()->isPointerTy()) {
39150b57cec5SDimitry Andric     std::swap(pointer, index);
39160b57cec5SDimitry Andric     std::swap(pointerOperand, indexOperand);
39170b57cec5SDimitry Andric   }
39180b57cec5SDimitry Andric 
39190b57cec5SDimitry Andric   bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
39200b57cec5SDimitry Andric 
39210b57cec5SDimitry Andric   unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
39220b57cec5SDimitry Andric   auto &DL = CGF.CGM.getDataLayout();
39230b57cec5SDimitry Andric   auto PtrTy = cast<llvm::PointerType>(pointer->getType());
39240b57cec5SDimitry Andric 
39250b57cec5SDimitry Andric   // Some versions of glibc and gcc use idioms (particularly in their malloc
39260b57cec5SDimitry Andric   // routines) that add a pointer-sized integer (known to be a pointer value)
39270b57cec5SDimitry Andric   // to a null pointer in order to cast the value back to an integer or as
39280b57cec5SDimitry Andric   // part of a pointer alignment algorithm.  This is undefined behavior, but
39290b57cec5SDimitry Andric   // we'd like to be able to compile programs that use it.
39300b57cec5SDimitry Andric   //
39310b57cec5SDimitry Andric   // Normally, we'd generate a GEP with a null-pointer base here in response
39320b57cec5SDimitry Andric   // to that code, but it's also UB to dereference a pointer created that
39330b57cec5SDimitry Andric   // way.  Instead (as an acknowledged hack to tolerate the idiom) we will
39340b57cec5SDimitry Andric   // generate a direct cast of the integer value to a pointer.
39350b57cec5SDimitry Andric   //
39360b57cec5SDimitry Andric   // The idiom (p = nullptr + N) is not met if any of the following are true:
39370b57cec5SDimitry Andric   //
39380b57cec5SDimitry Andric   //   The operation is subtraction.
39390b57cec5SDimitry Andric   //   The index is not pointer-sized.
39400b57cec5SDimitry Andric   //   The pointer type is not byte-sized.
39410b57cec5SDimitry Andric   //
39420b57cec5SDimitry Andric   if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(),
39430b57cec5SDimitry Andric                                                        op.Opcode,
39440b57cec5SDimitry Andric                                                        expr->getLHS(),
39450b57cec5SDimitry Andric                                                        expr->getRHS()))
39460b57cec5SDimitry Andric     return CGF.Builder.CreateIntToPtr(index, pointer->getType());
39470b57cec5SDimitry Andric 
3948480093f4SDimitry Andric   if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
39490b57cec5SDimitry Andric     // Zero-extend or sign-extend the pointer value according to
39500b57cec5SDimitry Andric     // whether the index is signed or not.
3951480093f4SDimitry Andric     index = CGF.Builder.CreateIntCast(index, DL.getIndexType(PtrTy), isSigned,
39520b57cec5SDimitry Andric                                       "idx.ext");
39530b57cec5SDimitry Andric   }
39540b57cec5SDimitry Andric 
39550b57cec5SDimitry Andric   // If this is subtraction, negate the index.
39560b57cec5SDimitry Andric   if (isSubtraction)
39570b57cec5SDimitry Andric     index = CGF.Builder.CreateNeg(index, "idx.neg");
39580b57cec5SDimitry Andric 
39590b57cec5SDimitry Andric   if (CGF.SanOpts.has(SanitizerKind::ArrayBounds))
39600b57cec5SDimitry Andric     CGF.EmitBoundsCheck(op.E, pointerOperand, index, indexOperand->getType(),
39610b57cec5SDimitry Andric                         /*Accessed*/ false);
39620b57cec5SDimitry Andric 
39630b57cec5SDimitry Andric   const PointerType *pointerType
39640b57cec5SDimitry Andric     = pointerOperand->getType()->getAs<PointerType>();
39650b57cec5SDimitry Andric   if (!pointerType) {
39660b57cec5SDimitry Andric     QualType objectType = pointerOperand->getType()
39670b57cec5SDimitry Andric                                         ->castAs<ObjCObjectPointerType>()
39680b57cec5SDimitry Andric                                         ->getPointeeType();
39690b57cec5SDimitry Andric     llvm::Value *objectSize
39700b57cec5SDimitry Andric       = CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(objectType));
39710b57cec5SDimitry Andric 
39720b57cec5SDimitry Andric     index = CGF.Builder.CreateMul(index, objectSize);
39730b57cec5SDimitry Andric 
39745f757f3fSDimitry Andric     Value *result =
39755f757f3fSDimitry Andric         CGF.Builder.CreateGEP(CGF.Int8Ty, pointer, index, "add.ptr");
39760b57cec5SDimitry Andric     return CGF.Builder.CreateBitCast(result, pointer->getType());
39770b57cec5SDimitry Andric   }
39780b57cec5SDimitry Andric 
39790b57cec5SDimitry Andric   QualType elementType = pointerType->getPointeeType();
39800b57cec5SDimitry Andric   if (const VariableArrayType *vla
39810b57cec5SDimitry Andric         = CGF.getContext().getAsVariableArrayType(elementType)) {
39820b57cec5SDimitry Andric     // The element count here is the total number of non-VLA elements.
39830b57cec5SDimitry Andric     llvm::Value *numElements = CGF.getVLASize(vla).NumElts;
39840b57cec5SDimitry Andric 
39850b57cec5SDimitry Andric     // Effectively, the multiply by the VLA size is part of the GEP.
39860b57cec5SDimitry Andric     // GEP indexes are signed, and scaling an index isn't permitted to
39870b57cec5SDimitry Andric     // signed-overflow, so we use the same semantics for our explicit
39880b57cec5SDimitry Andric     // multiply.  We suppress this if overflow is not undefined behavior.
398981ad6265SDimitry Andric     llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
39900b57cec5SDimitry Andric     if (CGF.getLangOpts().isSignedOverflowDefined()) {
39910b57cec5SDimitry Andric       index = CGF.Builder.CreateMul(index, numElements, "vla.index");
39920eae32dcSDimitry Andric       pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
39930b57cec5SDimitry Andric     } else {
39940b57cec5SDimitry Andric       index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
39950eae32dcSDimitry Andric       pointer = CGF.EmitCheckedInBoundsGEP(
39960eae32dcSDimitry Andric           elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
39970eae32dcSDimitry Andric           "add.ptr");
39980b57cec5SDimitry Andric     }
39990b57cec5SDimitry Andric     return pointer;
40000b57cec5SDimitry Andric   }
40010b57cec5SDimitry Andric 
40020b57cec5SDimitry Andric   // Explicitly handle GNU void* and function pointer arithmetic extensions. The
40030b57cec5SDimitry Andric   // GNU void* casts amount to no-ops since our void* type is i8*, but this is
40040b57cec5SDimitry Andric   // future proof.
40055f757f3fSDimitry Andric   llvm::Type *elemTy;
400606c3fb27SDimitry Andric   if (elementType->isVoidType() || elementType->isFunctionType())
40075f757f3fSDimitry Andric     elemTy = CGF.Int8Ty;
40085f757f3fSDimitry Andric   else
40095f757f3fSDimitry Andric     elemTy = CGF.ConvertTypeForMem(elementType);
40100b57cec5SDimitry Andric 
40110b57cec5SDimitry Andric   if (CGF.getLangOpts().isSignedOverflowDefined())
40120eae32dcSDimitry Andric     return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
40130b57cec5SDimitry Andric 
40140eae32dcSDimitry Andric   return CGF.EmitCheckedInBoundsGEP(
40150eae32dcSDimitry Andric       elemTy, pointer, index, isSigned, isSubtraction, op.E->getExprLoc(),
40160eae32dcSDimitry Andric       "add.ptr");
40170b57cec5SDimitry Andric }
40180b57cec5SDimitry Andric 
40190b57cec5SDimitry Andric // Construct an fmuladd intrinsic to represent a fused mul-add of MulOp and
40200b57cec5SDimitry Andric // Addend. Use negMul and negAdd to negate the first operand of the Mul or
40210b57cec5SDimitry Andric // the add operand respectively. This allows fmuladd to represent a*b-c, or
40220b57cec5SDimitry Andric // c-a*b. Patterns in LLVM should catch the negated forms and translate them to
40230b57cec5SDimitry Andric // efficient operations.
buildFMulAdd(llvm::Instruction * MulOp,Value * Addend,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool negMul,bool negAdd)40245ffd83dbSDimitry Andric static Value* buildFMulAdd(llvm::Instruction *MulOp, Value *Addend,
40250b57cec5SDimitry Andric                            const CodeGenFunction &CGF, CGBuilderTy &Builder,
40260b57cec5SDimitry Andric                            bool negMul, bool negAdd) {
40270b57cec5SDimitry Andric   Value *MulOp0 = MulOp->getOperand(0);
40280b57cec5SDimitry Andric   Value *MulOp1 = MulOp->getOperand(1);
4029480093f4SDimitry Andric   if (negMul)
4030480093f4SDimitry Andric     MulOp0 = Builder.CreateFNeg(MulOp0, "neg");
4031480093f4SDimitry Andric   if (negAdd)
4032480093f4SDimitry Andric     Addend = Builder.CreateFNeg(Addend, "neg");
40330b57cec5SDimitry Andric 
40345ffd83dbSDimitry Andric   Value *FMulAdd = nullptr;
40355ffd83dbSDimitry Andric   if (Builder.getIsFPConstrained()) {
40365ffd83dbSDimitry Andric     assert(isa<llvm::ConstrainedFPIntrinsic>(MulOp) &&
40375ffd83dbSDimitry Andric            "Only constrained operation should be created when Builder is in FP "
40385ffd83dbSDimitry Andric            "constrained mode");
40395ffd83dbSDimitry Andric     FMulAdd = Builder.CreateConstrainedFPCall(
40405ffd83dbSDimitry Andric         CGF.CGM.getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
40415ffd83dbSDimitry Andric                              Addend->getType()),
40425ffd83dbSDimitry Andric         {MulOp0, MulOp1, Addend});
40435ffd83dbSDimitry Andric   } else {
40445ffd83dbSDimitry Andric     FMulAdd = Builder.CreateCall(
40450b57cec5SDimitry Andric         CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
40460b57cec5SDimitry Andric         {MulOp0, MulOp1, Addend});
40475ffd83dbSDimitry Andric   }
40480b57cec5SDimitry Andric   MulOp->eraseFromParent();
40490b57cec5SDimitry Andric 
40500b57cec5SDimitry Andric   return FMulAdd;
40510b57cec5SDimitry Andric }
40520b57cec5SDimitry Andric 
40530b57cec5SDimitry Andric // Check whether it would be legal to emit an fmuladd intrinsic call to
40540b57cec5SDimitry Andric // represent op and if so, build the fmuladd.
40550b57cec5SDimitry Andric //
40560b57cec5SDimitry Andric // Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
40570b57cec5SDimitry Andric // Does NOT check the type of the operation - it's assumed that this function
40580b57cec5SDimitry Andric // will be called from contexts where it's known that the type is contractable.
tryEmitFMulAdd(const BinOpInfo & op,const CodeGenFunction & CGF,CGBuilderTy & Builder,bool isSub=false)40590b57cec5SDimitry Andric static Value* tryEmitFMulAdd(const BinOpInfo &op,
40600b57cec5SDimitry Andric                          const CodeGenFunction &CGF, CGBuilderTy &Builder,
40610b57cec5SDimitry Andric                          bool isSub=false) {
40620b57cec5SDimitry Andric 
40630b57cec5SDimitry Andric   assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
40640b57cec5SDimitry Andric           op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
40650b57cec5SDimitry Andric          "Only fadd/fsub can be the root of an fmuladd.");
40660b57cec5SDimitry Andric 
40670b57cec5SDimitry Andric   // Check whether this op is marked as fusable.
40680b57cec5SDimitry Andric   if (!op.FPFeatures.allowFPContractWithinStatement())
40690b57cec5SDimitry Andric     return nullptr;
40700b57cec5SDimitry Andric 
407106c3fb27SDimitry Andric   Value *LHS = op.LHS;
407206c3fb27SDimitry Andric   Value *RHS = op.RHS;
407306c3fb27SDimitry Andric 
407406c3fb27SDimitry Andric   // Peek through fneg to look for fmul. Make sure fneg has no users, and that
407506c3fb27SDimitry Andric   // it is the only use of its operand.
407606c3fb27SDimitry Andric   bool NegLHS = false;
407706c3fb27SDimitry Andric   if (auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
407806c3fb27SDimitry Andric     if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
407906c3fb27SDimitry Andric         LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
408006c3fb27SDimitry Andric       LHS = LHSUnOp->getOperand(0);
408106c3fb27SDimitry Andric       NegLHS = true;
408206c3fb27SDimitry Andric     }
408306c3fb27SDimitry Andric   }
408406c3fb27SDimitry Andric 
408506c3fb27SDimitry Andric   bool NegRHS = false;
408606c3fb27SDimitry Andric   if (auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
408706c3fb27SDimitry Andric     if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
408806c3fb27SDimitry Andric         RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
408906c3fb27SDimitry Andric       RHS = RHSUnOp->getOperand(0);
409006c3fb27SDimitry Andric       NegRHS = true;
409106c3fb27SDimitry Andric     }
409206c3fb27SDimitry Andric   }
409306c3fb27SDimitry Andric 
40940b57cec5SDimitry Andric   // We have a potentially fusable op. Look for a mul on one of the operands.
40950b57cec5SDimitry Andric   // Also, make sure that the mul result isn't used directly. In that case,
40960b57cec5SDimitry Andric   // there's no point creating a muladd operation.
409706c3fb27SDimitry Andric   if (auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
40980b57cec5SDimitry Andric     if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
409906c3fb27SDimitry Andric         (LHSBinOp->use_empty() || NegLHS)) {
410006c3fb27SDimitry Andric       // If we looked through fneg, erase it.
410106c3fb27SDimitry Andric       if (NegLHS)
410206c3fb27SDimitry Andric         cast<llvm::Instruction>(op.LHS)->eraseFromParent();
410306c3fb27SDimitry Andric       return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
41040b57cec5SDimitry Andric     }
410506c3fb27SDimitry Andric   }
410606c3fb27SDimitry Andric   if (auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
41070b57cec5SDimitry Andric     if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
410806c3fb27SDimitry Andric         (RHSBinOp->use_empty() || NegRHS)) {
410906c3fb27SDimitry Andric       // If we looked through fneg, erase it.
411006c3fb27SDimitry Andric       if (NegRHS)
411106c3fb27SDimitry Andric         cast<llvm::Instruction>(op.RHS)->eraseFromParent();
411206c3fb27SDimitry Andric       return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS, false);
411306c3fb27SDimitry Andric     }
41140b57cec5SDimitry Andric   }
41150b57cec5SDimitry Andric 
411606c3fb27SDimitry Andric   if (auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
41175ffd83dbSDimitry Andric     if (LHSBinOp->getIntrinsicID() ==
41185ffd83dbSDimitry Andric             llvm::Intrinsic::experimental_constrained_fmul &&
411906c3fb27SDimitry Andric         (LHSBinOp->use_empty() || NegLHS)) {
412006c3fb27SDimitry Andric       // If we looked through fneg, erase it.
412106c3fb27SDimitry Andric       if (NegLHS)
412206c3fb27SDimitry Andric         cast<llvm::Instruction>(op.LHS)->eraseFromParent();
412306c3fb27SDimitry Andric       return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
41245ffd83dbSDimitry Andric     }
412506c3fb27SDimitry Andric   }
412606c3fb27SDimitry Andric   if (auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
41275ffd83dbSDimitry Andric     if (RHSBinOp->getIntrinsicID() ==
41285ffd83dbSDimitry Andric             llvm::Intrinsic::experimental_constrained_fmul &&
412906c3fb27SDimitry Andric         (RHSBinOp->use_empty() || NegRHS)) {
413006c3fb27SDimitry Andric       // If we looked through fneg, erase it.
413106c3fb27SDimitry Andric       if (NegRHS)
413206c3fb27SDimitry Andric         cast<llvm::Instruction>(op.RHS)->eraseFromParent();
413306c3fb27SDimitry Andric       return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS, false);
413406c3fb27SDimitry Andric     }
41355ffd83dbSDimitry Andric   }
41365ffd83dbSDimitry Andric 
41370b57cec5SDimitry Andric   return nullptr;
41380b57cec5SDimitry Andric }
41390b57cec5SDimitry Andric 
EmitAdd(const BinOpInfo & op)41400b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
41410b57cec5SDimitry Andric   if (op.LHS->getType()->isPointerTy() ||
41420b57cec5SDimitry Andric       op.RHS->getType()->isPointerTy())
41430b57cec5SDimitry Andric     return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction);
41440b57cec5SDimitry Andric 
41450b57cec5SDimitry Andric   if (op.Ty->isSignedIntegerOrEnumerationType()) {
41460b57cec5SDimitry Andric     switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
41470b57cec5SDimitry Andric     case LangOptions::SOB_Defined:
41480fca6ea1SDimitry Andric       if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
41490b57cec5SDimitry Andric         return Builder.CreateAdd(op.LHS, op.RHS, "add");
41500fca6ea1SDimitry Andric       [[fallthrough]];
41510b57cec5SDimitry Andric     case LangOptions::SOB_Undefined:
41520b57cec5SDimitry Andric       if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
41530b57cec5SDimitry Andric         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
4154bdd1243dSDimitry Andric       [[fallthrough]];
41550b57cec5SDimitry Andric     case LangOptions::SOB_Trapping:
41560b57cec5SDimitry Andric       if (CanElideOverflowCheck(CGF.getContext(), op))
41570b57cec5SDimitry Andric         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
41580b57cec5SDimitry Andric       return EmitOverflowCheckedBinOp(op);
41590b57cec5SDimitry Andric     }
41600b57cec5SDimitry Andric   }
41610b57cec5SDimitry Andric 
41625f757f3fSDimitry Andric   // For vector and matrix adds, try to fold into a fmuladd.
41635f757f3fSDimitry Andric   if (op.LHS->getType()->isFPOrFPVectorTy()) {
41645f757f3fSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
41655f757f3fSDimitry Andric     // Try to form an fmuladd.
41665f757f3fSDimitry Andric     if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
41675f757f3fSDimitry Andric       return FMulAdd;
41685f757f3fSDimitry Andric   }
41695f757f3fSDimitry Andric 
41705ffd83dbSDimitry Andric   if (op.Ty->isConstantMatrixType()) {
417181ad6265SDimitry Andric     llvm::MatrixBuilder MB(Builder);
4172fe6060f1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
41735ffd83dbSDimitry Andric     return MB.CreateAdd(op.LHS, op.RHS);
41745ffd83dbSDimitry Andric   }
41755ffd83dbSDimitry Andric 
41760b57cec5SDimitry Andric   if (op.Ty->isUnsignedIntegerType() &&
41770b57cec5SDimitry Andric       CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
41780b57cec5SDimitry Andric       !CanElideOverflowCheck(CGF.getContext(), op))
41790b57cec5SDimitry Andric     return EmitOverflowCheckedBinOp(op);
41800b57cec5SDimitry Andric 
41810b57cec5SDimitry Andric   if (op.LHS->getType()->isFPOrFPVectorTy()) {
41825ffd83dbSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
41835ffd83dbSDimitry Andric     return Builder.CreateFAdd(op.LHS, op.RHS, "add");
41840b57cec5SDimitry Andric   }
41850b57cec5SDimitry Andric 
41865ffd83dbSDimitry Andric   if (op.isFixedPointOp())
41870b57cec5SDimitry Andric     return EmitFixedPointBinOp(op);
41880b57cec5SDimitry Andric 
41890b57cec5SDimitry Andric   return Builder.CreateAdd(op.LHS, op.RHS, "add");
41900b57cec5SDimitry Andric }
41910b57cec5SDimitry Andric 
41920b57cec5SDimitry Andric /// The resulting value must be calculated with exact precision, so the operands
41930b57cec5SDimitry Andric /// may not be the same type.
EmitFixedPointBinOp(const BinOpInfo & op)41940b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {
41950b57cec5SDimitry Andric   using llvm::APSInt;
41960b57cec5SDimitry Andric   using llvm::ConstantInt;
41970b57cec5SDimitry Andric 
41985ffd83dbSDimitry Andric   // This is either a binary operation where at least one of the operands is
41995ffd83dbSDimitry Andric   // a fixed-point type, or a unary operation where the operand is a fixed-point
42005ffd83dbSDimitry Andric   // type. The result type of a binary operation is determined by
42015ffd83dbSDimitry Andric   // Sema::handleFixedPointConversions().
42020b57cec5SDimitry Andric   QualType ResultTy = op.Ty;
42035ffd83dbSDimitry Andric   QualType LHSTy, RHSTy;
42045ffd83dbSDimitry Andric   if (const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
42055ffd83dbSDimitry Andric     RHSTy = BinOp->getRHS()->getType();
42065ffd83dbSDimitry Andric     if (const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
42075ffd83dbSDimitry Andric       // For compound assignment, the effective type of the LHS at this point
42085ffd83dbSDimitry Andric       // is the computation LHS type, not the actual LHS type, and the final
42095ffd83dbSDimitry Andric       // result type is not the type of the expression but rather the
42105ffd83dbSDimitry Andric       // computation result type.
42115ffd83dbSDimitry Andric       LHSTy = CAO->getComputationLHSType();
42125ffd83dbSDimitry Andric       ResultTy = CAO->getComputationResultType();
42135ffd83dbSDimitry Andric     } else
42145ffd83dbSDimitry Andric       LHSTy = BinOp->getLHS()->getType();
42155ffd83dbSDimitry Andric   } else if (const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
42165ffd83dbSDimitry Andric     LHSTy = UnOp->getSubExpr()->getType();
42175ffd83dbSDimitry Andric     RHSTy = UnOp->getSubExpr()->getType();
42185ffd83dbSDimitry Andric   }
42190b57cec5SDimitry Andric   ASTContext &Ctx = CGF.getContext();
42200b57cec5SDimitry Andric   Value *LHS = op.LHS;
42210b57cec5SDimitry Andric   Value *RHS = op.RHS;
42220b57cec5SDimitry Andric 
42230b57cec5SDimitry Andric   auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy);
42240b57cec5SDimitry Andric   auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy);
42250b57cec5SDimitry Andric   auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy);
42260b57cec5SDimitry Andric   auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
42270b57cec5SDimitry Andric 
42285ffd83dbSDimitry Andric   // Perform the actual operation.
42290b57cec5SDimitry Andric   Value *Result;
4230e8d8bef9SDimitry Andric   llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
42315ffd83dbSDimitry Andric   switch (op.Opcode) {
42325ffd83dbSDimitry Andric   case BO_AddAssign:
4233e8d8bef9SDimitry Andric   case BO_Add:
4234e8d8bef9SDimitry Andric     Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
42350b57cec5SDimitry Andric     break;
42365ffd83dbSDimitry Andric   case BO_SubAssign:
4237e8d8bef9SDimitry Andric   case BO_Sub:
4238e8d8bef9SDimitry Andric     Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
42390b57cec5SDimitry Andric     break;
42405ffd83dbSDimitry Andric   case BO_MulAssign:
4241e8d8bef9SDimitry Andric   case BO_Mul:
4242e8d8bef9SDimitry Andric     Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
42435ffd83dbSDimitry Andric     break;
42445ffd83dbSDimitry Andric   case BO_DivAssign:
4245e8d8bef9SDimitry Andric   case BO_Div:
4246e8d8bef9SDimitry Andric     Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
42475ffd83dbSDimitry Andric     break;
4248e8d8bef9SDimitry Andric   case BO_ShlAssign:
4249e8d8bef9SDimitry Andric   case BO_Shl:
4250e8d8bef9SDimitry Andric     Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4251e8d8bef9SDimitry Andric     break;
4252e8d8bef9SDimitry Andric   case BO_ShrAssign:
4253e8d8bef9SDimitry Andric   case BO_Shr:
4254e8d8bef9SDimitry Andric     Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4255e8d8bef9SDimitry Andric     break;
42560b57cec5SDimitry Andric   case BO_LT:
4257e8d8bef9SDimitry Andric     return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
42580b57cec5SDimitry Andric   case BO_GT:
4259e8d8bef9SDimitry Andric     return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
42600b57cec5SDimitry Andric   case BO_LE:
4261e8d8bef9SDimitry Andric     return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
42620b57cec5SDimitry Andric   case BO_GE:
4263e8d8bef9SDimitry Andric     return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
42640b57cec5SDimitry Andric   case BO_EQ:
42650b57cec5SDimitry Andric     // For equality operations, we assume any padding bits on unsigned types are
42660b57cec5SDimitry Andric     // zero'd out. They could be overwritten through non-saturating operations
42670b57cec5SDimitry Andric     // that cause overflow, but this leads to undefined behavior.
4268e8d8bef9SDimitry Andric     return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
42690b57cec5SDimitry Andric   case BO_NE:
4270e8d8bef9SDimitry Andric     return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
42710b57cec5SDimitry Andric   case BO_Cmp:
42720b57cec5SDimitry Andric   case BO_LAnd:
42730b57cec5SDimitry Andric   case BO_LOr:
42740b57cec5SDimitry Andric     llvm_unreachable("Found unimplemented fixed point binary operation");
42750b57cec5SDimitry Andric   case BO_PtrMemD:
42760b57cec5SDimitry Andric   case BO_PtrMemI:
42770b57cec5SDimitry Andric   case BO_Rem:
42780b57cec5SDimitry Andric   case BO_Xor:
42790b57cec5SDimitry Andric   case BO_And:
42800b57cec5SDimitry Andric   case BO_Or:
42810b57cec5SDimitry Andric   case BO_Assign:
42820b57cec5SDimitry Andric   case BO_RemAssign:
42830b57cec5SDimitry Andric   case BO_AndAssign:
42840b57cec5SDimitry Andric   case BO_XorAssign:
42850b57cec5SDimitry Andric   case BO_OrAssign:
42860b57cec5SDimitry Andric   case BO_Comma:
42870b57cec5SDimitry Andric     llvm_unreachable("Found unsupported binary operation for fixed point types.");
42880b57cec5SDimitry Andric   }
42890b57cec5SDimitry Andric 
4290e8d8bef9SDimitry Andric   bool IsShift = BinaryOperator::isShiftOp(op.Opcode) ||
4291e8d8bef9SDimitry Andric                  BinaryOperator::isShiftAssignOp(op.Opcode);
42920b57cec5SDimitry Andric   // Convert to the result type.
4293e8d8bef9SDimitry Andric   return FPBuilder.CreateFixedToFixed(Result, IsShift ? LHSFixedSema
4294e8d8bef9SDimitry Andric                                                       : CommonFixedSema,
4295e8d8bef9SDimitry Andric                                       ResultFixedSema);
42960b57cec5SDimitry Andric }
42970b57cec5SDimitry Andric 
EmitSub(const BinOpInfo & op)42980b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
42990b57cec5SDimitry Andric   // The LHS is always a pointer if either side is.
43000b57cec5SDimitry Andric   if (!op.LHS->getType()->isPointerTy()) {
43010b57cec5SDimitry Andric     if (op.Ty->isSignedIntegerOrEnumerationType()) {
43020b57cec5SDimitry Andric       switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
43030b57cec5SDimitry Andric       case LangOptions::SOB_Defined:
43040fca6ea1SDimitry Andric         if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
43050b57cec5SDimitry Andric           return Builder.CreateSub(op.LHS, op.RHS, "sub");
43060fca6ea1SDimitry Andric         [[fallthrough]];
43070b57cec5SDimitry Andric       case LangOptions::SOB_Undefined:
43080b57cec5SDimitry Andric         if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow))
43090b57cec5SDimitry Andric           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
4310bdd1243dSDimitry Andric         [[fallthrough]];
43110b57cec5SDimitry Andric       case LangOptions::SOB_Trapping:
43120b57cec5SDimitry Andric         if (CanElideOverflowCheck(CGF.getContext(), op))
43130b57cec5SDimitry Andric           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
43140b57cec5SDimitry Andric         return EmitOverflowCheckedBinOp(op);
43150b57cec5SDimitry Andric       }
43160b57cec5SDimitry Andric     }
43170b57cec5SDimitry Andric 
43185f757f3fSDimitry Andric     // For vector and matrix subs, try to fold into a fmuladd.
43195f757f3fSDimitry Andric     if (op.LHS->getType()->isFPOrFPVectorTy()) {
43205f757f3fSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
43215f757f3fSDimitry Andric       // Try to form an fmuladd.
43225f757f3fSDimitry Andric       if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
43235f757f3fSDimitry Andric         return FMulAdd;
43245f757f3fSDimitry Andric     }
43255f757f3fSDimitry Andric 
43265ffd83dbSDimitry Andric     if (op.Ty->isConstantMatrixType()) {
432781ad6265SDimitry Andric       llvm::MatrixBuilder MB(Builder);
4328fe6060f1SDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
43295ffd83dbSDimitry Andric       return MB.CreateSub(op.LHS, op.RHS);
43305ffd83dbSDimitry Andric     }
43315ffd83dbSDimitry Andric 
43320b57cec5SDimitry Andric     if (op.Ty->isUnsignedIntegerType() &&
43330b57cec5SDimitry Andric         CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
43340b57cec5SDimitry Andric         !CanElideOverflowCheck(CGF.getContext(), op))
43350b57cec5SDimitry Andric       return EmitOverflowCheckedBinOp(op);
43360b57cec5SDimitry Andric 
43370b57cec5SDimitry Andric     if (op.LHS->getType()->isFPOrFPVectorTy()) {
43385ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
43395ffd83dbSDimitry Andric       return Builder.CreateFSub(op.LHS, op.RHS, "sub");
43400b57cec5SDimitry Andric     }
43410b57cec5SDimitry Andric 
43425ffd83dbSDimitry Andric     if (op.isFixedPointOp())
43430b57cec5SDimitry Andric       return EmitFixedPointBinOp(op);
43440b57cec5SDimitry Andric 
43450b57cec5SDimitry Andric     return Builder.CreateSub(op.LHS, op.RHS, "sub");
43460b57cec5SDimitry Andric   }
43470b57cec5SDimitry Andric 
43480b57cec5SDimitry Andric   // If the RHS is not a pointer, then we have normal pointer
43490b57cec5SDimitry Andric   // arithmetic.
43500b57cec5SDimitry Andric   if (!op.RHS->getType()->isPointerTy())
43510b57cec5SDimitry Andric     return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction);
43520b57cec5SDimitry Andric 
43530b57cec5SDimitry Andric   // Otherwise, this is a pointer subtraction.
43540b57cec5SDimitry Andric 
43550b57cec5SDimitry Andric   // Do the raw subtraction part.
43560b57cec5SDimitry Andric   llvm::Value *LHS
43570b57cec5SDimitry Andric     = Builder.CreatePtrToInt(op.LHS, CGF.PtrDiffTy, "sub.ptr.lhs.cast");
43580b57cec5SDimitry Andric   llvm::Value *RHS
43590b57cec5SDimitry Andric     = Builder.CreatePtrToInt(op.RHS, CGF.PtrDiffTy, "sub.ptr.rhs.cast");
43600b57cec5SDimitry Andric   Value *diffInChars = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
43610b57cec5SDimitry Andric 
43620b57cec5SDimitry Andric   // Okay, figure out the element size.
43630b57cec5SDimitry Andric   const BinaryOperator *expr = cast<BinaryOperator>(op.E);
43640b57cec5SDimitry Andric   QualType elementType = expr->getLHS()->getType()->getPointeeType();
43650b57cec5SDimitry Andric 
43660b57cec5SDimitry Andric   llvm::Value *divisor = nullptr;
43670b57cec5SDimitry Andric 
43680b57cec5SDimitry Andric   // For a variable-length array, this is going to be non-constant.
43690b57cec5SDimitry Andric   if (const VariableArrayType *vla
43700b57cec5SDimitry Andric         = CGF.getContext().getAsVariableArrayType(elementType)) {
43710b57cec5SDimitry Andric     auto VlaSize = CGF.getVLASize(vla);
43720b57cec5SDimitry Andric     elementType = VlaSize.Type;
43730b57cec5SDimitry Andric     divisor = VlaSize.NumElts;
43740b57cec5SDimitry Andric 
43750b57cec5SDimitry Andric     // Scale the number of non-VLA elements by the non-VLA element size.
43760b57cec5SDimitry Andric     CharUnits eltSize = CGF.getContext().getTypeSizeInChars(elementType);
43770b57cec5SDimitry Andric     if (!eltSize.isOne())
43780b57cec5SDimitry Andric       divisor = CGF.Builder.CreateNUWMul(CGF.CGM.getSize(eltSize), divisor);
43790b57cec5SDimitry Andric 
43800b57cec5SDimitry Andric   // For everything elese, we can just compute it, safe in the
43810b57cec5SDimitry Andric   // assumption that Sema won't let anything through that we can't
43820b57cec5SDimitry Andric   // safely compute the size of.
43830b57cec5SDimitry Andric   } else {
43840b57cec5SDimitry Andric     CharUnits elementSize;
43850b57cec5SDimitry Andric     // Handle GCC extension for pointer arithmetic on void* and
43860b57cec5SDimitry Andric     // function pointer types.
43870b57cec5SDimitry Andric     if (elementType->isVoidType() || elementType->isFunctionType())
43880b57cec5SDimitry Andric       elementSize = CharUnits::One();
43890b57cec5SDimitry Andric     else
43900b57cec5SDimitry Andric       elementSize = CGF.getContext().getTypeSizeInChars(elementType);
43910b57cec5SDimitry Andric 
43920b57cec5SDimitry Andric     // Don't even emit the divide for element size of 1.
43930b57cec5SDimitry Andric     if (elementSize.isOne())
43940b57cec5SDimitry Andric       return diffInChars;
43950b57cec5SDimitry Andric 
43960b57cec5SDimitry Andric     divisor = CGF.CGM.getSize(elementSize);
43970b57cec5SDimitry Andric   }
43980b57cec5SDimitry Andric 
43990b57cec5SDimitry Andric   // Otherwise, do a full sdiv. This uses the "exact" form of sdiv, since
44000b57cec5SDimitry Andric   // pointer difference in C is only defined in the case where both operands
44010b57cec5SDimitry Andric   // are pointing to elements of an array.
44020b57cec5SDimitry Andric   return Builder.CreateExactSDiv(diffInChars, divisor, "sub.ptr.div");
44030b57cec5SDimitry Andric }
44040b57cec5SDimitry Andric 
GetMaximumShiftAmount(Value * LHS,Value * RHS,bool RHSIsSigned)44050fca6ea1SDimitry Andric Value *ScalarExprEmitter::GetMaximumShiftAmount(Value *LHS, Value *RHS,
44060fca6ea1SDimitry Andric                                                 bool RHSIsSigned) {
44070b57cec5SDimitry Andric   llvm::IntegerType *Ty;
44080b57cec5SDimitry Andric   if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
44090b57cec5SDimitry Andric     Ty = cast<llvm::IntegerType>(VT->getElementType());
44100b57cec5SDimitry Andric   else
44110b57cec5SDimitry Andric     Ty = cast<llvm::IntegerType>(LHS->getType());
44120fca6ea1SDimitry Andric   // For a given type of LHS the maximum shift amount is width(LHS)-1, however
44130fca6ea1SDimitry Andric   // it can occur that width(LHS)-1 > range(RHS). Since there is no check for
44140fca6ea1SDimitry Andric   // this in ConstantInt::get, this results in the value getting truncated.
44150fca6ea1SDimitry Andric   // Constrain the return value to be max(RHS) in this case.
44160fca6ea1SDimitry Andric   llvm::Type *RHSTy = RHS->getType();
44170fca6ea1SDimitry Andric   llvm::APInt RHSMax =
44180fca6ea1SDimitry Andric       RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
44190fca6ea1SDimitry Andric                   : llvm::APInt::getMaxValue(RHSTy->getScalarSizeInBits());
44200fca6ea1SDimitry Andric   if (RHSMax.ult(Ty->getBitWidth()))
44210fca6ea1SDimitry Andric     return llvm::ConstantInt::get(RHSTy, RHSMax);
44220fca6ea1SDimitry Andric   return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
44230b57cec5SDimitry Andric }
44240b57cec5SDimitry Andric 
ConstrainShiftValue(Value * LHS,Value * RHS,const Twine & Name)44255ffd83dbSDimitry Andric Value *ScalarExprEmitter::ConstrainShiftValue(Value *LHS, Value *RHS,
44265ffd83dbSDimitry Andric                                               const Twine &Name) {
44275ffd83dbSDimitry Andric   llvm::IntegerType *Ty;
44285ffd83dbSDimitry Andric   if (auto *VT = dyn_cast<llvm::VectorType>(LHS->getType()))
44295ffd83dbSDimitry Andric     Ty = cast<llvm::IntegerType>(VT->getElementType());
44305ffd83dbSDimitry Andric   else
44315ffd83dbSDimitry Andric     Ty = cast<llvm::IntegerType>(LHS->getType());
44325ffd83dbSDimitry Andric 
44335ffd83dbSDimitry Andric   if (llvm::isPowerOf2_64(Ty->getBitWidth()))
44340fca6ea1SDimitry Andric     return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS, false), Name);
44355ffd83dbSDimitry Andric 
44365ffd83dbSDimitry Andric   return Builder.CreateURem(
44375ffd83dbSDimitry Andric       RHS, llvm::ConstantInt::get(RHS->getType(), Ty->getBitWidth()), Name);
44385ffd83dbSDimitry Andric }
44395ffd83dbSDimitry Andric 
EmitShl(const BinOpInfo & Ops)44400b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
4441e8d8bef9SDimitry Andric   // TODO: This misses out on the sanitizer check below.
4442e8d8bef9SDimitry Andric   if (Ops.isFixedPointOp())
4443e8d8bef9SDimitry Andric     return EmitFixedPointBinOp(Ops);
4444e8d8bef9SDimitry Andric 
44450b57cec5SDimitry Andric   // LLVM requires the LHS and RHS to be the same type: promote or truncate the
44460b57cec5SDimitry Andric   // RHS to the same size as the LHS.
44470b57cec5SDimitry Andric   Value *RHS = Ops.RHS;
44480b57cec5SDimitry Andric   if (Ops.LHS->getType() != RHS->getType())
44490b57cec5SDimitry Andric     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
44500b57cec5SDimitry Andric 
4451e8d8bef9SDimitry Andric   bool SanitizeSignedBase = CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
44520b57cec5SDimitry Andric                             Ops.Ty->hasSignedIntegerRepresentation() &&
44530b57cec5SDimitry Andric                             !CGF.getLangOpts().isSignedOverflowDefined() &&
44545ffd83dbSDimitry Andric                             !CGF.getLangOpts().CPlusPlus20;
4455e8d8bef9SDimitry Andric   bool SanitizeUnsignedBase =
4456e8d8bef9SDimitry Andric       CGF.SanOpts.has(SanitizerKind::UnsignedShiftBase) &&
4457e8d8bef9SDimitry Andric       Ops.Ty->hasUnsignedIntegerRepresentation();
4458e8d8bef9SDimitry Andric   bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
44590b57cec5SDimitry Andric   bool SanitizeExponent = CGF.SanOpts.has(SanitizerKind::ShiftExponent);
44600b57cec5SDimitry Andric   // OpenCL 6.3j: shift values are effectively % word size of LHS.
44610fca6ea1SDimitry Andric   if (CGF.getLangOpts().OpenCL || CGF.getLangOpts().HLSL)
44625ffd83dbSDimitry Andric     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
44630b57cec5SDimitry Andric   else if ((SanitizeBase || SanitizeExponent) &&
44640b57cec5SDimitry Andric            isa<llvm::IntegerType>(Ops.LHS->getType())) {
44650b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
44660b57cec5SDimitry Andric     SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
44670fca6ea1SDimitry Andric     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
44680fca6ea1SDimitry Andric     llvm::Value *WidthMinusOne =
44690fca6ea1SDimitry Andric         GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
44700b57cec5SDimitry Andric     llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
44710b57cec5SDimitry Andric 
44720b57cec5SDimitry Andric     if (SanitizeExponent) {
44730b57cec5SDimitry Andric       Checks.push_back(
44740b57cec5SDimitry Andric           std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
44750b57cec5SDimitry Andric     }
44760b57cec5SDimitry Andric 
44770b57cec5SDimitry Andric     if (SanitizeBase) {
44780b57cec5SDimitry Andric       // Check whether we are shifting any non-zero bits off the top of the
44790b57cec5SDimitry Andric       // integer. We only emit this check if exponent is valid - otherwise
44800b57cec5SDimitry Andric       // instructions below will have undefined behavior themselves.
44810b57cec5SDimitry Andric       llvm::BasicBlock *Orig = Builder.GetInsertBlock();
44820b57cec5SDimitry Andric       llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
44830b57cec5SDimitry Andric       llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
44840b57cec5SDimitry Andric       Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
44850b57cec5SDimitry Andric       llvm::Value *PromotedWidthMinusOne =
44860b57cec5SDimitry Andric           (RHS == Ops.RHS) ? WidthMinusOne
44870fca6ea1SDimitry Andric                            : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
44880b57cec5SDimitry Andric       CGF.EmitBlock(CheckShiftBase);
44890b57cec5SDimitry Andric       llvm::Value *BitsShiftedOff = Builder.CreateLShr(
44900b57cec5SDimitry Andric           Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
44910b57cec5SDimitry Andric                                      /*NUW*/ true, /*NSW*/ true),
44920b57cec5SDimitry Andric           "shl.check");
4493e8d8bef9SDimitry Andric       if (SanitizeUnsignedBase || CGF.getLangOpts().CPlusPlus) {
44940b57cec5SDimitry Andric         // In C99, we are not permitted to shift a 1 bit into the sign bit.
44950b57cec5SDimitry Andric         // Under C++11's rules, shifting a 1 bit into the sign bit is
44960b57cec5SDimitry Andric         // OK, but shifting a 1 bit out of it is not. (C89 and C++03 don't
44970b57cec5SDimitry Andric         // define signed left shifts, so we use the C99 and C++11 rules there).
4498e8d8bef9SDimitry Andric         // Unsigned shifts can always shift into the top bit.
44990b57cec5SDimitry Andric         llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
45000b57cec5SDimitry Andric         BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
45010b57cec5SDimitry Andric       }
45020b57cec5SDimitry Andric       llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
45030b57cec5SDimitry Andric       llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
45040b57cec5SDimitry Andric       CGF.EmitBlock(Cont);
45050b57cec5SDimitry Andric       llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
45060b57cec5SDimitry Andric       BaseCheck->addIncoming(Builder.getTrue(), Orig);
45070b57cec5SDimitry Andric       BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4508e8d8bef9SDimitry Andric       Checks.push_back(std::make_pair(
4509e8d8bef9SDimitry Andric           BaseCheck, SanitizeSignedBase ? SanitizerKind::ShiftBase
4510e8d8bef9SDimitry Andric                                         : SanitizerKind::UnsignedShiftBase));
45110b57cec5SDimitry Andric     }
45120b57cec5SDimitry Andric 
45130b57cec5SDimitry Andric     assert(!Checks.empty());
45140b57cec5SDimitry Andric     EmitBinOpCheck(Checks, Ops);
45150b57cec5SDimitry Andric   }
45160b57cec5SDimitry Andric 
45170b57cec5SDimitry Andric   return Builder.CreateShl(Ops.LHS, RHS, "shl");
45180b57cec5SDimitry Andric }
45190b57cec5SDimitry Andric 
EmitShr(const BinOpInfo & Ops)45200b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
4521e8d8bef9SDimitry Andric   // TODO: This misses out on the sanitizer check below.
4522e8d8bef9SDimitry Andric   if (Ops.isFixedPointOp())
4523e8d8bef9SDimitry Andric     return EmitFixedPointBinOp(Ops);
4524e8d8bef9SDimitry Andric 
45250b57cec5SDimitry Andric   // LLVM requires the LHS and RHS to be the same type: promote or truncate the
45260b57cec5SDimitry Andric   // RHS to the same size as the LHS.
45270b57cec5SDimitry Andric   Value *RHS = Ops.RHS;
45280b57cec5SDimitry Andric   if (Ops.LHS->getType() != RHS->getType())
45290b57cec5SDimitry Andric     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
45300b57cec5SDimitry Andric 
45310b57cec5SDimitry Andric   // OpenCL 6.3j: shift values are effectively % word size of LHS.
45320fca6ea1SDimitry Andric   if (CGF.getLangOpts().OpenCL || CGF.getLangOpts().HLSL)
45335ffd83dbSDimitry Andric     RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask");
45340b57cec5SDimitry Andric   else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
45350b57cec5SDimitry Andric            isa<llvm::IntegerType>(Ops.LHS->getType())) {
45360b57cec5SDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
45370fca6ea1SDimitry Andric     bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
45380fca6ea1SDimitry Andric     llvm::Value *Valid = Builder.CreateICmpULE(
45390fca6ea1SDimitry Andric         Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
45400b57cec5SDimitry Andric     EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
45410b57cec5SDimitry Andric   }
45420b57cec5SDimitry Andric 
45430b57cec5SDimitry Andric   if (Ops.Ty->hasUnsignedIntegerRepresentation())
45440b57cec5SDimitry Andric     return Builder.CreateLShr(Ops.LHS, RHS, "shr");
45450b57cec5SDimitry Andric   return Builder.CreateAShr(Ops.LHS, RHS, "shr");
45460b57cec5SDimitry Andric }
45470b57cec5SDimitry Andric 
45480b57cec5SDimitry Andric enum IntrinsicType { VCMPEQ, VCMPGT };
45490b57cec5SDimitry Andric // return corresponding comparison intrinsic for given vector type
GetIntrinsic(IntrinsicType IT,BuiltinType::Kind ElemKind)45500b57cec5SDimitry Andric static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
45510b57cec5SDimitry Andric                                         BuiltinType::Kind ElemKind) {
45520b57cec5SDimitry Andric   switch (ElemKind) {
45530b57cec5SDimitry Andric   default: llvm_unreachable("unexpected element type");
45540b57cec5SDimitry Andric   case BuiltinType::Char_U:
45550b57cec5SDimitry Andric   case BuiltinType::UChar:
45560b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
45570b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
45580b57cec5SDimitry Andric   case BuiltinType::Char_S:
45590b57cec5SDimitry Andric   case BuiltinType::SChar:
45600b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
45610b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
45620b57cec5SDimitry Andric   case BuiltinType::UShort:
45630b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
45640b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
45650b57cec5SDimitry Andric   case BuiltinType::Short:
45660b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
45670b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
45680b57cec5SDimitry Andric   case BuiltinType::UInt:
45690b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
45700b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
45710b57cec5SDimitry Andric   case BuiltinType::Int:
45720b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
45730b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
45740b57cec5SDimitry Andric   case BuiltinType::ULong:
45750b57cec5SDimitry Andric   case BuiltinType::ULongLong:
45760b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
45770b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
45780b57cec5SDimitry Andric   case BuiltinType::Long:
45790b57cec5SDimitry Andric   case BuiltinType::LongLong:
45800b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
45810b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
45820b57cec5SDimitry Andric   case BuiltinType::Float:
45830b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
45840b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
45850b57cec5SDimitry Andric   case BuiltinType::Double:
45860b57cec5SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
45870b57cec5SDimitry Andric                             llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
4588e8d8bef9SDimitry Andric   case BuiltinType::UInt128:
4589e8d8bef9SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4590e8d8bef9SDimitry Andric                           : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
4591e8d8bef9SDimitry Andric   case BuiltinType::Int128:
4592e8d8bef9SDimitry Andric     return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
4593e8d8bef9SDimitry Andric                           : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
45940b57cec5SDimitry Andric   }
45950b57cec5SDimitry Andric }
45960b57cec5SDimitry Andric 
EmitCompare(const BinaryOperator * E,llvm::CmpInst::Predicate UICmpOpc,llvm::CmpInst::Predicate SICmpOpc,llvm::CmpInst::Predicate FCmpOpc,bool IsSignaling)45970b57cec5SDimitry Andric Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
45980b57cec5SDimitry Andric                                       llvm::CmpInst::Predicate UICmpOpc,
45990b57cec5SDimitry Andric                                       llvm::CmpInst::Predicate SICmpOpc,
4600480093f4SDimitry Andric                                       llvm::CmpInst::Predicate FCmpOpc,
4601480093f4SDimitry Andric                                       bool IsSignaling) {
46020b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
46030b57cec5SDimitry Andric   Value *Result;
46040b57cec5SDimitry Andric   QualType LHSTy = E->getLHS()->getType();
46050b57cec5SDimitry Andric   QualType RHSTy = E->getRHS()->getType();
46060b57cec5SDimitry Andric   if (const MemberPointerType *MPT = LHSTy->getAs<MemberPointerType>()) {
46070b57cec5SDimitry Andric     assert(E->getOpcode() == BO_EQ ||
46080b57cec5SDimitry Andric            E->getOpcode() == BO_NE);
46090b57cec5SDimitry Andric     Value *LHS = CGF.EmitScalarExpr(E->getLHS());
46100b57cec5SDimitry Andric     Value *RHS = CGF.EmitScalarExpr(E->getRHS());
46110b57cec5SDimitry Andric     Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
46120b57cec5SDimitry Andric                    CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
46130b57cec5SDimitry Andric   } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) {
46140b57cec5SDimitry Andric     BinOpInfo BOInfo = EmitBinOps(E);
46150b57cec5SDimitry Andric     Value *LHS = BOInfo.LHS;
46160b57cec5SDimitry Andric     Value *RHS = BOInfo.RHS;
46170b57cec5SDimitry Andric 
46180b57cec5SDimitry Andric     // If AltiVec, the comparison results in a numeric type, so we use
46190b57cec5SDimitry Andric     // intrinsics comparing vectors and giving 0 or 1 as a result
46200b57cec5SDimitry Andric     if (LHSTy->isVectorType() && !E->getType()->isVectorType()) {
46210b57cec5SDimitry Andric       // constants for mapping CR6 register bits to predicate result
46220b57cec5SDimitry Andric       enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
46230b57cec5SDimitry Andric 
46240b57cec5SDimitry Andric       llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic;
46250b57cec5SDimitry Andric 
46260b57cec5SDimitry Andric       // in several cases vector arguments order will be reversed
46270b57cec5SDimitry Andric       Value *FirstVecArg = LHS,
46280b57cec5SDimitry Andric             *SecondVecArg = RHS;
46290b57cec5SDimitry Andric 
4630a7dea167SDimitry Andric       QualType ElTy = LHSTy->castAs<VectorType>()->getElementType();
4631480093f4SDimitry Andric       BuiltinType::Kind ElementKind = ElTy->castAs<BuiltinType>()->getKind();
46320b57cec5SDimitry Andric 
46330b57cec5SDimitry Andric       switch(E->getOpcode()) {
46340b57cec5SDimitry Andric       default: llvm_unreachable("is not a comparison operation");
46350b57cec5SDimitry Andric       case BO_EQ:
46360b57cec5SDimitry Andric         CR6 = CR6_LT;
46370b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPEQ, ElementKind);
46380b57cec5SDimitry Andric         break;
46390b57cec5SDimitry Andric       case BO_NE:
46400b57cec5SDimitry Andric         CR6 = CR6_EQ;
46410b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPEQ, ElementKind);
46420b57cec5SDimitry Andric         break;
46430b57cec5SDimitry Andric       case BO_LT:
46440b57cec5SDimitry Andric         CR6 = CR6_LT;
46450b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPGT, ElementKind);
46460b57cec5SDimitry Andric         std::swap(FirstVecArg, SecondVecArg);
46470b57cec5SDimitry Andric         break;
46480b57cec5SDimitry Andric       case BO_GT:
46490b57cec5SDimitry Andric         CR6 = CR6_LT;
46500b57cec5SDimitry Andric         ID = GetIntrinsic(VCMPGT, ElementKind);
46510b57cec5SDimitry Andric         break;
46520b57cec5SDimitry Andric       case BO_LE:
46530b57cec5SDimitry Andric         if (ElementKind == BuiltinType::Float) {
46540b57cec5SDimitry Andric           CR6 = CR6_LT;
46550b57cec5SDimitry Andric           ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
46560b57cec5SDimitry Andric           std::swap(FirstVecArg, SecondVecArg);
46570b57cec5SDimitry Andric         }
46580b57cec5SDimitry Andric         else {
46590b57cec5SDimitry Andric           CR6 = CR6_EQ;
46600b57cec5SDimitry Andric           ID = GetIntrinsic(VCMPGT, ElementKind);
46610b57cec5SDimitry Andric         }
46620b57cec5SDimitry Andric         break;
46630b57cec5SDimitry Andric       case BO_GE:
46640b57cec5SDimitry Andric         if (ElementKind == BuiltinType::Float) {
46650b57cec5SDimitry Andric           CR6 = CR6_LT;
46660b57cec5SDimitry Andric           ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
46670b57cec5SDimitry Andric         }
46680b57cec5SDimitry Andric         else {
46690b57cec5SDimitry Andric           CR6 = CR6_EQ;
46700b57cec5SDimitry Andric           ID = GetIntrinsic(VCMPGT, ElementKind);
46710b57cec5SDimitry Andric           std::swap(FirstVecArg, SecondVecArg);
46720b57cec5SDimitry Andric         }
46730b57cec5SDimitry Andric         break;
46740b57cec5SDimitry Andric       }
46750b57cec5SDimitry Andric 
46760b57cec5SDimitry Andric       Value *CR6Param = Builder.getInt32(CR6);
46770b57cec5SDimitry Andric       llvm::Function *F = CGF.CGM.getIntrinsic(ID);
46780b57cec5SDimitry Andric       Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
46790b57cec5SDimitry Andric 
46800b57cec5SDimitry Andric       // The result type of intrinsic may not be same as E->getType().
46810b57cec5SDimitry Andric       // If E->getType() is not BoolTy, EmitScalarConversion will do the
46820b57cec5SDimitry Andric       // conversion work. If E->getType() is BoolTy, EmitScalarConversion will
46830b57cec5SDimitry Andric       // do nothing, if ResultTy is not i1 at the same time, it will cause
46840b57cec5SDimitry Andric       // crash later.
46850b57cec5SDimitry Andric       llvm::IntegerType *ResultTy = cast<llvm::IntegerType>(Result->getType());
46860b57cec5SDimitry Andric       if (ResultTy->getBitWidth() > 1 &&
46870b57cec5SDimitry Andric           E->getType() == CGF.getContext().BoolTy)
46880b57cec5SDimitry Andric         Result = Builder.CreateTrunc(Result, Builder.getInt1Ty());
46890b57cec5SDimitry Andric       return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
46900b57cec5SDimitry Andric                                   E->getExprLoc());
46910b57cec5SDimitry Andric     }
46920b57cec5SDimitry Andric 
46935ffd83dbSDimitry Andric     if (BOInfo.isFixedPointOp()) {
46940b57cec5SDimitry Andric       Result = EmitFixedPointBinOp(BOInfo);
46950b57cec5SDimitry Andric     } else if (LHS->getType()->isFPOrFPVectorTy()) {
46965ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
4697480093f4SDimitry Andric       if (!IsSignaling)
46980b57cec5SDimitry Andric         Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
4699480093f4SDimitry Andric       else
4700480093f4SDimitry Andric         Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS, "cmp");
47010b57cec5SDimitry Andric     } else if (LHSTy->hasSignedIntegerRepresentation()) {
47020b57cec5SDimitry Andric       Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
47030b57cec5SDimitry Andric     } else {
47040b57cec5SDimitry Andric       // Unsigned integers and pointers.
47050b57cec5SDimitry Andric 
47060b57cec5SDimitry Andric       if (CGF.CGM.getCodeGenOpts().StrictVTablePointers &&
47070b57cec5SDimitry Andric           !isa<llvm::ConstantPointerNull>(LHS) &&
47080b57cec5SDimitry Andric           !isa<llvm::ConstantPointerNull>(RHS)) {
47090b57cec5SDimitry Andric 
47100b57cec5SDimitry Andric         // Dynamic information is required to be stripped for comparisons,
47110b57cec5SDimitry Andric         // because it could leak the dynamic information.  Based on comparisons
47120b57cec5SDimitry Andric         // of pointers to dynamic objects, the optimizer can replace one pointer
47130b57cec5SDimitry Andric         // with another, which might be incorrect in presence of invariant
47140b57cec5SDimitry Andric         // groups. Comparison with null is safe because null does not carry any
47150b57cec5SDimitry Andric         // dynamic information.
47160b57cec5SDimitry Andric         if (LHSTy.mayBeDynamicClass())
47170b57cec5SDimitry Andric           LHS = Builder.CreateStripInvariantGroup(LHS);
47180b57cec5SDimitry Andric         if (RHSTy.mayBeDynamicClass())
47190b57cec5SDimitry Andric           RHS = Builder.CreateStripInvariantGroup(RHS);
47200b57cec5SDimitry Andric       }
47210b57cec5SDimitry Andric 
47220b57cec5SDimitry Andric       Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
47230b57cec5SDimitry Andric     }
47240b57cec5SDimitry Andric 
47250b57cec5SDimitry Andric     // If this is a vector comparison, sign extend the result to the appropriate
47260b57cec5SDimitry Andric     // vector integer type and return it (don't convert to bool).
47270b57cec5SDimitry Andric     if (LHSTy->isVectorType())
47280b57cec5SDimitry Andric       return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext");
47290b57cec5SDimitry Andric 
47300b57cec5SDimitry Andric   } else {
47310b57cec5SDimitry Andric     // Complex Comparison: can only be an equality comparison.
47320b57cec5SDimitry Andric     CodeGenFunction::ComplexPairTy LHS, RHS;
47330b57cec5SDimitry Andric     QualType CETy;
47340b57cec5SDimitry Andric     if (auto *CTy = LHSTy->getAs<ComplexType>()) {
47350b57cec5SDimitry Andric       LHS = CGF.EmitComplexExpr(E->getLHS());
47360b57cec5SDimitry Andric       CETy = CTy->getElementType();
47370b57cec5SDimitry Andric     } else {
47380b57cec5SDimitry Andric       LHS.first = Visit(E->getLHS());
47390b57cec5SDimitry Andric       LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
47400b57cec5SDimitry Andric       CETy = LHSTy;
47410b57cec5SDimitry Andric     }
47420b57cec5SDimitry Andric     if (auto *CTy = RHSTy->getAs<ComplexType>()) {
47430b57cec5SDimitry Andric       RHS = CGF.EmitComplexExpr(E->getRHS());
47440b57cec5SDimitry Andric       assert(CGF.getContext().hasSameUnqualifiedType(CETy,
47450b57cec5SDimitry Andric                                                      CTy->getElementType()) &&
47460b57cec5SDimitry Andric              "The element types must always match.");
47470b57cec5SDimitry Andric       (void)CTy;
47480b57cec5SDimitry Andric     } else {
47490b57cec5SDimitry Andric       RHS.first = Visit(E->getRHS());
47500b57cec5SDimitry Andric       RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
47510b57cec5SDimitry Andric       assert(CGF.getContext().hasSameUnqualifiedType(CETy, RHSTy) &&
47520b57cec5SDimitry Andric              "The element types must always match.");
47530b57cec5SDimitry Andric     }
47540b57cec5SDimitry Andric 
47550b57cec5SDimitry Andric     Value *ResultR, *ResultI;
47560b57cec5SDimitry Andric     if (CETy->isRealFloatingType()) {
4757480093f4SDimitry Andric       // As complex comparisons can only be equality comparisons, they
4758480093f4SDimitry Andric       // are never signaling comparisons.
47590b57cec5SDimitry Andric       ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first, "cmp.r");
47600b57cec5SDimitry Andric       ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second, "cmp.i");
47610b57cec5SDimitry Andric     } else {
47620b57cec5SDimitry Andric       // Complex comparisons can only be equality comparisons.  As such, signed
47630b57cec5SDimitry Andric       // and unsigned opcodes are the same.
47640b57cec5SDimitry Andric       ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first, "cmp.r");
47650b57cec5SDimitry Andric       ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second, "cmp.i");
47660b57cec5SDimitry Andric     }
47670b57cec5SDimitry Andric 
47680b57cec5SDimitry Andric     if (E->getOpcode() == BO_EQ) {
47690b57cec5SDimitry Andric       Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
47700b57cec5SDimitry Andric     } else {
47710b57cec5SDimitry Andric       assert(E->getOpcode() == BO_NE &&
47720b57cec5SDimitry Andric              "Complex comparison other than == or != ?");
47730b57cec5SDimitry Andric       Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
47740b57cec5SDimitry Andric     }
47750b57cec5SDimitry Andric   }
47760b57cec5SDimitry Andric 
47770b57cec5SDimitry Andric   return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(),
47780b57cec5SDimitry Andric                               E->getExprLoc());
47790b57cec5SDimitry Andric }
47800b57cec5SDimitry Andric 
EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator * E,Value ** Previous,QualType * SrcType)47810fca6ea1SDimitry Andric llvm::Value *CodeGenFunction::EmitWithOriginalRHSBitfieldAssignment(
47820fca6ea1SDimitry Andric     const BinaryOperator *E, Value **Previous, QualType *SrcType) {
47830fca6ea1SDimitry Andric   // In case we have the integer or bitfield sanitizer checks enabled
47840fca6ea1SDimitry Andric   // we want to get the expression before scalar conversion.
47850fca6ea1SDimitry Andric   if (auto *ICE = dyn_cast<ImplicitCastExpr>(E->getRHS())) {
47860fca6ea1SDimitry Andric     CastKind Kind = ICE->getCastKind();
47870fca6ea1SDimitry Andric     if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
47880fca6ea1SDimitry Andric       *SrcType = ICE->getSubExpr()->getType();
47890fca6ea1SDimitry Andric       *Previous = EmitScalarExpr(ICE->getSubExpr());
47900fca6ea1SDimitry Andric       // Pass default ScalarConversionOpts to avoid emitting
47910fca6ea1SDimitry Andric       // integer sanitizer checks as E refers to bitfield.
47920fca6ea1SDimitry Andric       return EmitScalarConversion(*Previous, *SrcType, ICE->getType(),
47930fca6ea1SDimitry Andric                                   ICE->getExprLoc());
47940fca6ea1SDimitry Andric     }
47950fca6ea1SDimitry Andric   }
47960fca6ea1SDimitry Andric   return EmitScalarExpr(E->getRHS());
47970fca6ea1SDimitry Andric }
47980fca6ea1SDimitry Andric 
VisitBinAssign(const BinaryOperator * E)47990b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
48000b57cec5SDimitry Andric   bool Ignore = TestAndClearIgnoreResultAssign();
48010b57cec5SDimitry Andric 
48020b57cec5SDimitry Andric   Value *RHS;
48030b57cec5SDimitry Andric   LValue LHS;
48040b57cec5SDimitry Andric 
48050b57cec5SDimitry Andric   switch (E->getLHS()->getType().getObjCLifetime()) {
48060b57cec5SDimitry Andric   case Qualifiers::OCL_Strong:
48070b57cec5SDimitry Andric     std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
48080b57cec5SDimitry Andric     break;
48090b57cec5SDimitry Andric 
48100b57cec5SDimitry Andric   case Qualifiers::OCL_Autoreleasing:
48110b57cec5SDimitry Andric     std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E);
48120b57cec5SDimitry Andric     break;
48130b57cec5SDimitry Andric 
48140b57cec5SDimitry Andric   case Qualifiers::OCL_ExplicitNone:
48150b57cec5SDimitry Andric     std::tie(LHS, RHS) = CGF.EmitARCStoreUnsafeUnretained(E, Ignore);
48160b57cec5SDimitry Andric     break;
48170b57cec5SDimitry Andric 
48180b57cec5SDimitry Andric   case Qualifiers::OCL_Weak:
48190b57cec5SDimitry Andric     RHS = Visit(E->getRHS());
48200b57cec5SDimitry Andric     LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
48210fca6ea1SDimitry Andric     RHS = CGF.EmitARCStoreWeak(LHS.getAddress(), RHS, Ignore);
48220b57cec5SDimitry Andric     break;
48230b57cec5SDimitry Andric 
48240b57cec5SDimitry Andric   case Qualifiers::OCL_None:
48250b57cec5SDimitry Andric     // __block variables need to have the rhs evaluated first, plus
48260b57cec5SDimitry Andric     // this should improve codegen just a little.
48270fca6ea1SDimitry Andric     Value *Previous = nullptr;
48280fca6ea1SDimitry Andric     QualType SrcType = E->getRHS()->getType();
48290fca6ea1SDimitry Andric     // Check if LHS is a bitfield, if RHS contains an implicit cast expression
48300fca6ea1SDimitry Andric     // we want to extract that value and potentially (if the bitfield sanitizer
48310fca6ea1SDimitry Andric     // is enabled) use it to check for an implicit conversion.
48320fca6ea1SDimitry Andric     if (E->getLHS()->refersToBitField())
48330fca6ea1SDimitry Andric       RHS = CGF.EmitWithOriginalRHSBitfieldAssignment(E, &Previous, &SrcType);
48340fca6ea1SDimitry Andric     else
48350b57cec5SDimitry Andric       RHS = Visit(E->getRHS());
48360fca6ea1SDimitry Andric 
48370b57cec5SDimitry Andric     LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
48380b57cec5SDimitry Andric 
48390b57cec5SDimitry Andric     // Store the value into the LHS.  Bit-fields are handled specially
48400b57cec5SDimitry Andric     // because the result is altered by the store, i.e., [C99 6.5.16p1]
48410b57cec5SDimitry Andric     // 'An assignment expression has the value of the left operand after
48420b57cec5SDimitry Andric     // the assignment...'.
48430b57cec5SDimitry Andric     if (LHS.isBitField()) {
48440b57cec5SDimitry Andric       CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
48450fca6ea1SDimitry Andric       // If the expression contained an implicit conversion, make sure
48460fca6ea1SDimitry Andric       // to use the value before the scalar conversion.
48470fca6ea1SDimitry Andric       Value *Src = Previous ? Previous : RHS;
48480fca6ea1SDimitry Andric       QualType DstType = E->getLHS()->getType();
48490fca6ea1SDimitry Andric       CGF.EmitBitfieldConversionCheck(Src, SrcType, RHS, DstType,
48500fca6ea1SDimitry Andric                                       LHS.getBitFieldInfo(), E->getExprLoc());
48510b57cec5SDimitry Andric     } else {
48520b57cec5SDimitry Andric       CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
48530b57cec5SDimitry Andric       CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
48540b57cec5SDimitry Andric     }
48550b57cec5SDimitry Andric   }
48560b57cec5SDimitry Andric 
48570b57cec5SDimitry Andric   // If the result is clearly ignored, return now.
48580b57cec5SDimitry Andric   if (Ignore)
48590b57cec5SDimitry Andric     return nullptr;
48600b57cec5SDimitry Andric 
48610b57cec5SDimitry Andric   // The result of an assignment in C is the assigned r-value.
48620b57cec5SDimitry Andric   if (!CGF.getLangOpts().CPlusPlus)
48630b57cec5SDimitry Andric     return RHS;
48640b57cec5SDimitry Andric 
48650b57cec5SDimitry Andric   // If the lvalue is non-volatile, return the computed value of the assignment.
48660b57cec5SDimitry Andric   if (!LHS.isVolatileQualified())
48670b57cec5SDimitry Andric     return RHS;
48680b57cec5SDimitry Andric 
48690b57cec5SDimitry Andric   // Otherwise, reload the value.
48700b57cec5SDimitry Andric   return EmitLoadOfLValue(LHS, E->getExprLoc());
48710b57cec5SDimitry Andric }
48720b57cec5SDimitry Andric 
VisitBinLAnd(const BinaryOperator * E)48730b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
48740b57cec5SDimitry Andric   // Perform vector logical and on comparisons with zero vectors.
48750b57cec5SDimitry Andric   if (E->getType()->isVectorType()) {
48760b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
48770b57cec5SDimitry Andric 
48780b57cec5SDimitry Andric     Value *LHS = Visit(E->getLHS());
48790b57cec5SDimitry Andric     Value *RHS = Visit(E->getRHS());
48800b57cec5SDimitry Andric     Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
48810b57cec5SDimitry Andric     if (LHS->getType()->isFPOrFPVectorTy()) {
48825ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
48835ffd83dbSDimitry Andric           CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
48840b57cec5SDimitry Andric       LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
48850b57cec5SDimitry Andric       RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
48860b57cec5SDimitry Andric     } else {
48870b57cec5SDimitry Andric       LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
48880b57cec5SDimitry Andric       RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
48890b57cec5SDimitry Andric     }
48900b57cec5SDimitry Andric     Value *And = Builder.CreateAnd(LHS, RHS);
48910b57cec5SDimitry Andric     return Builder.CreateSExt(And, ConvertType(E->getType()), "sext");
48920b57cec5SDimitry Andric   }
48930b57cec5SDimitry Andric 
4894e8d8bef9SDimitry Andric   bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
48950b57cec5SDimitry Andric   llvm::Type *ResTy = ConvertType(E->getType());
48960b57cec5SDimitry Andric 
48970b57cec5SDimitry Andric   // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
48980b57cec5SDimitry Andric   // If we have 1 && X, just emit X without inserting the control flow.
48990b57cec5SDimitry Andric   bool LHSCondVal;
49000b57cec5SDimitry Andric   if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
49010b57cec5SDimitry Andric     if (LHSCondVal) { // If we have 1 && X, just emit X.
49020b57cec5SDimitry Andric       CGF.incrementProfileCounter(E);
49030b57cec5SDimitry Andric 
49041db9f3b2SDimitry Andric       // If the top of the logical operator nest, reset the MCDC temp to 0.
49051db9f3b2SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
49061db9f3b2SDimitry Andric         CGF.maybeResetMCDCCondBitmap(E);
49071db9f3b2SDimitry Andric 
49081db9f3b2SDimitry Andric       CGF.MCDCLogOpStack.push_back(E);
49091db9f3b2SDimitry Andric 
49100b57cec5SDimitry Andric       Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
4911e8d8bef9SDimitry Andric 
4912e8d8bef9SDimitry Andric       // If we're generating for profiling or coverage, generate a branch to a
4913e8d8bef9SDimitry Andric       // block that increments the RHS counter needed to track branch condition
4914e8d8bef9SDimitry Andric       // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
4915e8d8bef9SDimitry Andric       // "FalseBlock" after the increment is done.
4916e8d8bef9SDimitry Andric       if (InstrumentRegions &&
4917e8d8bef9SDimitry Andric           CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
49181db9f3b2SDimitry Andric         CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4919e8d8bef9SDimitry Andric         llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end");
4920e8d8bef9SDimitry Andric         llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4921e8d8bef9SDimitry Andric         Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
4922e8d8bef9SDimitry Andric         CGF.EmitBlock(RHSBlockCnt);
4923e8d8bef9SDimitry Andric         CGF.incrementProfileCounter(E->getRHS());
4924e8d8bef9SDimitry Andric         CGF.EmitBranch(FBlock);
4925e8d8bef9SDimitry Andric         CGF.EmitBlock(FBlock);
4926e8d8bef9SDimitry Andric       }
4927e8d8bef9SDimitry Andric 
49281db9f3b2SDimitry Andric       CGF.MCDCLogOpStack.pop_back();
49291db9f3b2SDimitry Andric       // If the top of the logical operator nest, update the MCDC bitmap.
49301db9f3b2SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
49311db9f3b2SDimitry Andric         CGF.maybeUpdateMCDCTestVectorBitmap(E);
49321db9f3b2SDimitry Andric 
49330b57cec5SDimitry Andric       // ZExt result to int or bool.
49340b57cec5SDimitry Andric       return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
49350b57cec5SDimitry Andric     }
49360b57cec5SDimitry Andric 
49370b57cec5SDimitry Andric     // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
49380b57cec5SDimitry Andric     if (!CGF.ContainsLabel(E->getRHS()))
49390b57cec5SDimitry Andric       return llvm::Constant::getNullValue(ResTy);
49400b57cec5SDimitry Andric   }
49410b57cec5SDimitry Andric 
49421db9f3b2SDimitry Andric   // If the top of the logical operator nest, reset the MCDC temp to 0.
49431db9f3b2SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
49441db9f3b2SDimitry Andric     CGF.maybeResetMCDCCondBitmap(E);
49451db9f3b2SDimitry Andric 
49461db9f3b2SDimitry Andric   CGF.MCDCLogOpStack.push_back(E);
49471db9f3b2SDimitry Andric 
49480b57cec5SDimitry Andric   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
49490b57cec5SDimitry Andric   llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
49500b57cec5SDimitry Andric 
49510b57cec5SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
49520b57cec5SDimitry Andric 
49530b57cec5SDimitry Andric   // Branch on the LHS first.  If it is false, go to the failure (cont) block.
49540b57cec5SDimitry Andric   CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
49550b57cec5SDimitry Andric                            CGF.getProfileCount(E->getRHS()));
49560b57cec5SDimitry Andric 
49570b57cec5SDimitry Andric   // Any edges into the ContBlock are now from an (indeterminate number of)
49580b57cec5SDimitry Andric   // edges from this first condition.  All of these values will be false.  Start
49590b57cec5SDimitry Andric   // setting up the PHI node in the Cont Block for this.
49600b57cec5SDimitry Andric   llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
49610b57cec5SDimitry Andric                                             "", ContBlock);
49620b57cec5SDimitry Andric   for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
49630b57cec5SDimitry Andric        PI != PE; ++PI)
49640b57cec5SDimitry Andric     PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
49650b57cec5SDimitry Andric 
49660b57cec5SDimitry Andric   eval.begin(CGF);
49670b57cec5SDimitry Andric   CGF.EmitBlock(RHSBlock);
49680b57cec5SDimitry Andric   CGF.incrementProfileCounter(E);
49690b57cec5SDimitry Andric   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
49700b57cec5SDimitry Andric   eval.end(CGF);
49710b57cec5SDimitry Andric 
49720b57cec5SDimitry Andric   // Reaquire the RHS block, as there may be subblocks inserted.
49730b57cec5SDimitry Andric   RHSBlock = Builder.GetInsertBlock();
49740b57cec5SDimitry Andric 
4975e8d8bef9SDimitry Andric   // If we're generating for profiling or coverage, generate a branch on the
4976e8d8bef9SDimitry Andric   // RHS to a block that increments the RHS true counter needed to track branch
4977e8d8bef9SDimitry Andric   // condition coverage.
4978e8d8bef9SDimitry Andric   if (InstrumentRegions &&
4979e8d8bef9SDimitry Andric       CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
49801db9f3b2SDimitry Andric     CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
4981e8d8bef9SDimitry Andric     llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
4982e8d8bef9SDimitry Andric     Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
4983e8d8bef9SDimitry Andric     CGF.EmitBlock(RHSBlockCnt);
4984e8d8bef9SDimitry Andric     CGF.incrementProfileCounter(E->getRHS());
4985e8d8bef9SDimitry Andric     CGF.EmitBranch(ContBlock);
4986e8d8bef9SDimitry Andric     PN->addIncoming(RHSCond, RHSBlockCnt);
4987e8d8bef9SDimitry Andric   }
4988e8d8bef9SDimitry Andric 
49890b57cec5SDimitry Andric   // Emit an unconditional branch from this block to ContBlock.
49900b57cec5SDimitry Andric   {
49910b57cec5SDimitry Andric     // There is no need to emit line number for unconditional branch.
49920b57cec5SDimitry Andric     auto NL = ApplyDebugLocation::CreateEmpty(CGF);
49930b57cec5SDimitry Andric     CGF.EmitBlock(ContBlock);
49940b57cec5SDimitry Andric   }
49950b57cec5SDimitry Andric   // Insert an entry into the phi node for the edge with the value of RHSCond.
49960b57cec5SDimitry Andric   PN->addIncoming(RHSCond, RHSBlock);
49970b57cec5SDimitry Andric 
49981db9f3b2SDimitry Andric   CGF.MCDCLogOpStack.pop_back();
49991db9f3b2SDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap.
50001db9f3b2SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
50011db9f3b2SDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(E);
50021db9f3b2SDimitry Andric 
50030b57cec5SDimitry Andric   // Artificial location to preserve the scope information
50040b57cec5SDimitry Andric   {
50050b57cec5SDimitry Andric     auto NL = ApplyDebugLocation::CreateArtificial(CGF);
50060b57cec5SDimitry Andric     PN->setDebugLoc(Builder.getCurrentDebugLocation());
50070b57cec5SDimitry Andric   }
50080b57cec5SDimitry Andric 
50090b57cec5SDimitry Andric   // ZExt result to int.
50100b57cec5SDimitry Andric   return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");
50110b57cec5SDimitry Andric }
50120b57cec5SDimitry Andric 
VisitBinLOr(const BinaryOperator * E)50130b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
50140b57cec5SDimitry Andric   // Perform vector logical or on comparisons with zero vectors.
50150b57cec5SDimitry Andric   if (E->getType()->isVectorType()) {
50160b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
50170b57cec5SDimitry Andric 
50180b57cec5SDimitry Andric     Value *LHS = Visit(E->getLHS());
50190b57cec5SDimitry Andric     Value *RHS = Visit(E->getRHS());
50200b57cec5SDimitry Andric     Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
50210b57cec5SDimitry Andric     if (LHS->getType()->isFPOrFPVectorTy()) {
50225ffd83dbSDimitry Andric       CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
50235ffd83dbSDimitry Andric           CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
50240b57cec5SDimitry Andric       LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
50250b57cec5SDimitry Andric       RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
50260b57cec5SDimitry Andric     } else {
50270b57cec5SDimitry Andric       LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS, Zero, "cmp");
50280b57cec5SDimitry Andric       RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS, Zero, "cmp");
50290b57cec5SDimitry Andric     }
50300b57cec5SDimitry Andric     Value *Or = Builder.CreateOr(LHS, RHS);
50310b57cec5SDimitry Andric     return Builder.CreateSExt(Or, ConvertType(E->getType()), "sext");
50320b57cec5SDimitry Andric   }
50330b57cec5SDimitry Andric 
5034e8d8bef9SDimitry Andric   bool InstrumentRegions = CGF.CGM.getCodeGenOpts().hasProfileClangInstr();
50350b57cec5SDimitry Andric   llvm::Type *ResTy = ConvertType(E->getType());
50360b57cec5SDimitry Andric 
50370b57cec5SDimitry Andric   // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
50380b57cec5SDimitry Andric   // If we have 0 || X, just emit X without inserting the control flow.
50390b57cec5SDimitry Andric   bool LHSCondVal;
50400b57cec5SDimitry Andric   if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
50410b57cec5SDimitry Andric     if (!LHSCondVal) { // If we have 0 || X, just emit X.
50420b57cec5SDimitry Andric       CGF.incrementProfileCounter(E);
50430b57cec5SDimitry Andric 
50441db9f3b2SDimitry Andric       // If the top of the logical operator nest, reset the MCDC temp to 0.
50451db9f3b2SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
50461db9f3b2SDimitry Andric         CGF.maybeResetMCDCCondBitmap(E);
50471db9f3b2SDimitry Andric 
50481db9f3b2SDimitry Andric       CGF.MCDCLogOpStack.push_back(E);
50491db9f3b2SDimitry Andric 
50500b57cec5SDimitry Andric       Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
5051e8d8bef9SDimitry Andric 
5052e8d8bef9SDimitry Andric       // If we're generating for profiling or coverage, generate a branch to a
5053e8d8bef9SDimitry Andric       // block that increments the RHS counter need to track branch condition
5054e8d8bef9SDimitry Andric       // coverage. In this case, use "FBlock" as both the final "TrueBlock" and
5055e8d8bef9SDimitry Andric       // "FalseBlock" after the increment is done.
5056e8d8bef9SDimitry Andric       if (InstrumentRegions &&
5057e8d8bef9SDimitry Andric           CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
50581db9f3b2SDimitry Andric         CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
5059e8d8bef9SDimitry Andric         llvm::BasicBlock *FBlock = CGF.createBasicBlock("lor.end");
5060e8d8bef9SDimitry Andric         llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
5061e8d8bef9SDimitry Andric         Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5062e8d8bef9SDimitry Andric         CGF.EmitBlock(RHSBlockCnt);
5063e8d8bef9SDimitry Andric         CGF.incrementProfileCounter(E->getRHS());
5064e8d8bef9SDimitry Andric         CGF.EmitBranch(FBlock);
5065e8d8bef9SDimitry Andric         CGF.EmitBlock(FBlock);
5066e8d8bef9SDimitry Andric       }
5067e8d8bef9SDimitry Andric 
50681db9f3b2SDimitry Andric       CGF.MCDCLogOpStack.pop_back();
50691db9f3b2SDimitry Andric       // If the top of the logical operator nest, update the MCDC bitmap.
50701db9f3b2SDimitry Andric       if (CGF.MCDCLogOpStack.empty())
50711db9f3b2SDimitry Andric         CGF.maybeUpdateMCDCTestVectorBitmap(E);
50721db9f3b2SDimitry Andric 
50730b57cec5SDimitry Andric       // ZExt result to int or bool.
50740b57cec5SDimitry Andric       return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
50750b57cec5SDimitry Andric     }
50760b57cec5SDimitry Andric 
50770b57cec5SDimitry Andric     // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.
50780b57cec5SDimitry Andric     if (!CGF.ContainsLabel(E->getRHS()))
50790b57cec5SDimitry Andric       return llvm::ConstantInt::get(ResTy, 1);
50800b57cec5SDimitry Andric   }
50810b57cec5SDimitry Andric 
50821db9f3b2SDimitry Andric   // If the top of the logical operator nest, reset the MCDC temp to 0.
50831db9f3b2SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
50841db9f3b2SDimitry Andric     CGF.maybeResetMCDCCondBitmap(E);
50851db9f3b2SDimitry Andric 
50861db9f3b2SDimitry Andric   CGF.MCDCLogOpStack.push_back(E);
50871db9f3b2SDimitry Andric 
50880b57cec5SDimitry Andric   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end");
50890b57cec5SDimitry Andric   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs");
50900b57cec5SDimitry Andric 
50910b57cec5SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
50920b57cec5SDimitry Andric 
50930b57cec5SDimitry Andric   // Branch on the LHS first.  If it is true, go to the success (cont) block.
50940b57cec5SDimitry Andric   CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock,
50950b57cec5SDimitry Andric                            CGF.getCurrentProfileCount() -
50960b57cec5SDimitry Andric                                CGF.getProfileCount(E->getRHS()));
50970b57cec5SDimitry Andric 
50980b57cec5SDimitry Andric   // Any edges into the ContBlock are now from an (indeterminate number of)
50990b57cec5SDimitry Andric   // edges from this first condition.  All of these values will be true.  Start
51000b57cec5SDimitry Andric   // setting up the PHI node in the Cont Block for this.
51010b57cec5SDimitry Andric   llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
51020b57cec5SDimitry Andric                                             "", ContBlock);
51030b57cec5SDimitry Andric   for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
51040b57cec5SDimitry Andric        PI != PE; ++PI)
51050b57cec5SDimitry Andric     PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
51060b57cec5SDimitry Andric 
51070b57cec5SDimitry Andric   eval.begin(CGF);
51080b57cec5SDimitry Andric 
51090b57cec5SDimitry Andric   // Emit the RHS condition as a bool value.
51100b57cec5SDimitry Andric   CGF.EmitBlock(RHSBlock);
51110b57cec5SDimitry Andric   CGF.incrementProfileCounter(E);
51120b57cec5SDimitry Andric   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
51130b57cec5SDimitry Andric 
51140b57cec5SDimitry Andric   eval.end(CGF);
51150b57cec5SDimitry Andric 
51160b57cec5SDimitry Andric   // Reaquire the RHS block, as there may be subblocks inserted.
51170b57cec5SDimitry Andric   RHSBlock = Builder.GetInsertBlock();
51180b57cec5SDimitry Andric 
5119e8d8bef9SDimitry Andric   // If we're generating for profiling or coverage, generate a branch on the
5120e8d8bef9SDimitry Andric   // RHS to a block that increments the RHS true counter needed to track branch
5121e8d8bef9SDimitry Andric   // condition coverage.
5122e8d8bef9SDimitry Andric   if (InstrumentRegions &&
5123e8d8bef9SDimitry Andric       CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
51241db9f3b2SDimitry Andric     CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
5125e8d8bef9SDimitry Andric     llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt");
5126e8d8bef9SDimitry Andric     Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5127e8d8bef9SDimitry Andric     CGF.EmitBlock(RHSBlockCnt);
5128e8d8bef9SDimitry Andric     CGF.incrementProfileCounter(E->getRHS());
5129e8d8bef9SDimitry Andric     CGF.EmitBranch(ContBlock);
5130e8d8bef9SDimitry Andric     PN->addIncoming(RHSCond, RHSBlockCnt);
5131e8d8bef9SDimitry Andric   }
5132e8d8bef9SDimitry Andric 
51330b57cec5SDimitry Andric   // Emit an unconditional branch from this block to ContBlock.  Insert an entry
51340b57cec5SDimitry Andric   // into the phi node for the edge with the value of RHSCond.
51350b57cec5SDimitry Andric   CGF.EmitBlock(ContBlock);
51360b57cec5SDimitry Andric   PN->addIncoming(RHSCond, RHSBlock);
51370b57cec5SDimitry Andric 
51381db9f3b2SDimitry Andric   CGF.MCDCLogOpStack.pop_back();
51391db9f3b2SDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap.
51401db9f3b2SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
51411db9f3b2SDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(E);
51421db9f3b2SDimitry Andric 
51430b57cec5SDimitry Andric   // ZExt result to int.
51440b57cec5SDimitry Andric   return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");
51450b57cec5SDimitry Andric }
51460b57cec5SDimitry Andric 
VisitBinComma(const BinaryOperator * E)51470b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
51480b57cec5SDimitry Andric   CGF.EmitIgnoredExpr(E->getLHS());
51490b57cec5SDimitry Andric   CGF.EnsureInsertPoint();
51500b57cec5SDimitry Andric   return Visit(E->getRHS());
51510b57cec5SDimitry Andric }
51520b57cec5SDimitry Andric 
51530b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
51540b57cec5SDimitry Andric //                             Other Operators
51550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
51560b57cec5SDimitry Andric 
51570b57cec5SDimitry Andric /// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
51580b57cec5SDimitry Andric /// expression is cheap enough and side-effect-free enough to evaluate
51590b57cec5SDimitry Andric /// unconditionally instead of conditionally.  This is used to convert control
51600b57cec5SDimitry Andric /// flow into selects in some cases.
isCheapEnoughToEvaluateUnconditionally(const Expr * E,CodeGenFunction & CGF)51610b57cec5SDimitry Andric static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E,
51620b57cec5SDimitry Andric                                                    CodeGenFunction &CGF) {
51630b57cec5SDimitry Andric   // Anything that is an integer or floating point constant is fine.
51640b57cec5SDimitry Andric   return E->IgnoreParens()->isEvaluatable(CGF.getContext());
51650b57cec5SDimitry Andric 
51660b57cec5SDimitry Andric   // Even non-volatile automatic variables can't be evaluated unconditionally.
51670b57cec5SDimitry Andric   // Referencing a thread_local may cause non-trivial initialization work to
51680b57cec5SDimitry Andric   // occur. If we're inside a lambda and one of the variables is from the scope
51690b57cec5SDimitry Andric   // outside the lambda, that function may have returned already. Reading its
51700b57cec5SDimitry Andric   // locals is a bad idea. Also, these reads may introduce races there didn't
51710b57cec5SDimitry Andric   // exist in the source-level program.
51720b57cec5SDimitry Andric }
51730b57cec5SDimitry Andric 
51740b57cec5SDimitry Andric 
51750b57cec5SDimitry Andric Value *ScalarExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)51760b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
51770b57cec5SDimitry Andric   TestAndClearIgnoreResultAssign();
51780b57cec5SDimitry Andric 
51790b57cec5SDimitry Andric   // Bind the common expression if necessary.
51800b57cec5SDimitry Andric   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
51810b57cec5SDimitry Andric 
51820b57cec5SDimitry Andric   Expr *condExpr = E->getCond();
51830b57cec5SDimitry Andric   Expr *lhsExpr = E->getTrueExpr();
51840b57cec5SDimitry Andric   Expr *rhsExpr = E->getFalseExpr();
51850b57cec5SDimitry Andric 
51860b57cec5SDimitry Andric   // If the condition constant folds and can be elided, try to avoid emitting
51870b57cec5SDimitry Andric   // the condition and the dead arm.
51880b57cec5SDimitry Andric   bool CondExprBool;
51890b57cec5SDimitry Andric   if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
51900b57cec5SDimitry Andric     Expr *live = lhsExpr, *dead = rhsExpr;
51910b57cec5SDimitry Andric     if (!CondExprBool) std::swap(live, dead);
51920b57cec5SDimitry Andric 
51930b57cec5SDimitry Andric     // If the dead side doesn't have labels we need, just emit the Live part.
51940b57cec5SDimitry Andric     if (!CGF.ContainsLabel(dead)) {
51950fca6ea1SDimitry Andric       if (CondExprBool) {
51960fca6ea1SDimitry Andric         if (llvm::EnableSingleByteCoverage) {
51970fca6ea1SDimitry Andric           CGF.incrementProfileCounter(lhsExpr);
51980fca6ea1SDimitry Andric           CGF.incrementProfileCounter(rhsExpr);
51990fca6ea1SDimitry Andric         }
52000b57cec5SDimitry Andric         CGF.incrementProfileCounter(E);
52010fca6ea1SDimitry Andric       }
52020b57cec5SDimitry Andric       Value *Result = Visit(live);
52030b57cec5SDimitry Andric 
52040b57cec5SDimitry Andric       // If the live part is a throw expression, it acts like it has a void
52050b57cec5SDimitry Andric       // type, so evaluating it returns a null Value*.  However, a conditional
52060b57cec5SDimitry Andric       // with non-void type must return a non-null Value*.
52070b57cec5SDimitry Andric       if (!Result && !E->getType()->isVoidType())
52080b57cec5SDimitry Andric         Result = llvm::UndefValue::get(CGF.ConvertType(E->getType()));
52090b57cec5SDimitry Andric 
52100b57cec5SDimitry Andric       return Result;
52110b57cec5SDimitry Andric     }
52120b57cec5SDimitry Andric   }
52130b57cec5SDimitry Andric 
52140b57cec5SDimitry Andric   // OpenCL: If the condition is a vector, we can treat this condition like
52150b57cec5SDimitry Andric   // the select function.
52165ffd83dbSDimitry Andric   if ((CGF.getLangOpts().OpenCL && condExpr->getType()->isVectorType()) ||
52175ffd83dbSDimitry Andric       condExpr->getType()->isExtVectorType()) {
52180b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
52190b57cec5SDimitry Andric 
52200b57cec5SDimitry Andric     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
52210b57cec5SDimitry Andric     llvm::Value *LHS = Visit(lhsExpr);
52220b57cec5SDimitry Andric     llvm::Value *RHS = Visit(rhsExpr);
52230b57cec5SDimitry Andric 
52240b57cec5SDimitry Andric     llvm::Type *condType = ConvertType(condExpr->getType());
5225e8d8bef9SDimitry Andric     auto *vecTy = cast<llvm::FixedVectorType>(condType);
52260b57cec5SDimitry Andric 
52270b57cec5SDimitry Andric     unsigned numElem = vecTy->getNumElements();
52280b57cec5SDimitry Andric     llvm::Type *elemType = vecTy->getElementType();
52290b57cec5SDimitry Andric 
52300b57cec5SDimitry Andric     llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
52310b57cec5SDimitry Andric     llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
52325ffd83dbSDimitry Andric     llvm::Value *tmp = Builder.CreateSExt(
52335ffd83dbSDimitry Andric         TestMSB, llvm::FixedVectorType::get(elemType, numElem), "sext");
52340b57cec5SDimitry Andric     llvm::Value *tmp2 = Builder.CreateNot(tmp);
52350b57cec5SDimitry Andric 
52360b57cec5SDimitry Andric     // Cast float to int to perform ANDs if necessary.
52370b57cec5SDimitry Andric     llvm::Value *RHSTmp = RHS;
52380b57cec5SDimitry Andric     llvm::Value *LHSTmp = LHS;
52390b57cec5SDimitry Andric     bool wasCast = false;
52400b57cec5SDimitry Andric     llvm::VectorType *rhsVTy = cast<llvm::VectorType>(RHS->getType());
52410b57cec5SDimitry Andric     if (rhsVTy->getElementType()->isFloatingPointTy()) {
52420b57cec5SDimitry Andric       RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
52430b57cec5SDimitry Andric       LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
52440b57cec5SDimitry Andric       wasCast = true;
52450b57cec5SDimitry Andric     }
52460b57cec5SDimitry Andric 
52470b57cec5SDimitry Andric     llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
52480b57cec5SDimitry Andric     llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
52490b57cec5SDimitry Andric     llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4, "cond");
52500b57cec5SDimitry Andric     if (wasCast)
52510b57cec5SDimitry Andric       tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
52520b57cec5SDimitry Andric 
52530b57cec5SDimitry Andric     return tmp5;
52540b57cec5SDimitry Andric   }
52550b57cec5SDimitry Andric 
525681ad6265SDimitry Andric   if (condExpr->getType()->isVectorType() ||
52575f757f3fSDimitry Andric       condExpr->getType()->isSveVLSBuiltinType()) {
5258480093f4SDimitry Andric     CGF.incrementProfileCounter(E);
5259480093f4SDimitry Andric 
5260480093f4SDimitry Andric     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
5261480093f4SDimitry Andric     llvm::Value *LHS = Visit(lhsExpr);
5262480093f4SDimitry Andric     llvm::Value *RHS = Visit(rhsExpr);
5263480093f4SDimitry Andric 
5264480093f4SDimitry Andric     llvm::Type *CondType = ConvertType(condExpr->getType());
5265480093f4SDimitry Andric     auto *VecTy = cast<llvm::VectorType>(CondType);
5266480093f4SDimitry Andric     llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5267480093f4SDimitry Andric 
5268480093f4SDimitry Andric     CondV = Builder.CreateICmpNE(CondV, ZeroVec, "vector_cond");
5269480093f4SDimitry Andric     return Builder.CreateSelect(CondV, LHS, RHS, "vector_select");
5270480093f4SDimitry Andric   }
5271480093f4SDimitry Andric 
52720b57cec5SDimitry Andric   // If this is a really simple expression (like x ? 4 : 5), emit this as a
52730b57cec5SDimitry Andric   // select instead of as control flow.  We can only do this if it is cheap and
52740b57cec5SDimitry Andric   // safe to evaluate the LHS and RHS unconditionally.
52750b57cec5SDimitry Andric   if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
52760b57cec5SDimitry Andric       isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
52770b57cec5SDimitry Andric     llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
52780b57cec5SDimitry Andric     llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
52790b57cec5SDimitry Andric 
52800fca6ea1SDimitry Andric     if (llvm::EnableSingleByteCoverage) {
52810fca6ea1SDimitry Andric       CGF.incrementProfileCounter(lhsExpr);
52820fca6ea1SDimitry Andric       CGF.incrementProfileCounter(rhsExpr);
52830fca6ea1SDimitry Andric       CGF.incrementProfileCounter(E);
52840fca6ea1SDimitry Andric     } else
52850b57cec5SDimitry Andric       CGF.incrementProfileCounter(E, StepV);
52860b57cec5SDimitry Andric 
52870b57cec5SDimitry Andric     llvm::Value *LHS = Visit(lhsExpr);
52880b57cec5SDimitry Andric     llvm::Value *RHS = Visit(rhsExpr);
52890b57cec5SDimitry Andric     if (!LHS) {
52900b57cec5SDimitry Andric       // If the conditional has void type, make sure we return a null Value*.
52910b57cec5SDimitry Andric       assert(!RHS && "LHS and RHS types must match");
52920b57cec5SDimitry Andric       return nullptr;
52930b57cec5SDimitry Andric     }
52940b57cec5SDimitry Andric     return Builder.CreateSelect(CondV, LHS, RHS, "cond");
52950b57cec5SDimitry Andric   }
52960b57cec5SDimitry Andric 
52971db9f3b2SDimitry Andric   // If the top of the logical operator nest, reset the MCDC temp to 0.
52981db9f3b2SDimitry Andric   if (CGF.MCDCLogOpStack.empty())
52991db9f3b2SDimitry Andric     CGF.maybeResetMCDCCondBitmap(condExpr);
53001db9f3b2SDimitry Andric 
53010b57cec5SDimitry Andric   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
53020b57cec5SDimitry Andric   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
53030b57cec5SDimitry Andric   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
53040b57cec5SDimitry Andric 
53050b57cec5SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
53060b57cec5SDimitry Andric   CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock,
53070b57cec5SDimitry Andric                            CGF.getProfileCount(lhsExpr));
53080b57cec5SDimitry Andric 
53090b57cec5SDimitry Andric   CGF.EmitBlock(LHSBlock);
53107a6dacacSDimitry Andric 
53117a6dacacSDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap for the
53127a6dacacSDimitry Andric   // ConditionalOperator prior to visiting its LHS and RHS blocks, since they
53137a6dacacSDimitry Andric   // may also contain a boolean expression.
53147a6dacacSDimitry Andric   if (CGF.MCDCLogOpStack.empty())
53157a6dacacSDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
53167a6dacacSDimitry Andric 
53170fca6ea1SDimitry Andric   if (llvm::EnableSingleByteCoverage)
53180fca6ea1SDimitry Andric     CGF.incrementProfileCounter(lhsExpr);
53190fca6ea1SDimitry Andric   else
53200b57cec5SDimitry Andric     CGF.incrementProfileCounter(E);
53210fca6ea1SDimitry Andric 
53220b57cec5SDimitry Andric   eval.begin(CGF);
53230b57cec5SDimitry Andric   Value *LHS = Visit(lhsExpr);
53240b57cec5SDimitry Andric   eval.end(CGF);
53250b57cec5SDimitry Andric 
53260b57cec5SDimitry Andric   LHSBlock = Builder.GetInsertBlock();
53270b57cec5SDimitry Andric   Builder.CreateBr(ContBlock);
53280b57cec5SDimitry Andric 
53290b57cec5SDimitry Andric   CGF.EmitBlock(RHSBlock);
53307a6dacacSDimitry Andric 
53317a6dacacSDimitry Andric   // If the top of the logical operator nest, update the MCDC bitmap for the
53327a6dacacSDimitry Andric   // ConditionalOperator prior to visiting its LHS and RHS blocks, since they
53337a6dacacSDimitry Andric   // may also contain a boolean expression.
53347a6dacacSDimitry Andric   if (CGF.MCDCLogOpStack.empty())
53357a6dacacSDimitry Andric     CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
53367a6dacacSDimitry Andric 
53370fca6ea1SDimitry Andric   if (llvm::EnableSingleByteCoverage)
53380fca6ea1SDimitry Andric     CGF.incrementProfileCounter(rhsExpr);
53390fca6ea1SDimitry Andric 
53400b57cec5SDimitry Andric   eval.begin(CGF);
53410b57cec5SDimitry Andric   Value *RHS = Visit(rhsExpr);
53420b57cec5SDimitry Andric   eval.end(CGF);
53430b57cec5SDimitry Andric 
53440b57cec5SDimitry Andric   RHSBlock = Builder.GetInsertBlock();
53450b57cec5SDimitry Andric   CGF.EmitBlock(ContBlock);
53460b57cec5SDimitry Andric 
53470b57cec5SDimitry Andric   // If the LHS or RHS is a throw expression, it will be legitimately null.
53480b57cec5SDimitry Andric   if (!LHS)
53490b57cec5SDimitry Andric     return RHS;
53500b57cec5SDimitry Andric   if (!RHS)
53510b57cec5SDimitry Andric     return LHS;
53520b57cec5SDimitry Andric 
53530b57cec5SDimitry Andric   // Create a PHI node for the real part.
53540b57cec5SDimitry Andric   llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), 2, "cond");
53550b57cec5SDimitry Andric   PN->addIncoming(LHS, LHSBlock);
53560b57cec5SDimitry Andric   PN->addIncoming(RHS, RHSBlock);
53571db9f3b2SDimitry Andric 
53580fca6ea1SDimitry Andric   // When single byte coverage mode is enabled, add a counter to continuation
53590fca6ea1SDimitry Andric   // block.
53600fca6ea1SDimitry Andric   if (llvm::EnableSingleByteCoverage)
53610fca6ea1SDimitry Andric     CGF.incrementProfileCounter(E);
53620fca6ea1SDimitry Andric 
53630b57cec5SDimitry Andric   return PN;
53640b57cec5SDimitry Andric }
53650b57cec5SDimitry Andric 
VisitChooseExpr(ChooseExpr * E)53660b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
53670b57cec5SDimitry Andric   return Visit(E->getChosenSubExpr());
53680b57cec5SDimitry Andric }
53690b57cec5SDimitry Andric 
VisitVAArgExpr(VAArgExpr * VE)53700b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
53710b57cec5SDimitry Andric   QualType Ty = VE->getType();
53720b57cec5SDimitry Andric 
53730b57cec5SDimitry Andric   if (Ty->isVariablyModifiedType())
53740b57cec5SDimitry Andric     CGF.EmitVariablyModifiedType(Ty);
53750b57cec5SDimitry Andric 
53760b57cec5SDimitry Andric   Address ArgValue = Address::invalid();
53770fca6ea1SDimitry Andric   RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);
53780b57cec5SDimitry Andric 
53790fca6ea1SDimitry Andric   return ArgPtr.getScalarVal();
53800b57cec5SDimitry Andric }
53810b57cec5SDimitry Andric 
VisitBlockExpr(const BlockExpr * block)53820b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
53830b57cec5SDimitry Andric   return CGF.EmitBlockLiteral(block);
53840b57cec5SDimitry Andric }
53850b57cec5SDimitry Andric 
53860b57cec5SDimitry Andric // Convert a vec3 to vec4, or vice versa.
ConvertVec3AndVec4(CGBuilderTy & Builder,CodeGenFunction & CGF,Value * Src,unsigned NumElementsDst)53870b57cec5SDimitry Andric static Value *ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF,
53880b57cec5SDimitry Andric                                  Value *Src, unsigned NumElementsDst) {
53895ffd83dbSDimitry Andric   static constexpr int Mask[] = {0, 1, 2, -1};
5390bdd1243dSDimitry Andric   return Builder.CreateShuffleVector(Src, llvm::ArrayRef(Mask, NumElementsDst));
53910b57cec5SDimitry Andric }
53920b57cec5SDimitry Andric 
53930b57cec5SDimitry Andric // Create cast instructions for converting LLVM value \p Src to LLVM type \p
53940b57cec5SDimitry Andric // DstTy. \p Src has the same size as \p DstTy. Both are single value types
53950b57cec5SDimitry Andric // but could be scalar or vectors of different lengths, and either can be
53960b57cec5SDimitry Andric // pointer.
53970b57cec5SDimitry Andric // There are 4 cases:
53980b57cec5SDimitry Andric // 1. non-pointer -> non-pointer  : needs 1 bitcast
53990b57cec5SDimitry Andric // 2. pointer -> pointer          : needs 1 bitcast or addrspacecast
54000b57cec5SDimitry Andric // 3. pointer -> non-pointer
54010b57cec5SDimitry Andric //   a) pointer -> intptr_t       : needs 1 ptrtoint
54020b57cec5SDimitry Andric //   b) pointer -> non-intptr_t   : needs 1 ptrtoint then 1 bitcast
54030b57cec5SDimitry Andric // 4. non-pointer -> pointer
54040b57cec5SDimitry Andric //   a) intptr_t -> pointer       : needs 1 inttoptr
54050b57cec5SDimitry Andric //   b) non-intptr_t -> pointer   : needs 1 bitcast then 1 inttoptr
54060b57cec5SDimitry Andric // Note: for cases 3b and 4b two casts are required since LLVM casts do not
54070b57cec5SDimitry Andric // allow casting directly between pointer types and non-integer non-pointer
54080b57cec5SDimitry Andric // types.
createCastsForTypeOfSameSize(CGBuilderTy & Builder,const llvm::DataLayout & DL,Value * Src,llvm::Type * DstTy,StringRef Name="")54090b57cec5SDimitry Andric static Value *createCastsForTypeOfSameSize(CGBuilderTy &Builder,
54100b57cec5SDimitry Andric                                            const llvm::DataLayout &DL,
54110b57cec5SDimitry Andric                                            Value *Src, llvm::Type *DstTy,
54120b57cec5SDimitry Andric                                            StringRef Name = "") {
54130b57cec5SDimitry Andric   auto SrcTy = Src->getType();
54140b57cec5SDimitry Andric 
54150b57cec5SDimitry Andric   // Case 1.
54160b57cec5SDimitry Andric   if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
54170b57cec5SDimitry Andric     return Builder.CreateBitCast(Src, DstTy, Name);
54180b57cec5SDimitry Andric 
54190b57cec5SDimitry Andric   // Case 2.
54200b57cec5SDimitry Andric   if (SrcTy->isPointerTy() && DstTy->isPointerTy())
54210b57cec5SDimitry Andric     return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
54220b57cec5SDimitry Andric 
54230b57cec5SDimitry Andric   // Case 3.
54240b57cec5SDimitry Andric   if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
54250b57cec5SDimitry Andric     // Case 3b.
54260b57cec5SDimitry Andric     if (!DstTy->isIntegerTy())
54270b57cec5SDimitry Andric       Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
54280b57cec5SDimitry Andric     // Cases 3a and 3b.
54290b57cec5SDimitry Andric     return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
54300b57cec5SDimitry Andric   }
54310b57cec5SDimitry Andric 
54320b57cec5SDimitry Andric   // Case 4b.
54330b57cec5SDimitry Andric   if (!SrcTy->isIntegerTy())
54340b57cec5SDimitry Andric     Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
54350b57cec5SDimitry Andric   // Cases 4a and 4b.
54360b57cec5SDimitry Andric   return Builder.CreateIntToPtr(Src, DstTy, Name);
54370b57cec5SDimitry Andric }
54380b57cec5SDimitry Andric 
VisitAsTypeExpr(AsTypeExpr * E)54390b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
54400b57cec5SDimitry Andric   Value *Src  = CGF.EmitScalarExpr(E->getSrcExpr());
54410b57cec5SDimitry Andric   llvm::Type *DstTy = ConvertType(E->getType());
54420b57cec5SDimitry Andric 
54430b57cec5SDimitry Andric   llvm::Type *SrcTy = Src->getType();
5444e8d8bef9SDimitry Andric   unsigned NumElementsSrc =
5445e8d8bef9SDimitry Andric       isa<llvm::VectorType>(SrcTy)
5446e8d8bef9SDimitry Andric           ? cast<llvm::FixedVectorType>(SrcTy)->getNumElements()
5447e8d8bef9SDimitry Andric           : 0;
5448e8d8bef9SDimitry Andric   unsigned NumElementsDst =
5449e8d8bef9SDimitry Andric       isa<llvm::VectorType>(DstTy)
5450e8d8bef9SDimitry Andric           ? cast<llvm::FixedVectorType>(DstTy)->getNumElements()
5451e8d8bef9SDimitry Andric           : 0;
54520b57cec5SDimitry Andric 
545381ad6265SDimitry Andric   // Use bit vector expansion for ext_vector_type boolean vectors.
545481ad6265SDimitry Andric   if (E->getType()->isExtVectorBoolType())
545581ad6265SDimitry Andric     return CGF.emitBoolVecConversion(Src, NumElementsDst, "astype");
545681ad6265SDimitry Andric 
54570b57cec5SDimitry Andric   // Going from vec3 to non-vec3 is a special case and requires a shuffle
54580b57cec5SDimitry Andric   // vector to get a vec4, then a bitcast if the target type is different.
54590b57cec5SDimitry Andric   if (NumElementsSrc == 3 && NumElementsDst != 3) {
54600b57cec5SDimitry Andric     Src = ConvertVec3AndVec4(Builder, CGF, Src, 4);
54610b57cec5SDimitry Andric     Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
54620b57cec5SDimitry Andric                                        DstTy);
54630b57cec5SDimitry Andric 
54640b57cec5SDimitry Andric     Src->setName("astype");
54650b57cec5SDimitry Andric     return Src;
54660b57cec5SDimitry Andric   }
54670b57cec5SDimitry Andric 
54680b57cec5SDimitry Andric   // Going from non-vec3 to vec3 is a special case and requires a bitcast
54690b57cec5SDimitry Andric   // to vec4 if the original type is not vec4, then a shuffle vector to
54700b57cec5SDimitry Andric   // get a vec3.
54710b57cec5SDimitry Andric   if (NumElementsSrc != 3 && NumElementsDst == 3) {
54725ffd83dbSDimitry Andric     auto *Vec4Ty = llvm::FixedVectorType::get(
54735ffd83dbSDimitry Andric         cast<llvm::VectorType>(DstTy)->getElementType(), 4);
54740b57cec5SDimitry Andric     Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src,
54750b57cec5SDimitry Andric                                        Vec4Ty);
54760b57cec5SDimitry Andric 
54770b57cec5SDimitry Andric     Src = ConvertVec3AndVec4(Builder, CGF, Src, 3);
54780b57cec5SDimitry Andric     Src->setName("astype");
54790b57cec5SDimitry Andric     return Src;
54800b57cec5SDimitry Andric   }
54810b57cec5SDimitry Andric 
5482a7dea167SDimitry Andric   return createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(),
54830b57cec5SDimitry Andric                                       Src, DstTy, "astype");
54840b57cec5SDimitry Andric }
54850b57cec5SDimitry Andric 
VisitAtomicExpr(AtomicExpr * E)54860b57cec5SDimitry Andric Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
54870b57cec5SDimitry Andric   return CGF.EmitAtomicExpr(E).getScalarVal();
54880b57cec5SDimitry Andric }
54890b57cec5SDimitry Andric 
54900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
54910b57cec5SDimitry Andric //                         Entry Point into this File
54920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
54930b57cec5SDimitry Andric 
54940b57cec5SDimitry Andric /// Emit the computation of the specified expression of scalar type, ignoring
54950b57cec5SDimitry Andric /// the result.
EmitScalarExpr(const Expr * E,bool IgnoreResultAssign)54960b57cec5SDimitry Andric Value *CodeGenFunction::EmitScalarExpr(const Expr *E, bool IgnoreResultAssign) {
54970b57cec5SDimitry Andric   assert(E && hasScalarEvaluationKind(E->getType()) &&
54980b57cec5SDimitry Andric          "Invalid scalar expression to emit");
54990b57cec5SDimitry Andric 
55000b57cec5SDimitry Andric   return ScalarExprEmitter(*this, IgnoreResultAssign)
55010b57cec5SDimitry Andric       .Visit(const_cast<Expr *>(E));
55020b57cec5SDimitry Andric }
55030b57cec5SDimitry Andric 
55040b57cec5SDimitry Andric /// Emit a conversion from the specified type to the specified destination type,
55050b57cec5SDimitry Andric /// both of which are LLVM scalar types.
EmitScalarConversion(Value * Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)55060b57cec5SDimitry Andric Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
55070b57cec5SDimitry Andric                                              QualType DstTy,
55080b57cec5SDimitry Andric                                              SourceLocation Loc) {
55090b57cec5SDimitry Andric   assert(hasScalarEvaluationKind(SrcTy) && hasScalarEvaluationKind(DstTy) &&
55100b57cec5SDimitry Andric          "Invalid scalar expression to emit");
55110b57cec5SDimitry Andric   return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
55120b57cec5SDimitry Andric }
55130b57cec5SDimitry Andric 
55140b57cec5SDimitry Andric /// Emit a conversion from the specified complex type to the specified
55150b57cec5SDimitry Andric /// destination type, where the destination type is an LLVM scalar type.
EmitComplexToScalarConversion(ComplexPairTy Src,QualType SrcTy,QualType DstTy,SourceLocation Loc)55160b57cec5SDimitry Andric Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
55170b57cec5SDimitry Andric                                                       QualType SrcTy,
55180b57cec5SDimitry Andric                                                       QualType DstTy,
55190b57cec5SDimitry Andric                                                       SourceLocation Loc) {
55200b57cec5SDimitry Andric   assert(SrcTy->isAnyComplexType() && hasScalarEvaluationKind(DstTy) &&
55210b57cec5SDimitry Andric          "Invalid complex -> scalar conversion");
55220b57cec5SDimitry Andric   return ScalarExprEmitter(*this)
55230b57cec5SDimitry Andric       .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
55240b57cec5SDimitry Andric }
55250b57cec5SDimitry Andric 
55260b57cec5SDimitry Andric 
5527bdd1243dSDimitry Andric Value *
EmitPromotedScalarExpr(const Expr * E,QualType PromotionType)5528bdd1243dSDimitry Andric CodeGenFunction::EmitPromotedScalarExpr(const Expr *E,
5529bdd1243dSDimitry Andric                                         QualType PromotionType) {
5530bdd1243dSDimitry Andric   if (!PromotionType.isNull())
5531bdd1243dSDimitry Andric     return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
5532bdd1243dSDimitry Andric   else
5533bdd1243dSDimitry Andric     return ScalarExprEmitter(*this).Visit(const_cast<Expr *>(E));
5534bdd1243dSDimitry Andric }
5535bdd1243dSDimitry Andric 
5536bdd1243dSDimitry Andric 
55370b57cec5SDimitry Andric llvm::Value *CodeGenFunction::
EmitScalarPrePostIncDec(const UnaryOperator * E,LValue LV,bool isInc,bool isPre)55380b57cec5SDimitry Andric EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
55390b57cec5SDimitry Andric                         bool isInc, bool isPre) {
55400b57cec5SDimitry Andric   return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
55410b57cec5SDimitry Andric }
55420b57cec5SDimitry Andric 
EmitObjCIsaExpr(const ObjCIsaExpr * E)55430b57cec5SDimitry Andric LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
55440b57cec5SDimitry Andric   // object->isa or (*object).isa
55450b57cec5SDimitry Andric   // Generate code as for: *(Class*)object
55460b57cec5SDimitry Andric 
55470b57cec5SDimitry Andric   Expr *BaseExpr = E->getBase();
55480b57cec5SDimitry Andric   Address Addr = Address::invalid();
5549fe6060f1SDimitry Andric   if (BaseExpr->isPRValue()) {
555081ad6265SDimitry Andric     llvm::Type *BaseTy =
555181ad6265SDimitry Andric         ConvertTypeForMem(BaseExpr->getType()->getPointeeType());
555281ad6265SDimitry Andric     Addr = Address(EmitScalarExpr(BaseExpr), BaseTy, getPointerAlign());
55530b57cec5SDimitry Andric   } else {
55540fca6ea1SDimitry Andric     Addr = EmitLValue(BaseExpr).getAddress();
55550b57cec5SDimitry Andric   }
55560b57cec5SDimitry Andric 
55570b57cec5SDimitry Andric   // Cast the address to Class*.
555806c3fb27SDimitry Andric   Addr = Addr.withElementType(ConvertType(E->getType()));
55590b57cec5SDimitry Andric   return MakeAddrLValue(Addr, E->getType());
55600b57cec5SDimitry Andric }
55610b57cec5SDimitry Andric 
55620b57cec5SDimitry Andric 
EmitCompoundAssignmentLValue(const CompoundAssignOperator * E)55630b57cec5SDimitry Andric LValue CodeGenFunction::EmitCompoundAssignmentLValue(
55640b57cec5SDimitry Andric                                             const CompoundAssignOperator *E) {
55650b57cec5SDimitry Andric   ScalarExprEmitter Scalar(*this);
55660b57cec5SDimitry Andric   Value *Result = nullptr;
55670b57cec5SDimitry Andric   switch (E->getOpcode()) {
55680b57cec5SDimitry Andric #define COMPOUND_OP(Op)                                                       \
55690b57cec5SDimitry Andric     case BO_##Op##Assign:                                                     \
55700b57cec5SDimitry Andric       return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
55710b57cec5SDimitry Andric                                              Result)
55720b57cec5SDimitry Andric   COMPOUND_OP(Mul);
55730b57cec5SDimitry Andric   COMPOUND_OP(Div);
55740b57cec5SDimitry Andric   COMPOUND_OP(Rem);
55750b57cec5SDimitry Andric   COMPOUND_OP(Add);
55760b57cec5SDimitry Andric   COMPOUND_OP(Sub);
55770b57cec5SDimitry Andric   COMPOUND_OP(Shl);
55780b57cec5SDimitry Andric   COMPOUND_OP(Shr);
55790b57cec5SDimitry Andric   COMPOUND_OP(And);
55800b57cec5SDimitry Andric   COMPOUND_OP(Xor);
55810b57cec5SDimitry Andric   COMPOUND_OP(Or);
55820b57cec5SDimitry Andric #undef COMPOUND_OP
55830b57cec5SDimitry Andric 
55840b57cec5SDimitry Andric   case BO_PtrMemD:
55850b57cec5SDimitry Andric   case BO_PtrMemI:
55860b57cec5SDimitry Andric   case BO_Mul:
55870b57cec5SDimitry Andric   case BO_Div:
55880b57cec5SDimitry Andric   case BO_Rem:
55890b57cec5SDimitry Andric   case BO_Add:
55900b57cec5SDimitry Andric   case BO_Sub:
55910b57cec5SDimitry Andric   case BO_Shl:
55920b57cec5SDimitry Andric   case BO_Shr:
55930b57cec5SDimitry Andric   case BO_LT:
55940b57cec5SDimitry Andric   case BO_GT:
55950b57cec5SDimitry Andric   case BO_LE:
55960b57cec5SDimitry Andric   case BO_GE:
55970b57cec5SDimitry Andric   case BO_EQ:
55980b57cec5SDimitry Andric   case BO_NE:
55990b57cec5SDimitry Andric   case BO_Cmp:
56000b57cec5SDimitry Andric   case BO_And:
56010b57cec5SDimitry Andric   case BO_Xor:
56020b57cec5SDimitry Andric   case BO_Or:
56030b57cec5SDimitry Andric   case BO_LAnd:
56040b57cec5SDimitry Andric   case BO_LOr:
56050b57cec5SDimitry Andric   case BO_Assign:
56060b57cec5SDimitry Andric   case BO_Comma:
56070b57cec5SDimitry Andric     llvm_unreachable("Not valid compound assignment operators");
56080b57cec5SDimitry Andric   }
56090b57cec5SDimitry Andric 
56100b57cec5SDimitry Andric   llvm_unreachable("Unhandled compound assignment operator");
56110b57cec5SDimitry Andric }
56120b57cec5SDimitry Andric 
5613a7dea167SDimitry Andric struct GEPOffsetAndOverflow {
5614a7dea167SDimitry Andric   // The total (signed) byte offset for the GEP.
5615a7dea167SDimitry Andric   llvm::Value *TotalOffset;
5616a7dea167SDimitry Andric   // The offset overflow flag - true if the total offset overflows.
5617a7dea167SDimitry Andric   llvm::Value *OffsetOverflows;
5618a7dea167SDimitry Andric };
56190b57cec5SDimitry Andric 
5620a7dea167SDimitry Andric /// Evaluate given GEPVal, which is either an inbounds GEP, or a constant,
5621a7dea167SDimitry Andric /// and compute the total offset it applies from it's base pointer BasePtr.
5622a7dea167SDimitry Andric /// Returns offset in bytes and a boolean flag whether an overflow happened
5623a7dea167SDimitry Andric /// during evaluation.
EmitGEPOffsetInBytes(Value * BasePtr,Value * GEPVal,llvm::LLVMContext & VMContext,CodeGenModule & CGM,CGBuilderTy & Builder)5624a7dea167SDimitry Andric static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal,
5625a7dea167SDimitry Andric                                                  llvm::LLVMContext &VMContext,
5626a7dea167SDimitry Andric                                                  CodeGenModule &CGM,
56275ffd83dbSDimitry Andric                                                  CGBuilderTy &Builder) {
5628a7dea167SDimitry Andric   const auto &DL = CGM.getDataLayout();
56290b57cec5SDimitry Andric 
5630a7dea167SDimitry Andric   // The total (signed) byte offset for the GEP.
5631a7dea167SDimitry Andric   llvm::Value *TotalOffset = nullptr;
56320b57cec5SDimitry Andric 
5633a7dea167SDimitry Andric   // Was the GEP already reduced to a constant?
5634a7dea167SDimitry Andric   if (isa<llvm::Constant>(GEPVal)) {
5635a7dea167SDimitry Andric     // Compute the offset by casting both pointers to integers and subtracting:
5636a7dea167SDimitry Andric     // GEPVal = BasePtr + ptr(Offset) <--> Offset = int(GEPVal) - int(BasePtr)
5637a7dea167SDimitry Andric     Value *BasePtr_int =
5638a7dea167SDimitry Andric         Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->getType()));
5639a7dea167SDimitry Andric     Value *GEPVal_int =
5640a7dea167SDimitry Andric         Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->getType()));
5641a7dea167SDimitry Andric     TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
5642a7dea167SDimitry Andric     return {TotalOffset, /*OffsetOverflows=*/Builder.getFalse()};
5643a7dea167SDimitry Andric   }
56440b57cec5SDimitry Andric 
56450b57cec5SDimitry Andric   auto *GEP = cast<llvm::GEPOperator>(GEPVal);
5646a7dea167SDimitry Andric   assert(GEP->getPointerOperand() == BasePtr &&
5647349cc55cSDimitry Andric          "BasePtr must be the base of the GEP.");
56480b57cec5SDimitry Andric   assert(GEP->isInBounds() && "Expected inbounds GEP");
56490b57cec5SDimitry Andric 
56500b57cec5SDimitry Andric   auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
56510b57cec5SDimitry Andric 
56520b57cec5SDimitry Andric   // Grab references to the signed add/mul overflow intrinsics for intptr_t.
56530b57cec5SDimitry Andric   auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
56540b57cec5SDimitry Andric   auto *SAddIntrinsic =
56550b57cec5SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
56560b57cec5SDimitry Andric   auto *SMulIntrinsic =
56570b57cec5SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
56580b57cec5SDimitry Andric 
56590b57cec5SDimitry Andric   // The offset overflow flag - true if the total offset overflows.
56600b57cec5SDimitry Andric   llvm::Value *OffsetOverflows = Builder.getFalse();
56610b57cec5SDimitry Andric 
56620b57cec5SDimitry Andric   /// Return the result of the given binary operation.
56630b57cec5SDimitry Andric   auto eval = [&](BinaryOperator::Opcode Opcode, llvm::Value *LHS,
56640b57cec5SDimitry Andric                   llvm::Value *RHS) -> llvm::Value * {
56650b57cec5SDimitry Andric     assert((Opcode == BO_Add || Opcode == BO_Mul) && "Can't eval binop");
56660b57cec5SDimitry Andric 
56670b57cec5SDimitry Andric     // If the operands are constants, return a constant result.
56680b57cec5SDimitry Andric     if (auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
56690b57cec5SDimitry Andric       if (auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
56700b57cec5SDimitry Andric         llvm::APInt N;
56710b57cec5SDimitry Andric         bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
56720b57cec5SDimitry Andric                                                   /*Signed=*/true, N);
56730b57cec5SDimitry Andric         if (HasOverflow)
56740b57cec5SDimitry Andric           OffsetOverflows = Builder.getTrue();
56750b57cec5SDimitry Andric         return llvm::ConstantInt::get(VMContext, N);
56760b57cec5SDimitry Andric       }
56770b57cec5SDimitry Andric     }
56780b57cec5SDimitry Andric 
56790b57cec5SDimitry Andric     // Otherwise, compute the result with checked arithmetic.
56800b57cec5SDimitry Andric     auto *ResultAndOverflow = Builder.CreateCall(
56810b57cec5SDimitry Andric         (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
56820b57cec5SDimitry Andric     OffsetOverflows = Builder.CreateOr(
56830b57cec5SDimitry Andric         Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
56840b57cec5SDimitry Andric     return Builder.CreateExtractValue(ResultAndOverflow, 0);
56850b57cec5SDimitry Andric   };
56860b57cec5SDimitry Andric 
56870b57cec5SDimitry Andric   // Determine the total byte offset by looking at each GEP operand.
56880b57cec5SDimitry Andric   for (auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
56890b57cec5SDimitry Andric        GTI != GTE; ++GTI) {
56900b57cec5SDimitry Andric     llvm::Value *LocalOffset;
56910b57cec5SDimitry Andric     auto *Index = GTI.getOperand();
56920b57cec5SDimitry Andric     // Compute the local offset contributed by this indexing step:
56930b57cec5SDimitry Andric     if (auto *STy = GTI.getStructTypeOrNull()) {
56940b57cec5SDimitry Andric       // For struct indexing, the local offset is the byte position of the
56950b57cec5SDimitry Andric       // specified field.
56960b57cec5SDimitry Andric       unsigned FieldNo = cast<llvm::ConstantInt>(Index)->getZExtValue();
56970b57cec5SDimitry Andric       LocalOffset = llvm::ConstantInt::get(
56980b57cec5SDimitry Andric           IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
56990b57cec5SDimitry Andric     } else {
57000b57cec5SDimitry Andric       // Otherwise this is array-like indexing. The local offset is the index
57010b57cec5SDimitry Andric       // multiplied by the element size.
57021db9f3b2SDimitry Andric       auto *ElementSize =
57031db9f3b2SDimitry Andric           llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
57040b57cec5SDimitry Andric       auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy, /*isSigned=*/true);
57050b57cec5SDimitry Andric       LocalOffset = eval(BO_Mul, ElementSize, IndexS);
57060b57cec5SDimitry Andric     }
57070b57cec5SDimitry Andric 
57080b57cec5SDimitry Andric     // If this is the first offset, set it as the total offset. Otherwise, add
57090b57cec5SDimitry Andric     // the local offset into the running total.
57100b57cec5SDimitry Andric     if (!TotalOffset || TotalOffset == Zero)
57110b57cec5SDimitry Andric       TotalOffset = LocalOffset;
57120b57cec5SDimitry Andric     else
57130b57cec5SDimitry Andric       TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
57140b57cec5SDimitry Andric   }
57150b57cec5SDimitry Andric 
5716a7dea167SDimitry Andric   return {TotalOffset, OffsetOverflows};
5717a7dea167SDimitry Andric }
5718a7dea167SDimitry Andric 
5719a7dea167SDimitry Andric Value *
EmitCheckedInBoundsGEP(llvm::Type * ElemTy,Value * Ptr,ArrayRef<Value * > IdxList,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,const Twine & Name)57200eae32dcSDimitry Andric CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
57210eae32dcSDimitry Andric                                         ArrayRef<Value *> IdxList,
5722a7dea167SDimitry Andric                                         bool SignedIndices, bool IsSubtraction,
5723a7dea167SDimitry Andric                                         SourceLocation Loc, const Twine &Name) {
5724fe6060f1SDimitry Andric   llvm::Type *PtrTy = Ptr->getType();
57250eae32dcSDimitry Andric   Value *GEPVal = Builder.CreateInBoundsGEP(ElemTy, Ptr, IdxList, Name);
5726a7dea167SDimitry Andric 
5727a7dea167SDimitry Andric   // If the pointer overflow sanitizer isn't enabled, do nothing.
5728a7dea167SDimitry Andric   if (!SanOpts.has(SanitizerKind::PointerOverflow))
5729a7dea167SDimitry Andric     return GEPVal;
5730a7dea167SDimitry Andric 
5731a7dea167SDimitry Andric   // Perform nullptr-and-offset check unless the nullptr is defined.
5732a7dea167SDimitry Andric   bool PerformNullCheck = !NullPointerIsDefined(
5733a7dea167SDimitry Andric       Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
5734a7dea167SDimitry Andric   // Check for overflows unless the GEP got constant-folded,
5735a7dea167SDimitry Andric   // and only in the default address space
5736a7dea167SDimitry Andric   bool PerformOverflowCheck =
5737a7dea167SDimitry Andric       !isa<llvm::Constant>(GEPVal) && PtrTy->getPointerAddressSpace() == 0;
5738a7dea167SDimitry Andric 
5739a7dea167SDimitry Andric   if (!(PerformNullCheck || PerformOverflowCheck))
5740a7dea167SDimitry Andric     return GEPVal;
5741a7dea167SDimitry Andric 
5742a7dea167SDimitry Andric   const auto &DL = CGM.getDataLayout();
5743a7dea167SDimitry Andric 
5744a7dea167SDimitry Andric   SanitizerScope SanScope(this);
5745a7dea167SDimitry Andric   llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
5746a7dea167SDimitry Andric 
5747a7dea167SDimitry Andric   GEPOffsetAndOverflow EvaluatedGEP =
5748a7dea167SDimitry Andric       EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder);
5749a7dea167SDimitry Andric 
5750a7dea167SDimitry Andric   assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
5751a7dea167SDimitry Andric           EvaluatedGEP.OffsetOverflows == Builder.getFalse()) &&
5752a7dea167SDimitry Andric          "If the offset got constant-folded, we don't expect that there was an "
5753a7dea167SDimitry Andric          "overflow.");
5754a7dea167SDimitry Andric 
5755a7dea167SDimitry Andric   auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
5756a7dea167SDimitry Andric 
5757a7dea167SDimitry Andric   // Common case: if the total offset is zero, and we are using C++ semantics,
5758a7dea167SDimitry Andric   // where nullptr+0 is defined, don't emit a check.
5759a7dea167SDimitry Andric   if (EvaluatedGEP.TotalOffset == Zero && CGM.getLangOpts().CPlusPlus)
57600b57cec5SDimitry Andric     return GEPVal;
57610b57cec5SDimitry Andric 
57620b57cec5SDimitry Andric   // Now that we've computed the total offset, add it to the base pointer (with
57630b57cec5SDimitry Andric   // wrapping semantics).
5764a7dea167SDimitry Andric   auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
5765a7dea167SDimitry Andric   auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.TotalOffset);
57660b57cec5SDimitry Andric 
5767a7dea167SDimitry Andric   llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
5768a7dea167SDimitry Andric 
5769a7dea167SDimitry Andric   if (PerformNullCheck) {
5770a7dea167SDimitry Andric     // In C++, if the base pointer evaluates to a null pointer value,
5771a7dea167SDimitry Andric     // the only valid  pointer this inbounds GEP can produce is also
5772a7dea167SDimitry Andric     // a null pointer, so the offset must also evaluate to zero.
5773a7dea167SDimitry Andric     // Likewise, if we have non-zero base pointer, we can not get null pointer
5774a7dea167SDimitry Andric     // as a result, so the offset can not be -intptr_t(BasePtr).
5775a7dea167SDimitry Andric     // In other words, both pointers are either null, or both are non-null,
5776a7dea167SDimitry Andric     // or the behaviour is undefined.
5777a7dea167SDimitry Andric     //
5778a7dea167SDimitry Andric     // C, however, is more strict in this regard, and gives more
5779a7dea167SDimitry Andric     // optimization opportunities: in C, additionally, nullptr+0 is undefined.
5780a7dea167SDimitry Andric     // So both the input to the 'gep inbounds' AND the output must not be null.
5781a7dea167SDimitry Andric     auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
5782a7dea167SDimitry Andric     auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
5783a7dea167SDimitry Andric     auto *Valid =
5784a7dea167SDimitry Andric         CGM.getLangOpts().CPlusPlus
5785a7dea167SDimitry Andric             ? Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr)
5786a7dea167SDimitry Andric             : Builder.CreateAnd(BaseIsNotNullptr, ResultIsNotNullptr);
5787a7dea167SDimitry Andric     Checks.emplace_back(Valid, SanitizerKind::PointerOverflow);
5788a7dea167SDimitry Andric   }
5789a7dea167SDimitry Andric 
5790a7dea167SDimitry Andric   if (PerformOverflowCheck) {
57910b57cec5SDimitry Andric     // The GEP is valid if:
57920b57cec5SDimitry Andric     // 1) The total offset doesn't overflow, and
57930b57cec5SDimitry Andric     // 2) The sign of the difference between the computed address and the base
57940b57cec5SDimitry Andric     // pointer matches the sign of the total offset.
57950b57cec5SDimitry Andric     llvm::Value *ValidGEP;
5796a7dea167SDimitry Andric     auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.OffsetOverflows);
57970b57cec5SDimitry Andric     if (SignedIndices) {
5798a7dea167SDimitry Andric       // GEP is computed as `unsigned base + signed offset`, therefore:
5799a7dea167SDimitry Andric       // * If offset was positive, then the computed pointer can not be
5800a7dea167SDimitry Andric       //   [unsigned] less than the base pointer, unless it overflowed.
5801a7dea167SDimitry Andric       // * If offset was negative, then the computed pointer can not be
5802a7dea167SDimitry Andric       //   [unsigned] greater than the bas pointere, unless it overflowed.
58030b57cec5SDimitry Andric       auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
5804a7dea167SDimitry Andric       auto *PosOrZeroOffset =
5805a7dea167SDimitry Andric           Builder.CreateICmpSGE(EvaluatedGEP.TotalOffset, Zero);
58060b57cec5SDimitry Andric       llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
5807a7dea167SDimitry Andric       ValidGEP =
5808a7dea167SDimitry Andric           Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
5809a7dea167SDimitry Andric     } else if (!IsSubtraction) {
5810a7dea167SDimitry Andric       // GEP is computed as `unsigned base + unsigned offset`,  therefore the
5811a7dea167SDimitry Andric       // computed pointer can not be [unsigned] less than base pointer,
5812a7dea167SDimitry Andric       // unless there was an overflow.
5813a7dea167SDimitry Andric       // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`.
5814a7dea167SDimitry Andric       ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
58150b57cec5SDimitry Andric     } else {
5816a7dea167SDimitry Andric       // GEP is computed as `unsigned base - unsigned offset`, therefore the
5817a7dea167SDimitry Andric       // computed pointer can not be [unsigned] greater than base pointer,
5818a7dea167SDimitry Andric       // unless there was an overflow.
5819a7dea167SDimitry Andric       // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`.
5820a7dea167SDimitry Andric       ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
58210b57cec5SDimitry Andric     }
5822a7dea167SDimitry Andric     ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
5823a7dea167SDimitry Andric     Checks.emplace_back(ValidGEP, SanitizerKind::PointerOverflow);
5824a7dea167SDimitry Andric   }
5825a7dea167SDimitry Andric 
5826a7dea167SDimitry Andric   assert(!Checks.empty() && "Should have produced some checks.");
58270b57cec5SDimitry Andric 
58280b57cec5SDimitry Andric   llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
58290b57cec5SDimitry Andric   // Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
58300b57cec5SDimitry Andric   llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
5831a7dea167SDimitry Andric   EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
58320b57cec5SDimitry Andric 
58330b57cec5SDimitry Andric   return GEPVal;
58340b57cec5SDimitry Andric }
58350fca6ea1SDimitry Andric 
EmitCheckedInBoundsGEP(Address Addr,ArrayRef<Value * > IdxList,llvm::Type * elementType,bool SignedIndices,bool IsSubtraction,SourceLocation Loc,CharUnits Align,const Twine & Name)58360fca6ea1SDimitry Andric Address CodeGenFunction::EmitCheckedInBoundsGEP(
58370fca6ea1SDimitry Andric     Address Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
58380fca6ea1SDimitry Andric     bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align,
58390fca6ea1SDimitry Andric     const Twine &Name) {
58400fca6ea1SDimitry Andric   if (!SanOpts.has(SanitizerKind::PointerOverflow))
58410fca6ea1SDimitry Andric     return Builder.CreateInBoundsGEP(Addr, IdxList, elementType, Align, Name);
58420fca6ea1SDimitry Andric 
58430fca6ea1SDimitry Andric   return RawAddress(
58440fca6ea1SDimitry Andric       EmitCheckedInBoundsGEP(Addr.getElementType(), Addr.emitRawPointer(*this),
58450fca6ea1SDimitry Andric                              IdxList, SignedIndices, IsSubtraction, Loc, Name),
58460fca6ea1SDimitry Andric       elementType, Align);
58470fca6ea1SDimitry Andric }
5848