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